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

[28/79] [partial] incubator-taverna-language git commit: Revert "temporarily empty repository"

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/README.md
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/README.md b/taverna-scufl2-examples/README.md
new file mode 100644
index 0000000..429d4e8
--- /dev/null
+++ b/taverna-scufl2-examples/README.md
@@ -0,0 +1,251 @@
+SCUFL2 examples
+===============
+
+Examples of using the [SCUFL2 API](http://dev.mygrid.org.uk/wiki/display/developer/SCUFL2+API) v0.14.0.
+
+[![Build Status](https://travis-ci.org/myGrid/scufl2-examples.svg?branch=master)](https://travis-ci.org/myGrid/scufl2-examples)
+
+As this code is meant only as examples that you can extend and modify, the
+groupId and package name are `org.apache.taverna.examples`, which should be changed
+in your application.
+
+
+
+Download
+--------
+Download the `scufl2-examples-0.x.x-standalone.jar` from the
+[latest build](http://build.mygrid.org.uk/ci/job/scufl2-examples/lastSuccessfulBuild/com.example$scufl2-examples/), or browse the [Maven snapshot repository](http://repository.mygrid.org.uk/artifactory/libs-snapshot-local/com/example/scufl2-examples/).
+
+This is a standalone executable JAR (see below). 
+
+
+
+Build
+-----
+
+
+To build, you'll need [Maven](http://maven.apache.org/download.cgi) 3.0.5 or newer, and run
+```mvn clean install```:
+
+    C:\Users\stain\workspace\scufl2-examples> mvn clean install
+    
+    [INFO] ------------------------------------------------------------------------
+    [INFO] Building SCUFL2 examples 0.1.1-SNAPSHOT
+    [INFO] ------------------------------------------------------------------------
+    [INFO] 
+    [INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ scufl2-examples ---
+    [INFO] Deleting C:\Users\stain\workspace\scufl2-examples\target
+    (..)
+    [INFO] Installing C:\Users\stain\workspace\scufl2-examples\target\scufl2-examples-0.1.1-SNAPSHOT.jar to C:\Users\stain\.m2\repository\com\example\scufl2-examples\0.1.1-SNAPSHOT\scufl2-examples-0.1.1-SNAPSHOT.jar
+    [INFO] Installing C:\Users\stain\workspace\scufl2-examples\pom.xml to C:\Users\stain\.m2\repository\com\example\scufl2-examples\0.1.1-SNAPSHOT\scufl2-examples-0.1.1-SNAPSHOT.pom
+    [INFO] ------------------------------------------------------------------------
+    [INFO] BUILD SUCCESS
+    [INFO] ------------------------------------------------------------------------
+    [INFO] Total time: 6.223s
+    [INFO] Finished at: Tue Apr 23 11:00:27 BST 2013
+    [INFO] Final Memory: 15M/243M
+    [INFO] ----------------    
+
+To run the examples, see the folder ```target\scufl2-examples``` which has a `bin/` executable for each of the below tools. Note that these tools require the provided `bin/` and `lib/` folder structure.
+
+Alternatively you can use ```java -jar target/scufl2-examples-0.2.0-SNAPSHOT-standalone.jar``` - this is a standalone
+JAR file that can execute any of the tools as the first argument. 
+
+Linux users can install this with:
+
+    chmod 755 target/scufl2-examples-*-standalone.jar
+    sudo cp target/scufl2-examples-*-standalone.jar /usr/local/bin/scufl2tool
+    
+as long as JAR files are recognized as executables:
+
+    stain@biggie-mint ~/src/scufl2-examples $ target/scufl2-examples-0.2.0-SNAPSHOT-standalone.jar 
+    SCUFL2 workflow tool
+    Usage: scufl2tool <tool> [option] ...
+
+    Available tools:
+    t2flowtowfbundle - Convert t2flow workflows to wfbundle
+    jsonexport - Export JSON structure of workflow
+    processornames - List tree of processor names in workflow
+    servicetypes - List service types used in workflow
+    workflowmaker - Create an example workflow programmatically
+
+
+
+processornames
+--------------
+This tool lists a tree of the processor names in the workflows of the given bundle.
+
+    C:\Users\stain\workspace\scufl2-examples> target\scufl2-examples\bin\processornames examples/helloworld.t2flow
+    + Hello_World
+      - hello
+    
+    
+    C:\Users\stain\workspace\scufl2-examples> target\scufl2-examples\bin\processornames examples/helloanyone.t2flow
+    + Hello_Anyone
+      - Concatenate_two_strings
+      - hello
+
+See the source code for [org.apache.taverna.examples.ProcessorNames](src/main/java/org/apache/taverna/examples/ProcessorNames.java)
+ for how this is implemented.
+
+
+servicetypes
+------------
+This tool lists the URIs of the types of services (activities) used in the workflow.
+
+    C:\Users\stain\workspace\scufl2-examples> target\scufl2-examples\bin\servicetypes examples/helloanyone.t2flow
+    http://ns.taverna.org.uk/2010/activity/beanshell
+    http://ns.taverna.org.uk/2010/activity/constant
+
+See the source code for [org.apache.taverna.examples.ServiceTypes](src/main/java/org/apache/taverna/examples/ServiceTypes.java)
+ for how this is implemented.
+
+
+workflowmaker
+-------------
+This tool shows how to construct a workflow from scratch and save it as a 
+[SCUFL2 wfbundle](http://dev.mygrid.org.uk/wiki/display/developer/Taverna+Workflow+Bundle).
+
+    C:\Users\stain\workspace\scufl2-examples> target\scufl2-examples\bin\workflowmaker
+    Written to C:\Users\stain\AppData\Local\Temp\test6264603033381329995.wfbundle
+    
+    WorkflowBundle '4fdb73e3-a5c6-41a8-aafb-32f67ca552b2'
+      MainWorkflow 'Echotest'
+      Workflow 'Echotest'
+        In 'in1'
+        Out 'out1'
+        Processor 'p'
+          In 'pIn'
+          Out 'pOut'
+        Links
+          'in1' -> 'p:pIn'
+          'p:pOut' -> 'out1'
+      MainProfile 'default'
+      Profile 'default'
+        Activity 'myBeanshell'
+          Type <http://ns.taverna.org.uk/2010/activity/beanshell>
+          In 'in1'
+          Out 'out1'
+        ProcessorBinding '434e7226-1d7f-498d-a19f-75be9f38f266'
+          Activity 'myBeanshell'
+          Processor 'Echotest:p'
+          InputPortBindings
+            'pIn' -> 'in1'
+          OutputPortBindings
+            'out1' -> 'pOut'
+        Configuration 'beanshellConf'
+          Type <http://ns.taverna.org.uk/2010/activity/beanshell#Config>
+          Configures 'activity/myBeanshell'
+          Property <http://ns.taverna.org.uk/2010/activity/beanshell#script>
+            '''out1 = in1'''
+
+
+See the source code for [org.apache.taverna.examples.WorkflowMaker](src/main/java/org/apache/taverna/WorkflowMaker.java) 
+for how this is implemented.
+
+
+t2flowtowfbundle
+----------------
+
+This tool shows how to convert a *.t2flow* file to a 
+[SCUFL2 .wfbundle](http://dev.mygrid.org.uk/wiki/display/developer/Taverna+Workflow+Bundle).
+
+    C:\Users\stain\workspace\scufl2-examples> rm helloworld.wfbundle
+    
+    C:\Users\stain\workspace\scufl2-examples> target\scufl2-examples\bin\t2flowtowfbu
+    
+    C:\Users\stain\workspace\scufl2-examples> unzip -t helloworld.wfbundle
+    Archive:  helloworld.wfbundle
+        testing: mimetype                 OK
+        testing: META-INF/                OK
+        testing: META-INF/manifest.xml    OK
+        testing: history/                 OK
+        testing: history/8781d5f4-d0ba-48a8-a1d1-14281bd8a917.t2flow   OK
+        testing: workflow/                OK
+        testing: workflow/Hello_World.rdf   OK
+        testing: profile/                 OK
+        testing: profile/taverna-2.2.0.rdf   OK
+        testing: annotation/              OK
+        testing: annotation/0c2f3c2c-7b5f-49cc-a448-92d707da3795.rdf   OK
+        testing: annotation/48c04fe7-90f8-42f2-be61-a0480aa826d1.rdf   OK
+        testing: annotation/9558f2e4-b629-4d1d-a62e-8c0dd39d7746.rdf   OK
+        testing: workflowBundle.rdf       OK
+        testing: META-INF/container.xml   OK
+    No errors detected in compressed data of helloworld.wfbundle.
+
+See the source code for 
+[org.apache.taverna.examples.ConvertT2flowToWorkflowBundle.java](src/main/java/org/apache/taverna/examples/ConvertT2flowToWorkflowBundle.java)
+for how this is implemented.
+
+The included files [helloworld.wfbundle](helloworld.wfbundle?raw=true) and
+[helloanyone.wfbundle](helloanyone.wfbundle?raw=true) are examples of converting
+[helloworld.t2flow](helloworld.t2flow?raw=true) and [helloanyone.t2flow](helloanyone.t2flow?raw=true)  
+
+
+jsonexport
+----------
+This tool exports a JSON structure of the workflow, including basic
+annotations on workflows, ports, processors, nested workflows and
+revision log of the workflows.
+
+Usage:
+
+    c:\Users\stain\src\scufl2-examples> target\scufl2-examples\bin\jsonexport -h
+    Export workflow structore as JSON.
+    Usage: jsonexport [filename] ...
+    If the filename is - the workflow will be read from STDIN and
+    JSON written to STDOUT.
+    Otherwise, the file is read as a workflow (t2flow, workflow bundle)
+    and written as JSON to a file with the .json extension.
+    Multiple filenames can be given. JSON filenames are written to STDOUT
+
+Converting multiple files:
+
+    c:\Users\stain\src\scufl2-examples> target\scufl2-examples\bin\jsonexport examples/helloworld.t2flow examples/helloanyone.wfbundle
+    examples/helloworld.json
+    examples/helloanyone.json
+    
+See the converted [examples/helloworld.json](helloworld.json) and
+[examples/helloanyone.json](helloanyone.json).
+
+Example using STDIN/STDOUT:
+
+    c:\Users\stain\src\scufl2-examples> target\scufl2-examples\bin\jsonexport - < examples/helloworld.t2flow
+    {
+      "@context" : [ "https://w3id.org/scufl2/context", {
+        "@base" : "http://ns.taverna.org.uk/2010/workflowBundle/8781d5f4-d0ba-48a8-a1d1-14281bd8a917/"
+      } ],
+      "id" : "http://ns.taverna.org.uk/2010/workflowBundle/8781d5f4-d0ba-48a8-a1d1-14281bd8a917/",
+      "workflow" : {
+        "id" : "workflow/Hello_World/",
+        "name" : "Hello_World",
+        "revisions" : [ {
+          "id" : "http://ns.taverna.org.uk/2010/workflow/8781d5f4-d0ba-48a8-a1d1-14281bd8a917/",
+          "generatedAtTime" : "2012-01-03T15:12:21Z"
+        } ],
+        "inputs" : [ ],
+        "outputs" : [ {
+          "name" : "greeting",
+          "id" : "workflow/Hello_World/out/greeting"
+        } ],
+        "processors" : [ {
+          "id" : "workflow/Hello_World/processor/hello/",
+          "name" : "hello",
+          "inputs" : [ ],
+          "outputs" : [ {
+            "name" : "value",
+            "id" : "workflow/Hello_World/processor/hello/out/value",
+            "depth" : 0
+          } ]
+        } ],
+        "datalinks" : [ {
+          "receivesFrom" : "workflow/Hello_World/processor/hello/out/value",
+          "sendsTo" : "workflow/Hello_World/out/greeting"
+        } ],
+        "controllinks" : [ ],
+        "http://purl.org/dc/terms/description" : "One of the simplest workflows possible. No workflow input ports, a single workflow output port \"greeting\",  outputting \"Hello, world!\" as produced by the String Constant \"hello\".",
+        "http://purl.org/dc/elements/1.1/creator" : "Stian Soiland-Reyes",
+        "http://purl.org/dc/terms/title" : "Hello World"
+      }
+    }
+

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/examples/helloanyone.json
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/examples/helloanyone.json b/taverna-scufl2-examples/examples/helloanyone.json
new file mode 100644
index 0000000..477b73c
--- /dev/null
+++ b/taverna-scufl2-examples/examples/helloanyone.json
@@ -0,0 +1,72 @@
+{
+  "@context" : [ "https://w3id.org/scufl2/context", {
+    "@base" : "http://ns.taverna.org.uk/2010/workflowBundle/01348671-5aaa-4cc2-84cc-477329b70b0d/"
+  } ],
+  "id" : "http://ns.taverna.org.uk/2010/workflowBundle/01348671-5aaa-4cc2-84cc-477329b70b0d/",
+  "workflow" : {
+    "id" : "workflow/Hello_Anyone/",
+    "name" : "Hello_Anyone",
+    "revisions" : [ {
+      "id" : "http://ns.taverna.org.uk/2010/workflow/01348671-5aaa-4cc2-84cc-477329b70b0d/",
+      "generatedAtTime" : "2012-01-03T15:14:30Z",
+      "wasRevisionOf" : "http://ns.taverna.org.uk/2010/workflow/ca7dba1d-1fdf-476f-b911-714d09227d70/"
+    }, {
+      "id" : "http://ns.taverna.org.uk/2010/workflow/ca7dba1d-1fdf-476f-b911-714d09227d70/",
+      "generatedAtTime" : "2012-01-03T15:14:18Z",
+      "wasRevisionOf" : "http://ns.taverna.org.uk/2010/workflow/8781d5f4-d0ba-48a8-a1d1-14281bd8a917/"
+    }, {
+      "id" : "http://ns.taverna.org.uk/2010/workflow/8781d5f4-d0ba-48a8-a1d1-14281bd8a917/",
+      "generatedAtTime" : "2012-01-03T15:12:21Z"
+    } ],
+    "inputs" : [ {
+      "name" : "name",
+      "id" : "workflow/Hello_Anyone/in/name",
+      "depth" : 0
+    } ],
+    "outputs" : [ {
+      "name" : "greeting",
+      "id" : "workflow/Hello_Anyone/out/greeting"
+    } ],
+    "processors" : [ {
+      "id" : "workflow/Hello_Anyone/processor/Concatenate_two_strings/",
+      "name" : "Concatenate_two_strings",
+      "inputs" : [ {
+        "name" : "string1",
+        "id" : "workflow/Hello_Anyone/processor/Concatenate_two_strings/in/string1",
+        "depth" : 0
+      }, {
+        "name" : "string2",
+        "id" : "workflow/Hello_Anyone/processor/Concatenate_two_strings/in/string2",
+        "depth" : 0
+      } ],
+      "outputs" : [ {
+        "name" : "output",
+        "id" : "workflow/Hello_Anyone/processor/Concatenate_two_strings/out/output",
+        "depth" : 0
+      } ]
+    }, {
+      "id" : "workflow/Hello_Anyone/processor/hello/",
+      "name" : "hello",
+      "inputs" : [ ],
+      "outputs" : [ {
+        "name" : "value",
+        "id" : "workflow/Hello_Anyone/processor/hello/out/value",
+        "depth" : 0
+      } ]
+    } ],
+    "datalinks" : [ {
+      "receivesFrom" : "workflow/Hello_Anyone/processor/Concatenate_two_strings/out/output",
+      "sendsTo" : "workflow/Hello_Anyone/out/greeting"
+    }, {
+      "receivesFrom" : "workflow/Hello_Anyone/processor/hello/out/value",
+      "sendsTo" : "workflow/Hello_Anyone/processor/Concatenate_two_strings/in/string1"
+    }, {
+      "receivesFrom" : "workflow/Hello_Anyone/in/name",
+      "sendsTo" : "workflow/Hello_Anyone/processor/Concatenate_two_strings/in/string2"
+    } ],
+    "controllinks" : [ ]
+  },
+  "profile" : {
+    "id" : "profile/taverna-2.2.0/"
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/examples/helloanyone.t2flow
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/examples/helloanyone.t2flow b/taverna-scufl2-examples/examples/helloanyone.t2flow
new file mode 100644
index 0000000..3b625f1
--- /dev/null
+++ b/taverna-scufl2-examples/examples/helloanyone.t2flow
@@ -0,0 +1,196 @@
+<?xml version="1.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.
+ -->
+<workflow xmlns="http://taverna.sf.net/2008/xml/t2flow" version="1" producedBy="taverna-2.2.0"><dataflow id="01348671-5aaa-4cc2-84cc-477329b70b0d" role="top"><name>Hello_Anyone</name><inputPorts><port><name>name</name><depth>0</depth><granularDepth>0</granularDepth><annotations><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.ExampleValue">
+        <text>World!</text>
+      </annotationBean>
+      <date>2012-01-03 15:13:04.106 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.FreeTextDescription">
+        <text>Your name for the greeting</text>
+      </annotationBean>
+      <date>2012-01-03 15:13:12.530 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain></annotations></port></inputPorts><outputPorts><port><name>greeting</name><annotations /></port></outputPorts><processors><processor><name>hello</name><inputPorts /><outputPorts><port><name>value</name><depth>0</depth><granularDepth>0</granularDepth></port></outputPorts><annotations /><activities><activity><raven><group>net.sf.taverna.t2.activities</group><artifact>stringconstant-activity</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.activities.stringconstant.StringConstantActivity</class><inputMap /><outputMap><map from="value" to="value" /></outputMap><configBean encoding="xstream"><net.sf.taverna.t2.activities.stringconstant.StringConstantConfigurationBean xmlns="">
+  <value>Hello, </value>
+</net.sf.taverna.t2.activities.stringconstant.StringConstantConfigurationBean></configBean><annotations /></activity></activities><dispatchStack><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Parallelize</class><configBean encoding="xstream"><net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ParallelizeConfig xmlns="">
+  <maxJobs>1</maxJobs>
+</net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ParallelizeConfig></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ErrorBounce</class><configBean encoding="xstream"><null xmlns="" /></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Failover</class><configBean encoding="xstream"><null xmlns="" /></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Retry</class><configBean encoding="xstream"><net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.RetryConfig xmlns="
 ">
+  <backoffFactor>1.0</backoffFactor>
+  <initialDelay>1000</initialDelay>
+  <maxDelay>5000</maxDelay>
+  <maxRetries>0</maxRetries>
+</net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.RetryConfig></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Invoke</class><configBean encoding="xstream"><null xmlns="" /></configBean></dispatchLayer></dispatchStack><iterationStrategyStack><iteration><strategy /></iteration></iterationStrategyStack></processor><processor><name>Concatenate_two_strings</name><inputPorts><port><name>string1</name><depth>0</depth></port><port><name>string2</name><depth>0</depth></port></inputPorts><outputPorts><port><name>output</name><depth>0</depth><granularDepth>0</granularDepth></port></outputPorts><annotations /><activities><activity><raven><group>net.sf.taverna.t2.activities</group><artifact>localworker-activity</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.activities.localworker.LocalworkerActivi
 ty</class><inputMap><map from="string2" to="string2" /><map from="string1" to="string1" /></inputMap><outputMap><map from="output" to="output" /></outputMap><configBean encoding="xstream"><net.sf.taverna.t2.activities.localworker.LocalworkerActivityConfigurationBean xmlns="">
+  <localworkerName>org.embl.ebi.escience.scuflworkers.java.StringConcat</localworkerName>
+  <script>output = string1 + string2;</script>
+  <dependencies />
+  <classLoaderSharing>workflow</classLoaderSharing>
+  <localDependencies />
+  <artifactDependencies />
+  <inputs>
+    <net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean>
+      <handledReferenceSchemes />
+      <translatedElementType>java.lang.String</translatedElementType>
+      <allowsLiteralValues>true</allowsLiteralValues>
+      <name>string1</name>
+      <depth>0</depth>
+      <mimeTypes>
+        <string>'text/plain'</string>
+      </mimeTypes>
+    </net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean>
+    <net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean>
+      <handledReferenceSchemes />
+      <translatedElementType>java.lang.String</translatedElementType>
+      <allowsLiteralValues>true</allowsLiteralValues>
+      <name>string2</name>
+      <depth>0</depth>
+      <mimeTypes>
+        <string>'text/plain'</string>
+      </mimeTypes>
+    </net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityInputPortDefinitionBean>
+  </inputs>
+  <outputs>
+    <net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean>
+      <granularDepth>0</granularDepth>
+      <name>output</name>
+      <depth>0</depth>
+      <mimeTypes>
+        <string>'text/plain'</string>
+      </mimeTypes>
+    </net.sf.taverna.t2.workflowmodel.processor.activity.config.ActivityOutputPortDefinitionBean>
+  </outputs>
+</net.sf.taverna.t2.activities.localworker.LocalworkerActivityConfigurationBean></configBean><annotations /></activity></activities><dispatchStack><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Parallelize</class><configBean encoding="xstream"><net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ParallelizeConfig xmlns="">
+  <maxJobs>1</maxJobs>
+</net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ParallelizeConfig></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ErrorBounce</class><configBean encoding="xstream"><null xmlns="" /></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Failover</class><configBean encoding="xstream"><null xmlns="" /></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Retry</class><configBean encoding="xstream"><net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.RetryConfig xmlns="
 ">
+  <backoffFactor>1.0</backoffFactor>
+  <initialDelay>1000</initialDelay>
+  <maxDelay>5000</maxDelay>
+  <maxRetries>0</maxRetries>
+</net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.RetryConfig></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Invoke</class><configBean encoding="xstream"><null xmlns="" /></configBean></dispatchLayer></dispatchStack><iterationStrategyStack><iteration><strategy><cross><port name="string1" depth="0" /><port name="string2" depth="0" /></cross></strategy></iteration></iterationStrategyStack></processor></processors><conditions /><datalinks><datalink><sink type="processor"><processor>Concatenate_two_strings</processor><port>string1</port></sink><source type="processor"><processor>hello</processor><port>value</port></source></datalink><datalink><sink type="processor"><processor>Concatenate_two_strings</processor><port>string2</port></sink><source type="dataflow"><port>name</port></source></datalink><datalin
 k><sink type="dataflow"><port>greeting</port></sink><source type="processor"><processor>Concatenate_two_strings</processor><port>output</port></source></datalink></datalinks><annotations><annotation_chain_2_2 encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.IdentificationAssertion">
+        <identification>8781d5f4-d0ba-48a8-a1d1-14281bd8a917</identification>
+      </annotationBean>
+      <date>2012-01-03 15:12:21.684 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain_2_2><annotation_chain_2_2 encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.IdentificationAssertion">
+        <identification>ca7dba1d-1fdf-476f-b911-714d09227d70</identification>
+      </annotationBean>
+      <date>2012-01-03 15:14:18.734 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain_2_2><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.Author">
+        <text>Stian Soiland-Reyes</text>
+      </annotationBean>
+      <date>2012-01-03 15:10:48.73 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.DescriptiveTitle">
+        <text>Hello Anyone</text>
+      </annotationBean>
+      <date>2012-01-03 15:14:25.703 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.DescriptiveTitle">
+        <text>Hello World</text>
+      </annotationBean>
+      <date>2012-01-03 15:10:54.167 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.FreeTextDescription">
+        <text>One of the simplest workflows possible, outputting the String Constant "Hello world!"</text>
+      </annotationBean>
+      <date>2012-01-03 15:11:14.557 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.FreeTextDescription">
+        <text>An extension to helloworld.t2flow - this workflow takes a workflow input "name" which is combined with the string constant "Hello, " using the local worker "Concatenate two strings", and outputs the produced string to the workflow output "greeting".</text>
+      </annotationBean>
+      <date>2012-01-03 15:14:13.847 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.FreeTextDescription">
+        <text>One of the simplest workflows possible. No workflow input ports, a single workflow output port "greeting",  outputting "Hello, world!" as produced by the String Constant "hello".</text>
+      </annotationBean>
+      <date>2012-01-03 15:12:15.643 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain><annotation_chain_2_2 encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.IdentificationAssertion">
+        <identification>01348671-5aaa-4cc2-84cc-477329b70b0d</identification>
+      </annotationBean>
+      <date>2012-01-03 15:14:30.45 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain_2_2></annotations></dataflow></workflow>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/examples/helloanyone.wfbundle
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/examples/helloanyone.wfbundle b/taverna-scufl2-examples/examples/helloanyone.wfbundle
new file mode 100644
index 0000000..904a40d
Binary files /dev/null and b/taverna-scufl2-examples/examples/helloanyone.wfbundle differ

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/examples/helloworld.json
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/examples/helloworld.json b/taverna-scufl2-examples/examples/helloworld.json
new file mode 100644
index 0000000..24e2f1c
--- /dev/null
+++ b/taverna-scufl2-examples/examples/helloworld.json
@@ -0,0 +1,37 @@
+{
+  "@context" : [ "https://w3id.org/scufl2/context", {
+    "@base" : "http://ns.taverna.org.uk/2010/workflowBundle/8781d5f4-d0ba-48a8-a1d1-14281bd8a917/"
+  } ],
+  "id" : "http://ns.taverna.org.uk/2010/workflowBundle/8781d5f4-d0ba-48a8-a1d1-14281bd8a917/",
+  "workflow" : {
+    "id" : "workflow/Hello_World/",
+    "name" : "Hello_World",
+    "revisions" : [ {
+      "id" : "http://ns.taverna.org.uk/2010/workflow/8781d5f4-d0ba-48a8-a1d1-14281bd8a917/",
+      "generatedAtTime" : "2012-01-03T15:12:21Z"
+    } ],
+    "inputs" : [ ],
+    "outputs" : [ {
+      "name" : "greeting",
+      "id" : "workflow/Hello_World/out/greeting"
+    } ],
+    "processors" : [ {
+      "id" : "workflow/Hello_World/processor/hello/",
+      "name" : "hello",
+      "inputs" : [ ],
+      "outputs" : [ {
+        "name" : "value",
+        "id" : "workflow/Hello_World/processor/hello/out/value",
+        "depth" : 0
+      } ]
+    } ],
+    "datalinks" : [ {
+      "receivesFrom" : "workflow/Hello_World/processor/hello/out/value",
+      "sendsTo" : "workflow/Hello_World/out/greeting"
+    } ],
+    "controllinks" : [ ]
+  },
+  "profile" : {
+    "id" : "profile/taverna-2.2.0/"
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/examples/helloworld.t2flow
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/examples/helloworld.t2flow b/taverna-scufl2-examples/examples/helloworld.t2flow
new file mode 100644
index 0000000..2e10ed9
--- /dev/null
+++ b/taverna-scufl2-examples/examples/helloworld.t2flow
@@ -0,0 +1,84 @@
+<?xml version="1.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.
+ -->
+<workflow xmlns="http://taverna.sf.net/2008/xml/t2flow" version="1" producedBy="taverna-2.2.0"><dataflow id="8781d5f4-d0ba-48a8-a1d1-14281bd8a917" role="top"><name>Hello_World</name><inputPorts /><outputPorts><port><name>greeting</name><annotations /></port></outputPorts><processors><processor><name>hello</name><inputPorts /><outputPorts><port><name>value</name><depth>0</depth><granularDepth>0</granularDepth></port></outputPorts><annotations /><activities><activity><raven><group>net.sf.taverna.t2.activities</group><artifact>stringconstant-activity</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.activities.stringconstant.StringConstantActivity</class><inputMap /><outputMap><map from="value" to="value" /></outputMap><configBean encoding="xstream"><net.sf.taverna.t2.activities.stringconstant.StringConstantConfigurationBean xmlns="">
+  <value>Hello, World!</value>
+</net.sf.taverna.t2.activities.stringconstant.StringConstantConfigurationBean></configBean><annotations /></activity></activities><dispatchStack><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Parallelize</class><configBean encoding="xstream"><net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ParallelizeConfig xmlns="">
+  <maxJobs>1</maxJobs>
+</net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ParallelizeConfig></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.ErrorBounce</class><configBean encoding="xstream"><null xmlns="" /></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Failover</class><configBean encoding="xstream"><null xmlns="" /></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Retry</class><configBean encoding="xstream"><net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.RetryConfig xmlns="
 ">
+  <backoffFactor>1.0</backoffFactor>
+  <initialDelay>1000</initialDelay>
+  <maxDelay>5000</maxDelay>
+  <maxRetries>0</maxRetries>
+</net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.RetryConfig></configBean></dispatchLayer><dispatchLayer><raven><group>net.sf.taverna.t2.core</group><artifact>workflowmodel-impl</artifact><version>1.2</version></raven><class>net.sf.taverna.t2.workflowmodel.processor.dispatch.layers.Invoke</class><configBean encoding="xstream"><null xmlns="" /></configBean></dispatchLayer></dispatchStack><iterationStrategyStack><iteration><strategy /></iteration></iterationStrategyStack></processor></processors><conditions /><datalinks><datalink><sink type="dataflow"><port>greeting</port></sink><source type="processor"><processor>hello</processor><port>value</port></source></datalink></datalinks><annotations><annotation_chain_2_2 encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.IdentificationAssertion">
+        <identification>8781d5f4-d0ba-48a8-a1d1-14281bd8a917</identification>
+      </annotationBean>
+      <date>2012-01-03 15:12:21.684 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain_2_2><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.Author">
+        <text>Stian Soiland-Reyes</text>
+      </annotationBean>
+      <date>2012-01-03 15:10:48.73 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.DescriptiveTitle">
+        <text>Hello World</text>
+      </annotationBean>
+      <date>2012-01-03 15:10:54.167 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.FreeTextDescription">
+        <text>One of the simplest workflows possible, outputting the String Constant "Hello world!"</text>
+      </annotationBean>
+      <date>2012-01-03 15:11:14.557 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain><annotation_chain encoding="xstream"><net.sf.taverna.t2.annotation.AnnotationChainImpl xmlns="">
+  <annotationAssertions>
+    <net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+      <annotationBean class="net.sf.taverna.t2.annotation.annotationbeans.FreeTextDescription">
+        <text>One of the simplest workflows possible. No workflow input ports, a single workflow output port "greeting",  outputting "Hello, world!" as produced by the String Constant "hello".</text>
+      </annotationBean>
+      <date>2012-01-03 15:12:15.643 GMT</date>
+      <creators />
+      <curationEventList />
+    </net.sf.taverna.t2.annotation.AnnotationAssertionImpl>
+  </annotationAssertions>
+</net.sf.taverna.t2.annotation.AnnotationChainImpl></annotation_chain></annotations></dataflow></workflow>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/examples/helloworld.wfbundle
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/examples/helloworld.wfbundle b/taverna-scufl2-examples/examples/helloworld.wfbundle
new file mode 100644
index 0000000..ed4cd76
Binary files /dev/null and b/taverna-scufl2-examples/examples/helloworld.wfbundle differ

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/pom.xml b/taverna-scufl2-examples/pom.xml
new file mode 100644
index 0000000..607b470
--- /dev/null
+++ b/taverna-scufl2-examples/pom.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.taverna.language</groupId>
+		<artifactId>taverna-language</artifactId>
+		<version>0.16.1-incubating-SNAPSHOT</version>
+	</parent>
+	<artifactId>taverna-scufl2-examples</artifactId>
+	<name>Apache Taverna Scufl 2 examples</name>
+	<dependencies>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-scufl2-api</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-scufl2-t2flow</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>${project.parent.groupId}</groupId>
+			<artifactId>taverna-scufl2-rdfxml</artifactId>
+			<version>${project.parent.version}</version>
+		</dependency>
+
+		<!-- Included to get rid of "Could not set prefix mapper" warning, but 
+			should work fine without -->
+		<dependency>
+			<groupId>com.sun.xml.bind</groupId>
+			<artifactId>jaxb-impl</artifactId>
+			<version>2.2.4-1</version>
+			<optional>true</optional>
+		</dependency>
+
+		<!-- For writing out JSON-LD annotations -->
+
+		<dependency>
+			<groupId>org.apache.jena</groupId>
+			<artifactId>jena-arq</artifactId>
+			<version>${jena.version}</version>
+		</dependency>
+
+		<!-- Following only needed by src/test/java -->
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.4</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>2.1</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>appassembler-maven-plugin</artifactId>
+				<version>1.1.1</version>
+				<executions>
+					<execution>
+						<id>assemble</id>
+						<phase>package</phase>
+						<goals>
+							<goal>assemble</goal>
+						</goals>
+					</execution>
+				</executions>
+				<configuration>
+					<repositoryLayout>flat</repositoryLayout>
+					<repositoryName>lib</repositoryName>
+					<assembleDirectory>${project.build.directory}/${project.artifactId}</assembleDirectory>
+					<programs>
+						<program>
+							<mainClass>org.apache.taverna.examples.ConvertT2flowToWorkflowBundle</mainClass>
+							<name>t2flowtowfbundle</name>
+						</program>
+						<program>
+							<mainClass>org.apache.taverna.examples.ProcessorNames</mainClass>
+							<name>processornames</name>
+						</program>
+						<program>
+							<mainClass>org.apache.taverna.examples.ServiceTypes</mainClass>
+							<name>servicetypes</name>
+						</program>
+						<program>
+							<mainClass>org.apache.taverna.examples.WorkflowMaker</mainClass>
+							<name>workflowmaker</name>
+						</program>
+						<program>
+							<mainClass>org.apache.taverna.examples.JsonExport</mainClass>
+							<name>jsonexport</name>
+						</program>
+					</programs>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-shade-plugin</artifactId>
+				<!--<version>2.0</version> does not work with Maven 2 :( -->
+				<version>1.7.1</version>
+				<executions>
+					<execution>
+						<phase>package</phase>
+						<goals>
+							<goal>shade</goal>
+						</goals>
+						<configuration>
+							<shadedArtifactAttached>true</shadedArtifactAttached>
+							<shadedClassifierName>standalone</shadedClassifierName>
+							<transformers>
+								<transformer
+									implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+									<mainClass>org.apache.taverna.examples.Scufl2Tool</mainClass>
+								</transformer>
+                <transformer implementation="org.apache.maven.plugins.shade.resource.ApacheNoticeResourceTransformer" />
+								<transformer
+									implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
+								<transformer
+									implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
+									<resource>META-INF/spring</resource>
+								</transformer>
+							</transformers>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ConvertT2flowToWorkflowBundle.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ConvertT2flowToWorkflowBundle.java b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ConvertT2flowToWorkflowBundle.java
new file mode 100644
index 0000000..ae57665
--- /dev/null
+++ b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ConvertT2flowToWorkflowBundle.java
@@ -0,0 +1,57 @@
+package org.apache.taverna.examples;
+
+/*
+ * 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.File;
+import java.io.IOException;
+
+import javax.xml.bind.JAXBException;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
+import org.apache.taverna.scufl2.api.io.WriterException;
+
+public class ConvertT2flowToWorkflowBundle {
+	public static void main(String[] args) throws Exception, ReaderException,
+			WriterException {
+		new ConvertT2flowToWorkflowBundle().convert(args);
+	}
+
+	public void convert(String[] filepaths) throws ReaderException, IOException, WriterException {
+
+		WorkflowBundleIO io = new WorkflowBundleIO();
+		for (String filepath : filepaths) {
+			File t2File = new File(filepath);
+			
+			String filename = t2File.getName();			
+			filename = filename.replaceFirst("\\..*", ".wfbundle");			
+			File scufl2File = new File(t2File.getParentFile(), filename);
+			
+			WorkflowBundle wfBundle = io.readBundle(t2File,
+					"application/vnd.taverna.t2flow+xml");
+			io.writeBundle(wfBundle, scufl2File,
+					"application/vnd.taverna.scufl2.workflow-bundle");
+		}
+
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/JsonExport.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/JsonExport.java b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/JsonExport.java
new file mode 100644
index 0000000..17e8e5b
--- /dev/null
+++ b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/JsonExport.java
@@ -0,0 +1,319 @@
+package org.apache.taverna.examples;
+
+/*
+ * 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.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.taverna.scufl2.api.annotation.Annotation;
+import org.apache.taverna.scufl2.api.annotation.Revision;
+import org.apache.taverna.scufl2.api.common.Child;
+import org.apache.taverna.scufl2.api.common.Ported;
+import org.apache.taverna.scufl2.api.common.Scufl2Tools;
+import org.apache.taverna.scufl2.api.common.URITools;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.core.BlockingControlLink;
+import org.apache.taverna.scufl2.api.core.ControlLink;
+import org.apache.taverna.scufl2.api.core.DataLink;
+import org.apache.taverna.scufl2.api.core.Processor;
+import org.apache.taverna.scufl2.api.core.Workflow;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
+import org.apache.taverna.scufl2.api.io.WorkflowBundleWriter;
+import org.apache.taverna.scufl2.api.io.WriterException;
+import org.apache.taverna.scufl2.api.port.DepthPort;
+import org.apache.taverna.scufl2.api.port.GranularDepthPort;
+import org.apache.taverna.scufl2.api.port.Port;
+import org.apache.taverna.scufl2.api.profiles.Profile;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
+
+public class JsonExport {
+    public class JsonWriter implements WorkflowBundleWriter {
+        
+        @Override
+        public Set<String> getMediaTypes() {
+            return new HashSet<String>(Arrays.asList("application/ld+json",
+                    "application/json"));
+        }
+        @Override
+        public void writeBundle(WorkflowBundle wfBundle, File destination,
+                String mediaType) throws WriterException, IOException {
+            ObjectNode json = toJson(wfBundle);
+            mapper.writeValue(destination, json);
+        }
+
+        @Override
+        public void writeBundle(WorkflowBundle wfBundle,
+                OutputStream output, String mediaType)
+                throws WriterException, IOException {
+            ObjectNode json = toJson(wfBundle);
+            mapper.writeValue(output, json);
+        }
+
+    }
+
+    public static void main(String[] args) throws ReaderException, IOException,
+            WriterException {
+        new JsonExport().convert(args);
+    }
+
+
+    private WorkflowBundleIO io = new WorkflowBundleIO();;
+
+    private WorkflowBundleWriter jsonWriter = new JsonWriter();
+
+    private ObjectMapper mapper = new ObjectMapper();
+    
+    private Scufl2Tools scufl2Tools = new Scufl2Tools();
+    
+    private URITools uriTools = new URITools();
+    
+    public JsonExport() {
+        mapper.enable(SerializationFeature.INDENT_OUTPUT);
+        mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
+        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+
+        mapper.setDateFormat(new ISO8601DateFormat());
+        
+        // Adding custom writer dynamically
+        List<WorkflowBundleWriter> writers = io.getWriters();
+        writers.add(jsonWriter);        
+        io.setWriters(writers);
+    }
+
+    protected void addPorts(Ported ported, ObjectNode p) {
+        ArrayNode inputs = mapper.createArrayNode();        
+        for (Port port : ported.getInputPorts()) {
+            inputs.add(toJson(port));
+        }
+        p.put("inputs", inputs);        
+        
+        ArrayNode outputs = mapper.createArrayNode();        
+        for (Port port : ported.getOutputPorts()) {
+            outputs.add(toJson(port));
+            // FIXME: Do we need the id for ports? Needed if we add datalinks
+        }
+        p.put("outputs", outputs);
+    }
+    
+    protected ObjectNode annotations(Child<?> bean) {
+        ObjectNode node = mapper.createObjectNode();
+        for (Annotation ann : scufl2Tools.annotationsFor(bean)) {
+            URI annUri = uriTools.uriForBean(ann);
+            
+            // TODO: include annotation body?
+        }
+        return node;
+    }
+
+    public void convert(String[] filepaths) throws ReaderException,
+            IOException, WriterException {
+        if (filepaths.length == 0  || filepaths[0].equals("-h")) {
+            System.out.println("Export workflow structore as JSON.");
+            System.out.println("Usage: jsonexport [filename] ...");
+            System.out.println("If the filename is - the workflow will be read from STDIN and");
+            System.out.println("JSON written to STDOUT. ");
+            System.out.println("Otherwise, the file is read as a workflow (t2flow, workflow bundle)");
+            System.out.println("and written as JSON to a file with the .json extension.");
+            System.out.println("Multiple filenames can be given. JSON filenames are written to STDOUT");
+            return;
+        }
+        if (filepaths[0].equals("-")) {
+            // Do piped Stdin/Stdout instead
+            WorkflowBundle wfBundle = io.readBundle(System.in, null);
+            io.writeBundle(wfBundle, System.err, "application/ld+json");
+            return;
+        }
+
+        for (String filepath : filepaths) {
+            File workflow = new File(filepath);
+
+            String filename = workflow.getName();
+            filename = filename.replaceFirst("\\..*", ".json");
+            File workflowFile = new File(workflow.getParentFile(), filename);
+
+            WorkflowBundle wfBundle = io.readBundle(workflow, null);
+            io.writeBundle(wfBundle, workflowFile, "application/ld+json");
+            System.out.println(workflowFile);
+        } 
+    }
+
+    protected ObjectNode toJson(Port port) {
+       ObjectNode p = mapper.createObjectNode();
+       p.put("name", port.getName());
+       p.putPOJO("id", uriTools.relativeUriForBean(port, 
+               scufl2Tools.findParent(WorkflowBundle.class, ((Child<?>)port))));
+       
+       if (port instanceof DepthPort) {
+        DepthPort depthPort = (DepthPort) port;
+        if (depthPort.getDepth() != null) {
+            p.put("depth", depthPort.getDepth());
+        }
+       }
+       if (port instanceof GranularDepthPort) {
+           GranularDepthPort granularDepthPort = (GranularDepthPort) port;
+           if (granularDepthPort.getGranularDepth() != null && 
+                   ! granularDepthPort.getGranularDepth().equals(granularDepthPort.getDepth())) {
+               p.put("granularDepth", granularDepthPort.getGranularDepth());
+           }
+       }
+       p.putAll(annotations((Child<?>)port));
+       return p;
+    }
+
+    protected JsonNode toJson(Processor proc) {
+        ObjectNode p = mapper.createObjectNode();
+        p.putPOJO("id", uriTools.relativeUriForBean(proc, proc.getParent().getParent()));
+        p.put("name", proc.getName());
+        addPorts(proc, p);
+        p.putAll(annotations(proc));
+        
+        List<Workflow> nested = scufl2Tools.nestedWorkflowsForProcessor(proc, 
+                proc.getParent().getParent().getMainProfile());
+        if (! nested.isEmpty()) {
+            if (nested.size() == 1) {
+                p.put("nestedWorkflow", toJson(nested.iterator().next()));
+            } else {
+                ArrayNode list = mapper.createArrayNode();
+                for (Workflow w : nested) {
+                    list.add(toJson(w));
+                }
+                p.put("nestedWorkflow", list);
+            }
+        }
+        return p;
+    }
+    
+    protected JsonNode toJson(Revision currentRevision) {
+        ArrayNode revisions = mapper.createArrayNode();
+        while (currentRevision != null) {
+            ObjectNode rev = mapper.createObjectNode();
+            rev.putPOJO("id", currentRevision.getIdentifier());
+            if (currentRevision.getGeneratedAtTime() != null) {
+                rev.putPOJO("generatedAtTime", currentRevision.getGeneratedAtTime());
+            }
+            currentRevision = currentRevision.getPreviousRevision();
+            if (currentRevision != null) {
+                rev.putPOJO("wasRevisionOf", currentRevision.getIdentifier());
+            }
+            revisions.add(rev);
+        }
+        return revisions;
+    }
+
+    protected ObjectNode toJson(Workflow workflow) {
+        ObjectNode wf = mapper.createObjectNode();
+
+        wf.putPOJO("id", uriTools.relativeUriForBean(workflow, workflow.getParent()));
+        
+        wf.put("name", workflow.getName());
+        wf.put("revisions", toJson(workflow.getCurrentRevision()));
+
+        ArrayNode processors = mapper.createArrayNode();
+        for (Processor p : workflow.getProcessors()) {
+            processors.add(toJson(p));
+        }
+        addPorts(workflow, wf);
+        wf.put("processors", processors);
+        
+        ArrayNode datalinks = mapper.createArrayNode();
+        for (DataLink link : workflow.getDataLinks()) {
+            datalinks.add(toJson(link));
+        }
+        wf.put("datalinks", datalinks);
+
+        ArrayNode controlLinks = mapper.createArrayNode();
+        for (ControlLink link : workflow.getControlLinks()) {
+            controlLinks.add(toJson(link));
+        }
+        wf.put("controllinks", controlLinks);
+
+        
+        wf.putAll(annotations(workflow));
+        
+        return wf;
+    }
+
+    protected JsonNode toJson(ControlLink link) {
+        ObjectNode l = mapper.createObjectNode();
+        if (link instanceof BlockingControlLink) {
+            BlockingControlLink controlLink = (BlockingControlLink) link;
+            l.putPOJO("block", uriTools.relativeUriForBean(controlLink.getBlock(), 
+                    link.getParent().getParent()));
+            l.putPOJO("untilFinished", uriTools.relativeUriForBean(controlLink.getUntilFinished(), 
+                    link.getParent().getParent()));
+        }
+        return l;
+    }
+
+    protected JsonNode toJson(DataLink link) {
+        ObjectNode l = mapper.createObjectNode();
+        l.putPOJO("receivesFrom", uriTools.relativeUriForBean(link.getReceivesFrom(), 
+                link.getParent().getParent()));
+        l.putPOJO("sendsTo", uriTools.relativeUriForBean(link.getSendsTo(), 
+                link.getParent().getParent()));
+        if (link.getMergePosition() != null) {
+            l.put("mergePosition", link.getMergePosition());
+        }
+        return l;
+    }
+
+    public ObjectNode toJson(WorkflowBundle wfBundle) {
+        
+        ObjectNode root = mapper.createObjectNode();
+        ArrayNode contextList = root.arrayNode();
+        root.put("@context", contextList);
+        ObjectNode context = root.objectNode();
+        contextList.add("https://w3id.org/scufl2/context");
+        contextList.add(context);
+        URI base = wfBundle.getGlobalBaseURI();
+        context.put("@base", base.toASCIIString());
+        root.put("id", base.toASCIIString());
+       
+//        root.put("name", wfBundle.getName());
+//        root.put("revisions", toJson(wfBundle.getCurrentRevision()));
+        
+        root.put("workflow", toJson(wfBundle.getMainWorkflow()));
+        root.put("profile", toJson(wfBundle.getMainProfile()));
+        
+        return root;
+    }
+
+    private JsonNode toJson(Profile profile) {
+        ObjectNode pf = mapper.createObjectNode();
+
+        pf.putPOJO("id", uriTools.relativeUriForBean(profile, profile.getParent()));
+        // TODO: Activities and configurations
+        return pf;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ProcessorNames.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ProcessorNames.java b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ProcessorNames.java
new file mode 100644
index 0000000..0a57af5
--- /dev/null
+++ b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ProcessorNames.java
@@ -0,0 +1,132 @@
+package org.apache.taverna.examples;
+
+/*
+ * 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.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeModel;
+import javax.xml.bind.JAXBException;
+
+import org.apache.taverna.scufl2.api.common.Scufl2Tools;
+import org.apache.taverna.scufl2.api.common.URITools;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.core.Processor;
+import org.apache.taverna.scufl2.api.core.Workflow;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
+import org.apache.taverna.scufl2.api.profiles.Profile;
+
+public class ProcessorNames {
+
+	public static void main(String[] args) throws JAXBException, IOException,
+			ReaderException {
+		WorkflowBundleIO io = new WorkflowBundleIO();
+		ProcessorNames processorNames = new ProcessorNames();
+		for (String filename : args) {
+			// NOTE: We give 'null' as filetype so it will guess based on filename
+			WorkflowBundle ro = io.readBundle(new File(filename), null);
+//			System.out.print(filename + ": ");
+//			System.out.println(processorNames.showProcessorNames(ro));
+			System.out.println(processorNames.showProcessorTree(ro));
+		}
+	}
+	private Scufl2Tools scufl2Tools = new Scufl2Tools();
+
+	private URITools uriTools = new URITools();
+
+	private Workflow findNestedWorkflow(Processor processor) {
+		Profile profile = processor.getParent().getParent().getMainProfile();
+		return scufl2Tools.nestedWorkflowForProcessor(processor, profile);
+	}
+
+	private void findProcessors(WorkflowBundle ro, Workflow workflow,
+			DefaultMutableTreeNode parent) {
+		for (Processor processor : workflow.getProcessors()) {
+			DefaultMutableTreeNode processorNode = new DefaultMutableTreeNode(
+					processor.getName());
+			parent.add(processorNode);
+			Workflow wf = findNestedWorkflow(processor);
+			if (wf != null) {
+				findProcessors(ro, wf, processorNode);
+			}
+		}
+
+	}
+
+	public TreeModel makeProcessorTree(WorkflowBundle workflowBundle)
+			throws JAXBException, IOException {
+		Workflow workflow = workflowBundle.getMainWorkflow();
+		TreeModel treeModel = new DefaultTreeModel(new DefaultMutableTreeNode(
+				workflow.getName()));
+		DefaultMutableTreeNode parent = (DefaultMutableTreeNode) treeModel
+				.getRoot();
+
+		findProcessors(workflowBundle, workflow, parent);
+		return treeModel;
+	}
+
+	public List<String> showProcessorNames(WorkflowBundle ro)
+			throws JAXBException, IOException {
+		ArrayList<String> names = new ArrayList<String>();
+		for (Processor processor : ro.getMainWorkflow().getProcessors()) {
+			names.add(processor.getName());
+		}
+		Collections.sort(names);
+		return names;
+	}
+
+	public String showProcessorTree(WorkflowBundle ro) throws JAXBException,
+			IOException {
+		TreeModel treeModel = makeProcessorTree(ro);
+		return treeModelAsString(treeModel);
+	}
+
+	public String treeModelAsString(TreeModel treeModel) {
+		StringBuffer sb = new StringBuffer();
+		Object root = treeModel.getRoot();
+		treeModelAsString(treeModel, root, sb, "");
+		return sb.toString();
+	}
+
+	protected void treeModelAsString(TreeModel treeModel, Object parent,
+			StringBuffer sb, String indentation) {
+		sb.append(indentation);
+		int childCount = treeModel.getChildCount(parent);
+		if (childCount == 0) {
+			sb.append("- ");
+		} else {
+			sb.append("+ ");
+			indentation = indentation + "  ";
+		}
+		sb.append(parent);
+		sb.append("\n");
+		for (int i = 0; i < childCount; i++) {
+			Object child = treeModel.getChild(parent, i);
+			treeModelAsString(treeModel, child, sb, indentation);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/Scufl2Tool.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/Scufl2Tool.java b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/Scufl2Tool.java
new file mode 100644
index 0000000..1f2a842
--- /dev/null
+++ b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/Scufl2Tool.java
@@ -0,0 +1,101 @@
+package org.apache.taverna.examples;
+
+/*
+ * 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.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A wrapper around the other example main() methods
+ * 
+ * This in order to make a single executable JAR file.
+ * 
+ * @author Stian Soiland-Reyes
+ *
+ */
+public class Scufl2Tool {
+    
+    public enum Tool {
+        t2flowtowfbundle(ConvertT2flowToWorkflowBundle.class, "Convert t2flow workflows to wfbundle"),
+        jsonexport(JsonExport.class, "Export JSON structure of workflow"),
+        processornames(ProcessorNames.class, "List tree of processor names in workflow"),
+        servicetypes(ServiceTypes.class, "List service types used in workflow"),
+        workflowmaker(WorkflowMaker.class, "Create an example workflow programmatically");
+        
+        private final String description;
+        private final Class<?> mainClass;
+
+        Tool(Class<?> mainClass, String description) {
+            this.mainClass = mainClass;
+            this.description = description;
+        }
+
+        @Override
+        public String toString() {
+            return name() + " - " + description;
+        }
+
+        public Class<?> getMainClass() {
+            return mainClass;
+        }
+    }
+    
+    public static void main(String[] args) throws IllegalAccessException,
+            IllegalArgumentException, InvocationTargetException,
+            NoSuchMethodException, SecurityException {
+        List<String> argsList = Arrays.asList(args);
+        if (argsList.isEmpty() || argsList.get(0).equals("-h")) {
+            help();
+            return;
+        }
+        Tool tool;
+        try {
+            tool = Tool.valueOf(argsList.get(0).toLowerCase());
+        } catch (IllegalArgumentException e) {
+            System.err.println("Invalid tool: " + argsList.get(0));
+            help();
+            return;
+        }
+        
+        // Find and invoke the main method
+        Class<?> mainCls = tool.getMainClass();
+        Method main = mainCls.getMethod("main", String[].class);
+        // But stripping out the first argument
+        args = argsList.subList(1, argsList.size()).toArray(new String[0]);
+        // Array of arrays!
+        Object[] mainArgs = new Object[]{args};
+        main.invoke(null, mainArgs);
+    }
+
+    public static void help() {
+        System.out.println("SCUFL2 workflow tool");
+        System.out.println("Usage: scufl2tool <tool> [option] ...");
+        System.out.println();
+        System.out.println("Available tools:");
+        for (Tool tool : Tool.values()) {
+            System.out.println(tool);
+        }
+        
+    }
+}
+;

http://git-wip-us.apache.org/repos/asf/incubator-taverna-language/blob/c08405cb/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ServiceTypes.java
----------------------------------------------------------------------
diff --git a/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ServiceTypes.java b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ServiceTypes.java
new file mode 100644
index 0000000..2dcf4fb
--- /dev/null
+++ b/taverna-scufl2-examples/src/main/java/org/apache/taverna/examples/ServiceTypes.java
@@ -0,0 +1,62 @@
+package org.apache.taverna.examples;
+
+/*
+ * 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.File;
+import java.io.IOException;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.taverna.scufl2.api.activity.Activity;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.io.ReaderException;
+import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
+import org.apache.taverna.scufl2.api.io.WriterException;
+import org.apache.taverna.scufl2.api.profiles.Profile;
+
+public class ServiceTypes {
+	public static void main(String[] args) throws Exception, ReaderException,
+			WriterException {
+		for (String type :  new ServiceTypes().serviceTypes(args)) {
+			System.out.println(type);
+		}
+	}
+
+	public Set<String> serviceTypes(String[] filepaths) throws ReaderException, IOException, WriterException {
+		
+		Set<String> types = new LinkedHashSet<String>();
+		
+		WorkflowBundleIO io = new WorkflowBundleIO();
+		for (String filepath : filepaths) {
+			File file = new File(filepath);
+			// mediaType = null  --> guess
+			WorkflowBundle wfBundle = io.readBundle(file, null);
+			
+			for (Profile profile : wfBundle.getProfiles()) {
+				for (Activity activity : profile.getActivities()) {
+					types.add(activity.getType().toASCIIString());
+				}
+			}			
+		}
+		return types;
+	}
+
+}