Convert WorkflowProcess to WorkflowBundle with nested processes
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Converter.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Converter.java
index 687a278..086d9dd 100644
--- a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Converter.java
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Converter.java
@@ -25,6 +25,7 @@
 
 import org.apache.taverna.scufl2.api.core.Workflow;
 import org.apache.taverna.scufl2.api.core.Processor;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
 
 import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
 import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
@@ -158,4 +159,47 @@
 
         return port;
     }
+
+    public WorkflowBundle buildWorkflowBundle(Process process) {
+        WorkflowBundle bundle = new WorkflowBundle();
+        if(!(process instanceof WorkflowProcess)) {
+            throw new UnsupportedOperationException("WorkflowBundle is not created without an initial workflow yet");
+        }
+        Workflow workflow = convertWorkflowProcess((WorkflowProcess) process, bundle);
+        workflow.setParent(bundle);
+
+        return bundle;
+    }
+
+    public Workflow convertWorkflowProcess(WorkflowProcess workflowProcess, WorkflowBundle bundle) {
+        Workflow workflow = new Workflow();
+        Set<InputWorkflowPort> inputs = new HashSet<>(workflowProcess.getWorkflowInputs().values());
+        Set<OutputWorkflowPort> outputs = new HashSet<>(workflowProcess.getWorkflowOutputs().values());
+        workflow.setInputPorts(inputs);
+        workflow.setOutputPorts(outputs);
+
+        for(Process process: workflowProcess.getProcesses()) {
+            if(process instanceof WorkflowProcess) {
+                Workflow childWorkflow = convertWorkflowProcess((WorkflowProcess) process, bundle); // TODO: Add nested relationship
+                bundle.getWorkflows().add(childWorkflow);
+            } else if(process instanceof CommandLineTool) {
+                Processor processor = convertCommandLineTool((CommandLineTool) process);
+                workflow.getProcessors().add(processor);
+            } else {
+                assert(process instanceof Reference);
+                Processor processor = convertReference((Reference) process);
+                workflow.getProcessors().add(processor);
+            }
+        }
+
+        return workflow;
+    }
+
+    public Processor convertCommandLineTool(CommandLineTool command) {
+        return new Processor(null, command.getBaseCommand());
+    }
+
+    public Processor convertReference(Reference reference) {
+        return new Processor(null, reference.getSource());
+    }
 }
\ No newline at end of file
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Reference.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Reference.java
index 7a25744..193e1a6 100644
--- a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Reference.java
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/components/Reference.java
@@ -40,4 +40,8 @@
     public String toString() {
         return source;
     }
+
+    public String getSource() {
+        return source;
+    }
 }
\ No newline at end of file
diff --git a/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestConverting.java b/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestConverting.java
new file mode 100644
index 0000000..b17cc88
--- /dev/null
+++ b/taverna-scufl2-cwl/src/test/java/org/apache/taverna/scufl2/cwl/TestConverting.java
@@ -0,0 +1,88 @@
+/*
+ * 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 org.apache.taverna.scufl2.cwl;
+
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+import org.yaml.snakeyaml.Yaml;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+import org.apache.taverna.scufl2.api.core.Workflow;
+
+import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
+import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
+
+import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
+import org.apache.taverna.scufl2.api.io.WriterException;
+
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+
+public class TestConverting {
+    private static final String HELLO_WORLD_CWL = "/hello_world.cwl";
+    private static final String WORKFLOW_WITH_COMMAND = "/workflow_with_command.cwl";
+    private static final String WORKFLOW_WITH_WORKFLOW = "/workflow_with_workflow.cwl";
+
+    private static JsonNode cwlFile;
+
+    public JsonNode loadYamlFile(String filename) {
+
+        Yaml reader = new Yaml();
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode node = mapper.valueToTree(reader.load(TestWorkflowProcess.class.getResourceAsStream(filename)));
+
+        return node;
+    }
+
+    @Test
+    public void testWorkflowBundleWithOneWorkflow() {
+        JsonNode cwlFile = loadYamlFile(HELLO_WORLD_CWL);
+
+        WorkflowProcess workflow = (WorkflowProcess) ProcessFactory.createProcess(cwlFile);
+        Converter converter = new Converter();
+        WorkflowBundle workflowBundle = converter.buildWorkflowBundle(workflow);
+
+        assertEquals(workflowBundle.getWorkflows().size(), 1);
+    }
+
+    @Test
+    public void testWorkflowBundleWithMultipleWorkflows() {
+        JsonNode cwlFile = loadYamlFile(WORKFLOW_WITH_WORKFLOW);
+
+        WorkflowProcess workflow = (WorkflowProcess) ProcessFactory.createProcess(cwlFile);
+        Converter converter = new Converter();
+        WorkflowBundle workflowBundle = converter.buildWorkflowBundle(workflow);
+
+        assertEquals(workflowBundle.getWorkflows().size(), 2);
+    }
+
+}