http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/ComponentHealthCheck.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/ComponentHealthCheck.java
 
b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/ComponentHealthCheck.java
deleted file mode 100644
index a3585f4..0000000
--- 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/ComponentHealthCheck.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.util;
-
-import static org.apache.log4j.Logger.getLogger;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import io.github.taverna_extras.component.api.ComponentException;
-import io.github.taverna_extras.component.api.ComponentFactory;
-import io.github.taverna_extras.component.api.Version;
-import 
io.github.taverna_extras.component.ui.ComponentActivityConfigurationBean;
-
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.scufl2.api.common.Visitor;
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-import 
org.apache.taverna.scufl2.validation.correctness.DefaultDispatchingVisitor;
-import org.apache.taverna.visit.VisitKind;
-import org.apache.taverna.visit.VisitReport;
-
-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;
-       private static Logger logger = getLogger(ComponentHealthCheck.class);
-       private static final String OUTDATED_MSG = "Component out of date";
-
-       private ComponentFactory factory;
-
-       public void setComponentFactory(ComponentFactory factory) {
-               this.factory = factory;
-       }
-
-       public List<Object> checkForOutdatedComponents(WorkflowBundle bundle) {
-               UpgradeChecker uc = new UpgradeChecker();
-               bundle.accept(uc);
-               return uc.warnings;
-       }
-
-       private class UpgradeChecker extends DefaultDispatchingVisitor {
-               ComponentFactory factory;
-               List<Object> warnings = new ArrayList<>();
-
-               @Override
-               public void visitActivity(Activity activity) {
-                       ComponentActivityConfigurationBean config = new 
ComponentActivityConfigurationBean(
-                                       activity.getConfiguration().getJson(), 
factory);
-                       Version v;
-                       try {
-                               v = config.getVersion();
-                       } catch (ComponentException e) {
-                               logger.error("failed to get component 
description", e);
-                               warnings.add(e);//FIXME Just putting the 
exception in here isn't good
-                               return;
-                       }
-                       visitComponent(activity, v);
-               }
-               protected void visitComponent(Activity activity, Version 
version) {
-                       int latest = 
version.getComponent().getComponentVersionMap().lastKey();
-                       if (latest > version.getVersionNumber())
-                               warnings.add(new 
VisitReport(ComponentHealthCheck.this,
-                                               activity, OUTDATED_MSG, 
OUT_OF_DATE,
-                                               VisitReport.Status.WARNING));
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/Utils.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/Utils.java
 
b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/Utils.java
deleted file mode 100644
index e81cbf6..0000000
--- 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/util/Utils.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.util;
-
-import static 
io.github.taverna_extras.component.ui.ComponentConstants.ACTIVITY_URI;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import io.github.taverna_extras.component.api.ComponentFactory;
-import io.github.taverna_extras.component.api.Version;
-import io.github.taverna_extras.component.ui.preference.ComponentPreference;
-import 
io.github.taverna_extras.component.ui.serviceprovider.ComponentServiceIcon;
-import 
io.github.taverna_extras.component.ui.serviceprovider.ComponentServiceProvider;
-
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.scufl2.api.common.Named;
-import org.apache.taverna.scufl2.api.common.NamedSet;
-import org.apache.taverna.scufl2.api.configurations.Configuration;
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
-import org.apache.taverna.workbench.file.FileManager;
-//import net.sf.taverna.t2.servicedescriptions.ServiceDescriptionRegistry;
-//import net.sf.taverna.t2.workbench.file.FileManager;
-
-/**
- * @author alanrw
- */
-public class Utils {
-       // From 
http://stackoverflow.com/questions/163360/regular-expresion-to-match-urls-in-java
-       public static String URL_PATTERN = 
"^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
-       public static final String LONG_STRING = 
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
-       public static final String SHORT_STRING = "XXX";
-
-       private FileManager fileManager;
-       private ServiceDescriptionRegistry registry;
-       private ComponentFactory factory;
-       private ComponentPreference prefs;
-       private ComponentServiceIcon icon;
-
-       public void setComponentFactory(ComponentFactory factory) {
-               this.factory = factory;
-       }
-       
-       public void setFileManager(FileManager fileManager) {
-               this.fileManager = fileManager;
-       }
-
-       public void setIcon(ComponentServiceIcon icon) {
-               this.icon = icon;
-       }
-       
-       public void setPrefs(ComponentPreference prefs) {
-               this.prefs = prefs;
-       }
-       
-       public void setRegistry(ServiceDescriptionRegistry registry) {
-               this.registry = registry;
-       }
-
-       public void refreshComponentServiceProvider(Configuration config) {
-               ComponentServiceProvider provider = new 
ComponentServiceProvider(
-                               factory, prefs, icon, this);
-               provider.configure(config);
-               registry.removeServiceDescriptionProvider(provider);
-               registry.addServiceDescriptionProvider(provider);
-       }
-
-       public void removeComponentServiceProvider(Configuration config) {
-               ComponentServiceProvider provider = new 
ComponentServiceProvider(
-                               factory, prefs, icon, this);
-               provider.configure(config);
-               registry.removeServiceDescriptionProvider(provider);
-       }
-
-       public boolean dataflowIsComponent(WorkflowBundle d) {
-               if (d == null)
-                       return false;
-               Object dataflowSource = fileManager.getDataflowSource(d);
-               return dataflowSource instanceof Version.ID;// FIXME Really?
-       }
-
-       public boolean currentDataflowIsComponent() {
-               return dataflowIsComponent(fileManager.getCurrentDataflow());
-       }
-
-       public static boolean isComponentActivity(Object obj) {
-               if (obj == null || !(obj instanceof Activity))
-                       return false;
-               Configuration cfg = ((Activity) obj).getConfiguration();
-               return cfg != null && ACTIVITY_URI.equals(cfg.getType());
-       }
-
-       private static final Pattern SANITIZER_RE = Pattern
-                       .compile("[^a-zA-Z0-9]+");
-       private static final Pattern SUFFIXED_RE = Pattern
-                       .compile("^(.+)_([0-9]+)$");
-
-       /**
-        * Pick a name that is unique within the context set. This is done by
-        * appending "<tt>_<i>n</i></tt>" as necessary, where <tt><i>n</i></tt> 
is a
-        * number.
-        * 
-        * @param name
-        *            The suggested name; this is always checked first.
-        * @param context
-        *            The set of things that the name will have to be unique 
within.
-        * @return A name that is definitely not the name of anything in the 
given
-        *         set.
-        */
-       public static String uniqueName(String name, NamedSet<? extends Named> 
context) {
-               String candidate = SANITIZER_RE.matcher(name).replaceAll("_");
-               if (context.getByName(candidate) == null)
-                       return candidate;
-               int counter = 0;
-               String prefix = candidate;
-               Matcher m = SUFFIXED_RE.matcher(candidate);
-               if (m.matches()) {
-                       prefix = m.group(1);
-                       counter = Integer.parseInt(m.group(2));
-               }
-               do {
-                       candidate = prefix + "_" + (++counter);
-               } while (context.getByName(candidate) != null);
-               return candidate;
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivityContextViewFactory.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivityContextViewFactory.java
 
b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivityContextViewFactory.java
deleted file mode 100644
index c27278f..0000000
--- 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivityContextViewFactory.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static 
io.github.taverna_extras.component.api.config.ComponentConfig.URI;
-
-import java.awt.Frame;
-import java.net.MalformedURLException;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.swing.Action;
-
-import io.github.taverna_extras.component.api.ComponentFactory;
-import io.github.taverna_extras.component.ui.config.ComponentConfigureAction;
-
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.servicedescriptions.ServiceDescriptionRegistry;
-import org.apache.taverna.services.ServiceRegistry;
-import org.apache.taverna.workbench.activityicons.ActivityIconManager;
-import org.apache.taverna.workbench.configuration.colour.ColourManager;
-import org.apache.taverna.workbench.edits.EditManager;
-import org.apache.taverna.workbench.file.FileManager;
-import 
org.apache.taverna.workbench.ui.actions.activity.HTMLBasedActivityContextualView;
-import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView;
-import 
org.apache.taverna.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
-
-public class ComponentActivityContextViewFactory implements
-               ContextualViewFactory<Activity> {
-       private ColourManager colourManager;
-       private ViewUtil util;
-       private ComponentFactory factory;
-       private ActivityIconManager aim;
-       private ServiceDescriptionRegistry sdr;
-       private EditManager em;
-       private FileManager fm;
-       private ServiceRegistry sr;
-
-       public void setComponentFactory(ComponentFactory factory) {
-               this.factory = factory;
-       }
-
-       public void setColourManager(ColourManager colourManager) {
-               this.colourManager = colourManager;
-       }
-
-       public void setViewUtils(ViewUtil util) {
-               this.util = util;
-       }
-
-       public void setIconManager(ActivityIconManager aim) {
-               this.aim = aim;
-       }
-
-       public void setServiceDescriptionRegistry(ServiceDescriptionRegistry 
sdr) {
-               this.sdr = sdr;
-       }
-
-       public void setEditManager(EditManager em) {
-               this.em = em;
-       }
-
-       public void setFileManager(FileManager fm) {
-               this.fm = fm;
-       }
-
-       public void setServiceTypeRegistry(ServiceRegistry sr) {
-               this.sr = sr;
-       }
-
-       @Override
-       public boolean canHandle(Object selection) {
-               return selection instanceof Activity
-                               && ((Activity) selection).getType().equals(URI);
-       }
-
-       @Override
-       public List<ContextualView> getViews(Activity selection) {
-               return Arrays.<ContextualView>asList(new 
ComponentActivityContextualView(selection));
-       }
-
-       @SuppressWarnings("serial")
-       private class ComponentActivityContextualView extends
-                       HTMLBasedActivityContextualView {
-               public ComponentActivityContextualView(Activity activity) {
-                       super(activity, colourManager);
-                       init();
-               }
-
-               private void init() {
-               }
-
-               @Override
-               public String getViewTitle() {
-                       return "Component service";
-               }
-
-               /**
-                * View position hint
-                */
-               @Override
-               public int getPreferredPosition() {
-                       // We want to be on top
-                       return 100;
-               }
-
-               @Override
-               public Action getConfigureAction(Frame owner) {
-                       return new ComponentConfigureAction(getActivity(), 
owner, factory,
-                                       aim, sdr, em, fm, sr);
-               }
-
-               @Override
-               protected String getRawTableRowsHtml() {
-                       try {
-                               return util.getRawTablesHtml(getConfigBean());
-                       } catch (MalformedURLException e) {
-                               return "<tr><td>malformed URL: <pre>" + 
e.getMessage()
-                                               + "</pre></td></tr>";
-                       }
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationContextViewFactory.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationContextViewFactory.java
 
b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationContextViewFactory.java
deleted file mode 100644
index fcb6e4a..0000000
--- 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationContextViewFactory.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static org.apache.log4j.Logger.getLogger;
-import static 
io.github.taverna_extras.component.api.config.ComponentConfig.URI;
-
-import java.net.MalformedURLException;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import io.github.taverna_extras.component.api.ComponentException;
-import io.github.taverna_extras.component.api.ComponentFactory;
-import io.github.taverna_extras.component.api.profile.Profile;
-import 
io.github.taverna_extras.component.ui.ComponentActivityConfigurationBean;
-import 
io.github.taverna_extras.component.ui.annotation.AbstractSemanticAnnotationContextualView;
-
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.scufl2.api.core.Workflow;
-import org.apache.taverna.scufl2.api.port.InputActivityPort;
-import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
-import org.apache.taverna.scufl2.api.port.OutputActivityPort;
-import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
-import org.apache.taverna.scufl2.api.port.Port;
-import org.apache.taverna.workbench.file.FileManager;
-import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView;
-import 
org.apache.taverna.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
-
-public class ComponentActivitySemanticAnnotationContextViewFactory implements
-               ContextualViewFactory<Object> {
-       public static final String VIEW_TITLE = "Inherited Semantic 
Annotations";
-       private static final Logger logger = 
getLogger(ComponentActivitySemanticAnnotationContextViewFactory.class);
-
-       private FileManager fm;
-       private ComponentFactory factory;
-
-       public void setFileManager(FileManager fm) {
-               this.fm = fm;
-       }
-
-       public void setComponentFactory(ComponentFactory factory) {
-               this.factory = factory;
-       }
-
-       @Override
-       public boolean canHandle(Object selection) {
-               return getContainingComponentActivity(selection) != null;
-       }
-
-       public Activity getContainingComponentActivity(Object selection) {
-               if (selection instanceof Activity) {
-                       Activity a = (Activity) selection;
-                       if (a.getType().equals(URI))
-                               return a;
-               }
-               if (selection instanceof InputActivityPort
-                               || selection instanceof OutputActivityPort)
-                       return 
getContainingComponentActivity(((OutputActivityPort) selection)
-                                       .getParent());
-               return null;
-       }
-
-       @Override
-       public List<ContextualView> getViews(Object selection) {
-               return Arrays
-                               .<ContextualView> asList(new 
SemanticAnnotationCV(
-                                               selection));
-       }
-
-       @SuppressWarnings("serial")
-       private class SemanticAnnotationCV extends
-                       AbstractSemanticAnnotationContextualView {
-               private Profile componentProfile;
-
-               public SemanticAnnotationCV(Object selection) {
-                       super(fm, false);
-                       Activity componentActivity = 
getContainingComponentActivity(selection);
-                       try {
-                               ComponentActivityConfigurationBean 
configuration = new ComponentActivityConfigurationBean(
-                                               
componentActivity.getConfiguration(), factory);
-                               setAnnotatedThing(selection, 
configuration.getVersion()
-                                               
.getImplementation().getMainWorkflow());
-                               componentProfile = 
configuration.getComponent().getFamily()
-                                               .getComponentProfile();
-                               setProfile(selection);
-                               super.initialise();
-                       } catch (ComponentException e) {
-                               logger.error("problem querying registry", e);
-                       } catch (MalformedURLException e) {
-                               logger.error("malformed URL in component 
description", e);
-                       }
-               }
-
-               private void setAnnotatedThing(Object selection,
-                               Workflow underlyingDataflow) {
-                       if (selection instanceof Activity) {
-                               setAnnotated(underlyingDataflow);
-                       } else if (selection instanceof InputActivityPort) {
-                               String name = ((Port) selection).getName();
-                               for (InputWorkflowPort dip : 
underlyingDataflow.getInputPorts())
-                                       if (dip.getName().equals(name)) {
-                                               setAnnotated(dip);
-                                               break;
-                                       }
-                       } else if (selection instanceof OutputActivityPort) {
-                               String name = ((Port) selection).getName();
-                               for (OutputWorkflowPort dop : underlyingDataflow
-                                               .getOutputPorts())
-                                       if (dop.getName().equals(name)) {
-                                               setAnnotated(dop);
-                                               break;
-                                       }
-                       }
-               }
-
-               private void setProfile(Object selection) throws 
ComponentException {
-                       if (componentProfile == null)
-                               return;
-                       if (selection instanceof Activity) {
-                               setSemanticAnnotationProfiles(componentProfile
-                                               .getSemanticAnnotations());
-                       } else if (selection instanceof InputActivityPort) {
-                               setSemanticAnnotationProfiles(componentProfile
-                                               
.getInputSemanticAnnotationProfiles());
-                       } else if (selection instanceof OutputActivityPort) {
-                               setSemanticAnnotationProfiles(componentProfile
-                                               
.getOutputSemanticAnnotationProfiles());
-                       }
-               }
-               
-               @Override
-               public String getViewTitle() {
-                       return VIEW_TITLE;
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationPanel.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationPanel.java
 
b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationPanel.java
deleted file mode 100644
index d3580a8..0000000
--- 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentActivitySemanticAnnotationPanel.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static java.awt.Color.GRAY;
-import static java.awt.Color.WHITE;
-import static java.awt.GridBagConstraints.BOTH;
-import static java.awt.GridBagConstraints.EAST;
-import static java.awt.GridBagConstraints.HORIZONTAL;
-import static java.awt.GridBagConstraints.SOUTHEAST;
-import static java.lang.String.format;
-import static 
io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.getDisplayName;
-import static 
io.github.taverna_extras.component.ui.annotation.SemanticAnnotationUtils.getObjectName;
-
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.util.Set;
-
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTextArea;
-import javax.swing.border.AbstractBorder;
-import javax.swing.border.EmptyBorder;
-
-import 
io.github.taverna_extras.component.api.profile.SemanticAnnotationProfile;
-
-import org.apache.jena.ontology.OntProperty;
-import org.apache.jena.rdf.model.Statement;
-
-public class ComponentActivitySemanticAnnotationPanel extends JPanel {
-       private static final long serialVersionUID = 3599768150252711758L;
-       private static final String ANNTYPE_MSG = "Annotation type : %s";
-       private static final String NONE_MSG = "No semantic annotations";       
-       private SemanticAnnotationProfile profile;
-       private final Set<Statement> statements;
-
-       public ComponentActivitySemanticAnnotationPanel(
-                       SemanticAnnotationProfile profile, Set<Statement> 
statements) {
-               this.profile = profile;
-               this.statements = statements;
-               initialize();
-       }
-
-       private void initialize() {
-               setLayout(new GridBagLayout());
-               setBorder(new AbstractBorder() {
-                       private static final long serialVersionUID = 
-5921448975807056953L;
-
-                       @Override
-                       public void paintBorder(Component c, Graphics g, int x, 
int y,
-                                       int width, int height) {
-                               g.setColor(GRAY);
-                               g.drawLine(x, y + height - 1, x + width - 1, y 
+ height - 1);
-                       }
-               });
-
-               GridBagConstraints c = new GridBagConstraints();
-               c.anchor = SOUTHEAST;
-               c.fill = BOTH;
-               c.weightx = 1;
-               c.gridx = 0;
-
-               OntProperty predicate = profile.getPredicate();
-               c.gridwidth = 2;
-               JLabel label = new JLabel(format(ANNTYPE_MSG, 
getDisplayName(predicate)));
-               label.setBorder(new EmptyBorder(5, 5, 5, 5));
-               label.setBackground(WHITE);
-               label.setOpaque(true);
-               add(label, c);
-
-               c.insets = new Insets(5, 7, 0, 0);
-               c.anchor = EAST;
-               c.fill = HORIZONTAL;
-               if (statements.isEmpty()) {
-                       c.gridwidth = 2;
-                       // c.weightx = 1;
-                       // c.gridy++;
-                       add(new JLabel(NONE_MSG), c);
-               } else {
-                       c.gridwidth = 1;
-                       for (Statement statement : statements) {
-                               c.gridx = 0;
-                               c.weightx = 1;
-                               JTextArea value = new 
JTextArea(getObjectName(statement));
-                               value.setBackground(WHITE);
-                               value.setOpaque(true);
-                               value.setBorder(new EmptyBorder(2, 4, 2, 4));
-                               add(value, c);
-                       }
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextViewFactory.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextViewFactory.java
 
b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextViewFactory.java
deleted file mode 100644
index 938a32e..0000000
--- 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextViewFactory.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static 
io.github.taverna_extras.component.api.config.ComponentConfig.URI;
-
-import java.util.Arrays;
-import java.util.List;
-
-import io.github.taverna_extras.component.api.Version;
-
-import org.apache.taverna.scufl2.api.activity.Activity;
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-import org.apache.taverna.workbench.file.FileManager;
-import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView;
-import 
org.apache.taverna.workbench.ui.views.contextualviews.activity.ContextualViewFactory;
-
-public class ComponentContextViewFactory implements
-               ContextualViewFactory<WorkflowBundle> {
-       private FileManager fileManager;
-
-       public void setFileManager(FileManager fileManager) {
-               this.fileManager = fileManager;
-       }
-
-       @Override
-       public boolean canHandle(Object selection) {
-               if (selection instanceof WorkflowBundle) {
-                       Object dataflowSource = fileManager
-                                       .getDataflowSource((WorkflowBundle) 
selection);
-                       //FIXME Is this right?
-                       return dataflowSource instanceof Version.ID;
-               }
-               return selection instanceof Activity
-                               && ((Activity) selection).getType().equals(URI);
-       }
-
-       @Override
-       public List<ContextualView> getViews(WorkflowBundle selection) {
-               Object dataflowSource = 
fileManager.getDataflowSource(selection);
-               return Arrays.<ContextualView> asList(new 
ComponentContextualView(
-                               (Version.ID) dataflowSource));
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextualView.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextualView.java
 
b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextualView.java
deleted file mode 100644
index c763d06..0000000
--- 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ComponentContextualView.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static java.lang.String.format;
-
-import java.awt.Color;
-
-import javax.swing.JComponent;
-import javax.swing.JEditorPane;
-
-import io.github.taverna_extras.component.api.Version;
-import org.apache.taverna.lang.ui.HtmlUtils;
-import org.apache.taverna.workbench.configuration.colour.ColourManager;
-import org.apache.taverna.workbench.ui.views.contextualviews.ContextualView;
-
-@SuppressWarnings("serial")
-public class ComponentContextualView extends ContextualView {
-       private JEditorPane editorPane;
-       private final Version.ID component;
-       ColourManager colourManager;//FIXME beaninject
-       ViewUtil viewUtils;//FIXME beaninject;
-
-       public ComponentContextualView(Version.ID component) {
-               this.component = component;
-               initView();
-       }
-
-       @Override
-       public JComponent getMainFrame() {
-               editorPane = HtmlUtils.createEditorPane(buildHtml());
-               return HtmlUtils.panelForHtml(editorPane);
-       }
-
-       private String buildHtml() {
-               StringBuilder html = new 
StringBuilder(HtmlUtils.getHtmlHead(getBackgroundColour()));
-               html.append(HtmlUtils.buildTableOpeningTag());
-               viewUtils.getRawTablesHtml(component, html);
-               return html.append("</table></body></html>").toString();
-       }
-
-       public String getBackgroundColour() {
-               Color colour = colourManager.getPreferredColour(
-                               
"io.github.taverna_extras.component.registry.Component");
-               return format("#%1$2x%2$2x%3$2x", colour.getRed(), 
colour.getGreen(),
-                               colour.getBlue());
-       }
-
-       @Override
-       public int getPreferredPosition() {
-               return 50;
-       }
-
-       private static int MAX_LENGTH = 50;
-
-       private String limitName(String fullName) {
-               if (fullName.length() > MAX_LENGTH)
-                       return fullName.substring(0, MAX_LENGTH - 3) + "...";
-               return fullName;
-       }
-
-       @Override
-       public String getViewTitle() {
-               return "Component " + limitName(component.getComponentName());
-       }
-
-       @Override
-       public void refreshView() {
-               editorPane.setText(buildHtml());
-               repaint();
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ViewUtil.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ViewUtil.java
 
b/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ViewUtil.java
deleted file mode 100644
index 5764f6c..0000000
--- 
a/taverna-component-activity-ui/src/main/java/org/apache/taverna/component/ui/view/ViewUtil.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
-package io.github.taverna_extras.component.ui.view;
-
-import static java.lang.String.format;
-import static org.apache.log4j.Logger.getLogger;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Set;
-
-import org.apache.log4j.Logger;
-import io.github.taverna_extras.component.api.Component;
-import io.github.taverna_extras.component.api.ComponentFactory;
-import io.github.taverna_extras.component.api.Family;
-import io.github.taverna_extras.component.api.Version;
-import 
io.github.taverna_extras.component.ui.ComponentActivityConfigurationBean;
-
-import org.apache.taverna.scufl2.api.configurations.Configuration;
-import org.apache.taverna.scufl2.api.container.WorkflowBundle;
-import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
-import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
-
-/**
- * @author alanrw
- */
-public class ViewUtil {
-       private static Logger logger = getLogger(ViewUtil.class);
-
-       private static final String VERSION_DESCRIPTION_LABEL = "Component 
version description";
-       private static final String COMPONENT_DESCRIPTION_LABEL = "Component 
description";
-       private static final String FAMILY_DESCRIPTION_LABEL = "Family 
description";
-
-       private static final String plainFormat = "<tr><td><b>%1$s</b></td><td 
nowrap=\"wrap\" style=\"width:100px;\">%2$s</td></tr>";
-       private static final String headerFormat = 
"<tr><th>%1$s</th><th>%2$s</th></tr>";
-       private static final String rowFormat = 
"<tr><td><b>%1$s</b></td><td>%2$s</td></tr>";
-       private static final String rowLinkFormat = 
"<tr><td><b>%1$s</b></td><td><a href=\"%3$s\">%2$s</a></td></tr>";
-       private static final String descriptionFormat = "<tr><td 
colspan=\"2\"><b>%1$s</b></td></tr><tr><td colspan=\"2\" nowrap=\"wrap\" 
style=\"width:100px;\">%2$s</td></tr>";
-
-       private ComponentFactory factory;//FIXME beaninject
-
-       public void setComponentFactory(ComponentFactory factory) {
-               this.factory = factory;
-       }
-
-       public String getRawTablesHtml(Version.ID id) {
-               StringBuilder html = new StringBuilder();
-               getRawTablesHtml(id, html);
-               return html.toString();
-       }
-
-       public String getRawTablesHtml(Configuration config) throws 
MalformedURLException {
-               StringBuilder html = new StringBuilder();
-               getRawTablesHtml(
-                               new ComponentActivityConfigurationBean(
-                                               config.getJsonAsObjectNode(), 
factory), html);
-               return html.toString();
-       }
-
-       public void getRawTablesHtml(Version.ID id, StringBuilder html) {
-               URL registryBase = id.getRegistryBase();
-               String registryLink = null;
-               if (registryBase.getProtocol().startsWith("http"))
-                       registryLink = registryBase.toExternalForm();
-               /*
-                * \u200b is a zero-width space, so the HTML renderer can know 
to break
-                * lines.
-                */
-               String registryName = registryBase.toString().replaceAll("/", 
"\u200b/");
-               appendRow(html, "Component registry base", registryName, 
registryLink);
-
-               String familyName = id.getFamilyName();
-               appendRow(html, "Component family", familyName, null);
-               try {
-                       Family family = factory.getFamily(registryBase, 
familyName);
-                       if (family != null)
-                               appendDescriptionHtml(html, 
FAMILY_DESCRIPTION_LABEL,
-                                               family.getDescription());
-               } catch (Exception e) {
-                       logger.error("failed to get component family 
description", e);
-               }
-
-               String componentName = id.getComponentName();
-               String helpLink = null;
-               try {
-                       URL helpURL = factory.getVersion(id).getHelpURL();
-                       if (helpURL != null)
-                               helpLink = helpURL.toExternalForm();
-               } catch (Exception e) {
-                       logger.error(e);
-               }
-
-               appendRow(html, "Component name", componentName, helpLink);
-               try {
-                       Component component = factory.getComponent(registryBase,
-                                       familyName, componentName);
-                       if (component != null)
-                               appendDescriptionHtml(html, 
COMPONENT_DESCRIPTION_LABEL,
-                                               component.getDescription());
-               } catch (Exception e) {
-                       logger.error("failed to get component description", e);
-               }
-
-               Integer componentVersion = id.getComponentVersion();
-
-               if (componentVersion == null)
-                       appendRow(html, "Component version", "N/A", helpLink);
-               else {
-                       appendRow(html, "Component version", componentVersion, 
helpLink);
-                       try {
-                               Version version = 
factory.getVersion(registryBase,
-                                               familyName, componentName, 
componentVersion);
-                               if (version != null) {
-                                       appendDescriptionHtml(html, 
VERSION_DESCRIPTION_LABEL,
-                                                       
version.getDescription());
-                                       WorkflowBundle impl = 
version.getImplementation();
-                                       Set<InputWorkflowPort> inputs = 
impl.getMainWorkflow().getInputPorts();
-                                       if (!inputs.isEmpty()) {
-                                               appendHeaderRow(html, "Input 
Port Name", "Depth");
-                                               for (InputWorkflowPort input : 
inputs)
-                                                       appendPlainRow(html, 
input.getName(), input.getDepth());
-                                       }
-                                       Set<OutputWorkflowPort> outputs = 
impl.getMainWorkflow().getOutputPorts();
-                                       if (!outputs.isEmpty()) {
-                                               appendHeaderRow(html, "Output 
Port Name", "Depth");
-                                               for (OutputWorkflowPort output 
: outputs) {
-                                                       //FIXME get depth of 
output ports!
-                                                       appendPlainRow(html, 
output.getName(), -1 /*output.getDepth()*/);
-                                               }
-                                       }
-                               }
-                       } catch (Exception e) {
-                               logger.error("failed to get component version 
description", e);
-                       }
-               }
-       }
-
-       private static void appendRow(StringBuilder html, Object label,
-                       Object value, String link) {
-               if (link == null)
-                       html.append(format(rowFormat, label, value));
-               else
-                       html.append(format(rowLinkFormat, label, value, link));
-       }
-
-       private static void appendHeaderRow(StringBuilder html, Object label1,
-                       Object label2) {
-               html.append(format(headerFormat, label1, label2));
-       }
-
-       private static void appendPlainRow(StringBuilder html, Object value1,
-                       Object value2) {
-               html.append(format(plainFormat, value1, value2));
-       }
-
-       private static void appendDescriptionHtml(StringBuilder html,
-                       String header, String description) {
-               if ((description != null) && !description.isEmpty())
-                       html.append(format(descriptionFormat, header, 
description));
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivity.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivity.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivity.java
new file mode 100644
index 0000000..9619297
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivity.java
@@ -0,0 +1,167 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.apache.log4j.Logger.getLogger;
+
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.api.profile.ExceptionHandling;
+import 
io.github.taverna_extras.component.registry.ComponentImplementationCache;
+import io.github.taverna_extras.component.registry.ComponentUtil;
+import io.github.taverna_extras.component.utils.AnnotationUtils;
+import io.github.taverna_extras.component.utils.SystemUtils;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.taverna.activities.dataflow.DataflowActivity;
+import org.apache.taverna.annotation.annotationbeans.SemanticAnnotation;
+import org.apache.taverna.invocation.InvocationContext;
+import org.apache.taverna.invocation.impl.InvocationContextImpl;
+import org.apache.taverna.platform.execution.api.InvalidWorkflowException;
+import org.apache.taverna.reference.ReferenceService;
+import org.apache.taverna.reference.T2Reference;
+import org.apache.taverna.workflowmodel.Dataflow;
+import org.apache.taverna.workflowmodel.EditException;
+import org.apache.taverna.workflowmodel.Edits;
+import 
org.apache.taverna.workflowmodel.processor.activity.AbstractAsynchronousActivity;
+import 
org.apache.taverna.workflowmodel.processor.activity.ActivityConfigurationException;
+import 
org.apache.taverna.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import org.apache.taverna.workflowmodel.utils.AnnotationTools;
+
+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 = 
AnnotationTools.getAnnotationString(realizingDataflow,
+                                       SemanticAnnotation.class, null);
+                       if (annotationValue != null)
+                               AnnotationTools.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/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityConfigurationBean.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityConfigurationBean.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityConfigurationBean.java
new file mode 100644
index 0000000..6819b3f
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityConfigurationBean.java
@@ -0,0 +1,168 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.apache.log4j.Logger.getLogger;
+import static 
io.github.taverna_extras.component.api.config.ComponentPropertyNames.COMPONENT_NAME;
+import static 
io.github.taverna_extras.component.api.config.ComponentPropertyNames.COMPONENT_VERSION;
+import static 
io.github.taverna_extras.component.api.config.ComponentPropertyNames.FAMILY_NAME;
+import static 
io.github.taverna_extras.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 io.github.taverna_extras.component.api.Version;
+import io.github.taverna_extras.component.api.profile.ExceptionHandling;
+import 
io.github.taverna_extras.component.registry.ComponentImplementationCache;
+import io.github.taverna_extras.component.registry.ComponentUtil;
+import 
io.github.taverna_extras.component.registry.ComponentVersionIdentification;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
+import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import 
org.apache.taverna.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
+import 
org.apache.taverna.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
+import 
org.apache.taverna.workflowmodel.processor.activity.config.ActivityPortsDefinitionBean;
+
+/**
+ * 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 
(io.github.taverna_extras.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));
+               // FIXME: Get the ValidatorState (so we can get 
getPortResolvedDepth()
+               ValidatorState vs =  ... ;
+               for (OutputWorkflowPort owp : 
w.getMainWorkflow().getOutputPorts())
+                       
outputs.add(makeOutputDefinition(vs.getPortResolvedDepth(owp), owp.getName()));
+
+               try {
+                       eh = util.getFamily(getRegistryBase(), getFamilyName())
+                                       
.getComponentProfile().getExceptionHandling();
+                       if (eh != null)
+                               outputs.add(makeOutputDefinition(1, 
ERROR_CHANNEL));
+               } catch 
(io.github.taverna_extras.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 
io.github.taverna_extras.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/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityFactory.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityFactory.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityFactory.java
new file mode 100644
index 0000000..c90ea1a
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityFactory.java
@@ -0,0 +1,142 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Set;
+
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.api.Version.ID;
+import 
io.github.taverna_extras.component.registry.ComponentImplementationCache;
+import io.github.taverna_extras.component.registry.ComponentUtil;
+import io.github.taverna_extras.component.utils.AnnotationUtils;
+import io.github.taverna_extras.component.utils.SystemUtils;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.taverna.workflowmodel.Edits;
+import 
org.apache.taverna.workflowmodel.processor.activity.ActivityConfigurationException;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityFactory;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityInputPort;
+import org.apache.taverna.workflowmodel.processor.activity.ActivityOutputPort;
+import 
org.apache.taverna.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean;
+import 
org.apache.taverna.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean;
+
+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/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityLocalChecker.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityLocalChecker.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityLocalChecker.java
new file mode 100644
index 0000000..d874241
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityLocalChecker.java
@@ -0,0 +1,69 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static 
io.github.taverna_extras.component.activity.ComponentHealthCheck.NON_SHAREABLE;
+
+import java.util.List;
+import org.apache.taverna.visit.VisitKind;
+import org.apache.taverna.visit.VisitReport;
+import static org.apache.taverna.visit.VisitReport.Status.WARNING;
+import org.apache.taverna.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/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityUpgradeChecker.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityUpgradeChecker.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityUpgradeChecker.java
new file mode 100644
index 0000000..4d45b60
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentActivityUpgradeChecker.java
@@ -0,0 +1,83 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.apache.log4j.Logger.getLogger;
+import static 
io.github.taverna_extras.component.activity.ComponentHealthCheck.OUT_OF_DATE;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.ComponentException;
+import io.github.taverna_extras.component.registry.ComponentUtil;
+import org.apache.taverna.visit.VisitKind;
+import org.apache.taverna.visit.VisitReport;
+import static org.apache.taverna.visit.VisitReport.Status.WARNING;
+import org.apache.taverna.workflowmodel.health.HealthChecker;
+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/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentExceptionFactory.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentExceptionFactory.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentExceptionFactory.java
new file mode 100644
index 0000000..243fe84
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentExceptionFactory.java
@@ -0,0 +1,38 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+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/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentHealthCheck.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentHealthCheck.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentHealthCheck.java
new file mode 100644
index 0000000..0381de1
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentHealthCheck.java
@@ -0,0 +1,42 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.taverna.visit.VisitKind;
+import org.apache.taverna.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/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentImplementationException.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentImplementationException.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentImplementationException.java
new file mode 100644
index 0000000..7ef77f7
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ComponentImplementationException.java
@@ -0,0 +1,37 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+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/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ProxyCallback.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ProxyCallback.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ProxyCallback.java
new file mode 100644
index 0000000..3a04af3
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/ProxyCallback.java
@@ -0,0 +1,264 @@
+package io.github.taverna_extras.component.activity;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+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 org.apache.log4j.Logger;
+import io.github.taverna_extras.component.api.profile.ExceptionHandling;
+import io.github.taverna_extras.component.api.profile.ExceptionReplacement;
+import io.github.taverna_extras.component.api.profile.HandleException;
+import org.apache.taverna.invocation.InvocationContext;
+import org.apache.taverna.reference.ErrorDocument;
+import org.apache.taverna.reference.ErrorDocumentService;
+import org.apache.taverna.reference.IdentifiedList;
+import org.apache.taverna.reference.ListService;
+import org.apache.taverna.reference.ReferenceService;
+import org.apache.taverna.reference.T2Reference;
+import static org.apache.taverna.reference.T2ReferenceType.ErrorDocument;
+import static org.apache.taverna.reference.T2ReferenceType.IdentifiedList;
+import static org.apache.taverna.reference.T2ReferenceType.ReferenceSet;
+import 
org.apache.taverna.workflowmodel.processor.activity.AsynchronousActivityCallback;
+import 
org.apache.taverna.workflowmodel.processor.dispatch.events.DispatchErrorType;
+
+/**
+ * @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/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/package-info.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/package-info.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/package-info.java
new file mode 100644
index 0000000..086a49b
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/activity/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package io.github.taverna_extras.component.activity;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-plugin-component/blob/b7b61e71/taverna-component-activity/src/main/java/io/github/taverna_extras/component/profile/ActivityProfileImpl.java
----------------------------------------------------------------------
diff --git 
a/taverna-component-activity/src/main/java/io/github/taverna_extras/component/profile/ActivityProfileImpl.java
 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/profile/ActivityProfileImpl.java
new file mode 100644
index 0000000..a948cd4
--- /dev/null
+++ 
b/taverna-component-activity/src/main/java/io/github/taverna_extras/component/profile/ActivityProfileImpl.java
@@ -0,0 +1,53 @@
+package io.github.taverna_extras.component.profile;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.github.taverna_extras.component.api.profile.ActivityProfile;
+import 
io.github.taverna_extras.component.api.profile.SemanticAnnotationProfile;
+
+import io.github.taverna_extras.component.api.profile.doc.Activity;
+import io.github.taverna_extras.component.api.profile.doc.SemanticAnnotation;
+
+/**
+ * Specifies the semantic annotations that an activity must have.
+ * 
+ * @author David Withers
+ */
+public class ActivityProfileImpl implements ActivityProfile {
+       private final ComponentProfileImpl componentProfile;
+       private final Activity activity;
+
+       public ActivityProfileImpl(ComponentProfileImpl componentProfile,
+                       Activity activity) {
+               this.componentProfile = componentProfile;
+               this.activity = activity;
+       }
+
+       @Override
+       public List<SemanticAnnotationProfile> getSemanticAnnotations() {
+               List<SemanticAnnotationProfile> saProfiles = new ArrayList<>();
+               for (SemanticAnnotation annotation : 
activity.getSemanticAnnotation())
+                       saProfiles.add(new 
SemanticAnnotationProfileImpl(componentProfile,
+                                       annotation));
+               return saProfiles;
+       }
+}


Reply via email to