Add CWL Parser, import helper from common activities
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Parser.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Parser.java
index 65844b9..c0ef438 100644
--- a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Parser.java
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/Parser.java
@@ -1,212 +1,114 @@
+/*
+ * 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.*;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
+import org.apache.taverna.scufl2.api.core.Workflow;
+import org.apache.taverna.scufl2.api.core.Processor;
 
+import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
+import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
+import org.apache.taverna.scufl2.api.port.InputProcessorPort;
+import org.apache.taverna.scufl2.api.port.OutputProcessorPort;
 
-class InputField {
-
-    public String key;
-    public String type;
-    public int position;
-    public String prefix;
-
-    public InputField(String _key) {
-        key = _key;
-        type = "";
-        position = -1;
-        prefix = "";
-    }
-
-    public InputField(String _key, String _type) {
-        key = _key;
-        type = _type;
-        position = -1;
-        prefix = "";
-    }
-
-    public InputField(String _key, String _type, int pos) {
-        key = _key;
-        type = _type;
-        position = pos;
-        prefix = "";
-    }
-
-    public InputField(String _key, String _type, int pos, String _prefix) {
-        key = _key;
-        type = _type;
-        position = pos;
-        prefix = _prefix;
-    }
-}
-
+import com.fasterxml.jackson.databind.JsonNode;
 
 public class Parser {
 
-    private String yamlLine;
-    private int fileLength;
+    private JsonNode cwlFile;
+    private YAMLHelper yamlHelper;
+    private Workflow workflow;
 
-    private Map<Integer, String> yamlFile = null;
-
-    public Parser(File file) {
-        int counter = 0;
-
-        yamlFile = new HashMap<>();
-
-        FileReader yamlFileDescriptor = null;
-
-
-        try {
-            yamlFileDescriptor = new FileReader(file);
-            BufferedReader bufferedReader = new BufferedReader(yamlFileDescriptor);
-            String parent = null;
-            int parentDepth = 0;
-            while((yamlLine = bufferedReader.readLine()) != null) {
-
-                yamlFile.put(counter, yamlLine);
-                counter = counter + 1;
-            }
-
-            bufferedReader.close();
-            fileLength = counter;
-        } catch (IOException e) {
-            System.err.println("Parser init error: " + e );
-        }
+    public Parser(JsonNode cwlFile) {
+        this.cwlFile = cwlFile;
+        this.yamlHelper = new YAMLHelper();
+        this.workflow = new Workflow();
+        this.workflow.setInputPorts(parseInputs());
+        this.workflow.setOutputPorts(parseOutputs());
     }
 
-    public ArrayList<InputField> parseInputs() {
-        int startIndex = 0;
-        int endIndex = -1;
-        int depth = -1;
+    public Workflow getWorkflow() {
+        return this.workflow;
+    }
 
-        /**
-         * Search for start and end of inputs section
-         */
-        for(Map.Entry<Integer, String> entry: yamlFile.entrySet()) {
-            int index = entry.getKey();
-            String line = entry.getValue();
-            String key = getKeyFromLine(line);
-            if(key.equals("inputs")) {
-                startIndex = index;
-                endIndex = index;
-                depth = getDepth(line);
-            } else if(!line.equals("") && getDepth(line) <= depth) {
-                break;
-            } else {
-                endIndex++;
-            }
+    public Set<Step> parseSteps() {
+        return yamlHelper.processSteps(cwlFile);
+    }
+
+    public Processor convertStepToProcessor(Step step) {
+        Processor processor = new Processor(null, step.getId());
+        // Convert input ports
+        Set<InputProcessorPort> processorInputs = new HashSet<>();
+        Set<StepInput> inputs = step.getInputs();
+        for(StepInput input: inputs) {
+            InputProcessorPort port = new InputProcessorPort(processor, input.getId());
+            processorInputs.add(port);
         }
-        /**
-         * Parse each input
-         */
-        ArrayList<InputField> result = new ArrayList<>();
-        for(int i = startIndex+1; i <= endIndex; i++) {
-            int curDepth = getDepth(yamlFile.get(i));
-            // If current element is a child of inputs key
-            if(curDepth == depth + 1) {
-                result.add(parseInputField(i));
-            }
+        processor.setInputPorts(processorInputs);
+        // Convert output ports
+        Set<OutputProcessorPort> processorOutputs = new HashSet<>();
+        Set<StepOutput> outputs = step.getOutputs();
+        for(StepOutput output: outputs) {
+            OutputProcessorPort port = new OutputProcessorPort(processor, output.getId());
+            processorOutputs.add(port);
+        }
+        processor.setOutputPorts(processorOutputs);
+
+        return processor;
+    }
+
+    public Set<InputWorkflowPort> parseInputs() {
+        Map<String, PortDetail> inputs = yamlHelper.processInputDetails(cwlFile);
+        Map<String, Integer> inputDepths = yamlHelper.processInputDepths(cwlFile);
+
+        if(inputs == null || inputDepths == null) {
+            return null;
+        }
+        Set<InputWorkflowPort> result = new HashSet<InputWorkflowPort>();
+        for(String id: inputs.keySet()) {
+            PortDetail detail = inputs.get(id);
+            int depth = inputDepths.get(id);
+            InputWorkflowPort port = new InputWorkflowPort();
+            port.setName(id);
+            port.setDepth(depth);
+            result.add(port);
         }
 
         return result;
     }
 
-    public InputField parseInputField(int startIndex) {
-        String line = yamlFile.get(startIndex);
-        int depth = getDepth(line);
-        String id = getKeyFromLine(line);
-        String value = getValueFromLine(line);
+    public Set<OutputWorkflowPort> parseOutputs() {
+        Map<String, PortDetail> inputs = yamlHelper.processOutputDetails(cwlFile);
 
-        if(!value.equals("")) {
-            return new InputField(id, value);
+        if(inputs == null) {
+            return null;
+        }
+        Set<OutputWorkflowPort> result = new HashSet<OutputWorkflowPort>();
+        for(String id: inputs.keySet()) {
+            PortDetail detail = inputs.get(id);
+            OutputWorkflowPort port = new OutputWorkflowPort();
+            port.setName(id);
+            result.add(port);
         }
 
-        InputField field = new InputField(id);
-        for(int i = startIndex+1; i < length; i++) {
-            String curLine = yamlFile.get(i);
-            if(curLine.equals("")) {
-                // Ignore empty lines
-                continue;
-            }
-            if(getDepth(curLine) <= depth) {
-                // Out of input section
-                break;
-            }
-            String key = getKeyFromLine(curLine);
-            value = getValueFromLine(curLine);
-
-            if(key.trim().equals("type")) {
-                field.type = value;
-            } else if(key.trim().equals("inputBinding")) {
-                
-                int curDepth = getDepth(curLine);
-                int nextIndex = getNextLineIndex(i);
-                String nextLine = yamlFile.get(nextIndex);
-                String nextKey = getKeyFromLine(nextLine);
-                String nextValue = getValueFromLine(nextLine);
-
-                if(nextKey.equals("position")){
-                    field.position = Integer.parseInt(nextValue);
-                } else if(nextKey.equals("prefix")){
-                    field.prefix = nextValue;
-                }
-
-                // Check if we have another inputBinding property
-                nextIndex = getNextLineIndex(nextIndex);
-                nextLine = yamlFile.get(nextIndex);
-                if(getDepth(nextLine) == curDepth + 1) {
-                    nextKey = getKeyFromLine(nextLine);
-                    nextValue = getValueFromLine(nextLine);
-                    if(nextKey.equals("position")){
-                        field.position = Integer.parseInt(nextValue);
-                    } else if(nextKey.equals("prefix")){
-                        field.prefix = nextValue.trim();
-                    }
-                }
-            }
-        }
-
-        return field;
+        return result;
     }
 
-    private int getNextLineIndex(int index) {
-        index++;
-
-        while(yamlFile.get(index).equals("")) {
-            index++;
-        }
-
-        return index;
-    }
-
-    public static int getDepth(String line) {
-        int count = 0;
-        int idx = 0;
-        while(idx < line.length()) {
-            if(line.charAt(idx) != ' ') {
-                break;
-            }
-            count++;
-            idx++;
-        }
-        assert count % 2 == 0;
-        return count / 2;
-    }
-
-    public static String getKeyFromLine(String line) {
-        int commaIndex = line.indexOf(':');
-        assert commaIndex != -1;
-
-        return line.substring(0, commaIndex).trim();
-    }
-
-    public static String getValueFromLine(String line) {
-        int commaIndex = line.indexOf(':');
-        assert commaIndex != -1;
-
-        return line.substring(commaIndex + 1).trim();
-    }
 }
diff --git a/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/YAMLHelper.java b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/YAMLHelper.java
new file mode 100644
index 0000000..dacdc4f
--- /dev/null
+++ b/taverna-scufl2-cwl/src/main/java/org/apache/taverna/scufl2/cwl/YAMLHelper.java
@@ -0,0 +1,484 @@
+/*
+ * 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.util.ArrayList;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.fasterxml.jackson.databind.node.TextNode;
+
+public class YAMLHelper {
+
+    public static final String ARRAY_SPLIT_BRACKETS = "\\[\\]";
+    public static final String ARRAY_SIGNATURE_BRACKETS = "\\[\\]$";
+    private static final String INPUTS = "inputs";
+    private static final String OUTPUTS = "outputs";
+    private static final String STEPS = "steps";
+    private static final String ID = "id";
+    private static final String TYPE = "type";
+    private static final String ARRAY = "array";
+    private static final String DESCRIPTION = "description";
+    private static final int DEPTH_0 = 0;
+    private static final int DEPTH_1 = 1;
+    private static final int DEPTH_2 = 2;
+
+    private static final String FLOAT = "float";
+    private static final String NULL = "null";
+    private static final String BOOLEAN = "boolean";
+    private static final String INT = "int";
+    private static final String DOUBLE = "double";
+    private static final String STRING = "string";
+    private static final String LABEL = "label";
+    private static final String FILE = "file";
+    private static final String DIRECTORY = "directory";
+    private static final String FORMAT = "format";
+    private static final String RUN = "run";
+    private static final String SOURCE = "source";
+
+    private JsonNode nameSpace;
+
+    public YAMLHelper() {
+        this.nameSpace = null;
+    }
+
+    public JsonNode getNameSpace() {
+        return nameSpace;
+    }
+
+    /**
+     * This method is processing the CWL NameSpace for later use such as
+     * figuring out the Format of a input or output
+     */
+    public void processNameSpace(JsonNode file) {
+
+        if (file != null && file.has("$namespaces")) {
+            nameSpace = file.path("$namespaces");
+        }
+
+    }
+
+    public Map<String, Integer> processInputDepths(JsonNode file) {
+        return process(file.get(INPUTS));
+    }
+
+    public Map<String, Integer> processOutputDepths(JsonNode file) {
+        return process(file.get(OUTPUTS));
+    }
+
+    public Map<String, PortDetail> processInputDetails(JsonNode file) {
+        return processdetails(file.get(INPUTS));
+    }
+
+    public Map<String, PortDetail> processOutputDetails(JsonNode file) {
+        return processdetails(file.get(OUTPUTS));
+    }
+
+    /**
+     *
+     */
+    public Set<Step> processSteps(JsonNode file) {
+        Set<Step> result = new HashSet<>();
+
+        if(file == null) {
+            return result;
+        }
+
+        if(file.has(STEPS)) {
+            JsonNode steps = file.get(STEPS);
+            if(steps.isArray()) {
+                for (JsonNode stepNode : steps) {
+                    Step step = new Step();
+                    String id = stepNode.get(ID).asText();
+
+                    String run = stepNode.get(RUN).asText();
+                    Set<StepInput> inputs = processStepInput(stepNode.get(INPUTS));
+                    step.setId(id);
+                    step.setRun(run);
+                    step.setInputs(inputs);
+                    result.add(step);
+                }
+            } else if(steps.isObject()) {
+                Iterator<Entry<String, JsonNode>> iterator = steps.fields();
+                while(iterator.hasNext()) {
+                    Entry<String, JsonNode> entry = iterator.next();
+                    Step step = new Step();
+
+                    String id = entry.getKey();
+                    JsonNode value = entry.getValue();
+                    if(value.has(RUN)) {
+                        String run = entry.getValue().get(RUN).asText();
+                        step.setRun(run);
+                    }
+                    Set<StepInput> inputs = processStepInput(value.get(INPUTS));
+                    step.setId(id);
+                    step.setInputs(inputs);
+
+                    result.add(step);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    private Set<StepInput> processStepInput(JsonNode inputs) {
+
+        Set<StepInput> result = new HashSet<>();
+        if(inputs == null) {
+            return result;
+        }
+        if (inputs.getClass() == ArrayNode.class) {
+
+            for (JsonNode input : inputs) {
+                String id = input.get(ID).asText();
+                String source = input.get(SOURCE).asText();
+
+                result.add(new StepInput(id, source));
+            }
+        } else if (inputs.getClass() == ObjectNode.class) {
+            Iterator<Entry<String, JsonNode>> iterator = inputs.fields();
+            while (iterator.hasNext()) {
+                Entry<String, JsonNode> entry = iterator.next();
+
+                String id = entry.getKey();
+                String source = entry.getValue().get(SOURCE).asText();
+
+                result.add(new StepInput(id, source));
+            }
+        }
+        return result;
+    }
+
+    /**
+     * This method will go through CWL tool input or out puts and figure outs
+     * their IDs and the respective depths
+     *
+     * @param inputs
+     *            This is JsonNode object which contains the Inputs or outputs
+     *            of the respective CWL tool
+     * @return This the respective, ID and the depth of the input or output
+     */
+    public Map<String, Integer> process(JsonNode inputs) {
+
+        Map<String, Integer> result = new HashMap<>();
+
+        if (inputs == null)
+            return result;
+
+        if (inputs.getClass() == ArrayNode.class) {
+            Iterator<JsonNode> iterator = inputs.iterator();
+
+            while (iterator.hasNext()) {
+                JsonNode input = iterator.next();
+                String currentInputId = input.get(ID).asText();
+
+                JsonNode typeConfigurations;
+                try {
+
+                    typeConfigurations = input.get(TYPE);
+                    // if type :single argument
+                    if (typeConfigurations.getClass() == TextNode.class) {
+                        // inputs:
+                        /// -id: input_1
+                        //// type: int[]
+                        if (isValidArrayType(typeConfigurations.asText()))
+                            result.put(currentInputId, DEPTH_1);
+                            // inputs:
+                            /// -id: input_1
+                            //// type: int or int?
+                        else
+                            result.put(currentInputId, DEPTH_0);
+                        // type : defined as another map which contains type:
+                    } else if (typeConfigurations.getClass() == ObjectNode.class) {
+                        // inputs:
+                        /// -id: input_1
+                        //// type:
+                        ///// type: array or int[]
+                        String inputType = typeConfigurations.get(TYPE).asText();
+                        if (inputType.equals(ARRAY) || isValidArrayType(inputType)) {
+                            result.put(currentInputId, DEPTH_1);
+
+                        }
+                        // inputs:
+                        // -id: input_1
+                        // type:
+                        // type: ["null",int]
+                    } else if (typeConfigurations.getClass() == ArrayNode.class) {
+                        if (isValidDataType(typeConfigurations)) {
+                            result.put(currentInputId, DEPTH_0);
+                        }
+
+                    }
+
+                } catch (ClassCastException e) {
+
+                    System.out.println("Class cast exception !!!");
+                }
+
+            }
+        } else if (inputs.getClass() == ObjectNode.class) {
+
+            Iterator<Entry<String, JsonNode>> iterator = inputs.fields();
+
+            while (iterator.hasNext()) {
+                Entry<String, JsonNode> entry = iterator.next();
+                String currentInputId = entry.getKey();
+                JsonNode typeConfigurations = entry.getValue();
+
+                if (typeConfigurations.getClass() == TextNode.class) {
+                    if (typeConfigurations.asText().startsWith("$")) {
+                        System.out.println("Exception");
+                    }
+                    // inputs:
+                    /// input_1: int[]
+                    else if (isValidArrayType(typeConfigurations.asText()))
+                        result.put(currentInputId, DEPTH_1);
+                        // inputs:
+                        /// input_1: int or int?
+                    else
+                        result.put(currentInputId, DEPTH_0);
+
+                } else if (typeConfigurations.getClass() == ObjectNode.class) {
+
+                    if (typeConfigurations.has(TYPE)) {
+                        JsonNode inputType = typeConfigurations.get(TYPE);
+                        // inputs:
+                        /// input_1:
+                        //// type: [int,"null"]
+                        if (inputType.getClass() == ArrayNode.class) {
+                            if (isValidDataType(inputType))
+                                result.put(currentInputId, DEPTH_0);
+                        } else {
+                            // inputs:
+                            /// input_1:
+                            //// type: array or int[]
+                            if (inputType.asText().equals(ARRAY) || isValidArrayType(inputType.asText()))
+                                result.put(currentInputId, DEPTH_1);
+                                // inputs:
+                                /// input_1:
+                                //// type: int or int?
+                            else
+                                result.put(currentInputId, DEPTH_0);
+                        }
+                    }
+                }
+            }
+
+        }
+        return result;
+    }
+
+    /**
+     * This method is used for extracting details of the CWL tool inputs or
+     * outputs. ex:Label, Format, Description
+     *
+     * @param inputs
+     *            This is JsonNode object which contains the Inputs or outputs
+     *            of the respective CWL tool
+     * @return
+     */
+    private Map<String, PortDetail> processdetails(JsonNode inputs) {
+
+        Map<String, PortDetail> result = new HashMap<>();
+        if(inputs == null) {
+            return result;
+        }
+        if (inputs.getClass() == ArrayNode.class) {
+
+            for (JsonNode input : inputs) {
+                PortDetail detail = new PortDetail();
+                String currentInputId = input.get(ID).asText();
+
+                getParamDetails(result, input, detail, currentInputId);
+
+            }
+        } else if (inputs.getClass() == ObjectNode.class) {
+            Iterator<Entry<String, JsonNode>> iterator = inputs.fields();
+            while (iterator.hasNext()) {
+                PortDetail detail = new PortDetail();
+                Entry<String, JsonNode> entry = iterator.next();
+                getParamDetails(result, entry.getValue(), detail, entry.getKey());
+            }
+        }
+        return result;
+    }
+
+    private void getParamDetails(Map<String, PortDetail> result, JsonNode input, PortDetail detail,
+                                 String currentInputId) {
+        extractDescription(input, detail);
+
+        extractFormat(input, detail);
+
+        extractLabel(input, detail);
+
+        result.put(currentInputId, detail);
+    }
+
+    /**
+     * This method is used for extracting the Label of a CWL input or Output
+     *
+     * @param input
+     *            Single CWL input or output as a JsonNode
+     * @param detail
+     *            respective PortDetail Object to hold the extracted Label
+     */
+    public void extractLabel(JsonNode input, PortDetail detail) {
+        if (input != null)
+            if (input.has(LABEL)) {
+                detail.setLabel(input.get(LABEL).asText());
+            } else {
+                detail.setLabel(null);
+            }
+    }
+
+    /**
+     *
+     * @param input
+     *            Single CWL input or output as a JsonNode
+     * @param detail
+     *            respective PortDetail Object to hold the extracted Label
+     */
+    public void extractDescription(JsonNode input, PortDetail detail) {
+        if (input != null)
+            if (input.has(DESCRIPTION)) {
+                detail.setDescription(input.get(DESCRIPTION).asText());
+            } else {
+                detail.setDescription(null);
+            }
+    }
+
+    /**
+     * This method is used for extracting the Formats of a CWL input or Output
+     * Single argument(Input or Output) can have multiple Formats.
+     *
+     * @param input
+     *            Single CWL input or output as a JsonNode
+     * @param detail
+     *            respective PortDetail Object to hold the extracted Label
+     */
+    public void extractFormat(JsonNode input, PortDetail detail) {
+        if (input != null)
+            if (input.has(FORMAT)) {
+
+                JsonNode formatInfo = input.get(FORMAT);
+
+                ArrayList<String> format = new ArrayList<>();
+                detail.setFormat(format);
+
+                if (formatInfo.getClass() == TextNode.class) {
+
+                    figureOutFormats(formatInfo.asText(), detail);
+                } else if (formatInfo.getClass() == ArrayNode.class) {
+                    for (JsonNode eachFormat : formatInfo) {
+                        figureOutFormats(eachFormat.asText(), detail);
+                    }
+                }
+
+            }
+    }
+
+    /**
+     * Re Format the CWL format using the NameSpace in CWL Tool if possible
+     * otherwise it doesn't change the current nameSpace => edam:http://edam.org
+     * format : edam :1245 => http://edamontology.org/1245
+     *
+     * @param formatInfoString
+     *            Single Format
+     * @param detail
+     *            respective PortDetail Object to hold the extracted Label
+     */
+    public void figureOutFormats(String formatInfoString, PortDetail detail) {
+        if (formatInfoString.startsWith("$")) {
+
+            detail.addFormat(formatInfoString);
+        } else if (formatInfoString.contains(":")) {
+            String format[] = formatInfoString.split(":");
+            String namespaceKey = format[0];
+            String urlAppednd = format[1];
+
+            if (nameSpace.has(namespaceKey))
+                detail.addFormat(nameSpace.get(namespaceKey).asText() + urlAppednd);
+            else
+                // can't figure out the format
+                detail.addFormat(formatInfoString);
+
+        } else {
+            // can't figure out the format
+            detail.addFormat(formatInfoString);
+        }
+    }
+
+    /**
+     * This method is used to check whether the input/output is valid CWL TYPE
+     * when the type is represented as type: ["null","int"]
+     *
+     * @param typeConfigurations
+     *            Type of the CWl input or output
+     * @return
+     */
+    public boolean isValidDataType(JsonNode typeConfigurations) {
+        if (typeConfigurations == null)
+            return false;
+        for (JsonNode type : typeConfigurations) {
+            if (!(type.asText().equals(FLOAT) || type.asText().equals(NULL) || type.asText().equals(BOOLEAN)
+                    || type.asText().equals(INT) || type.asText().equals(STRING) || type.asText().equals(DOUBLE)
+                    || type.asText().equals(FILE)||type.asText().equals(DIRECTORY)))
+                return false;
+        }
+        return true;
+    }
+
+    /**
+     *
+     * This method is for figure out whether the parameter is an array or not.
+     * As from CWL document v1.0, array can be defined as "TYPE[]". For Example
+     * : int[] This method will look for "[]" sequence of characters in the end
+     * of the type and is provided type is a valid CWL TYPE or not
+     *
+     * @param type
+     *            type of the CWL parameter
+     * @return
+     */
+    public boolean isValidArrayType(String type) {
+        if (type == null)
+            return false;
+        Pattern pattern = Pattern.compile(ARRAY_SIGNATURE_BRACKETS);
+        Matcher matcher = pattern.matcher(type);
+        ObjectMapper mapper = new ObjectMapper();
+        ArrayNode node = mapper.createArrayNode();
+        node.add(type.split(ARRAY_SPLIT_BRACKETS)[0]);
+        if (matcher.find() && isValidDataType(node))
+            return true;
+        else
+            return false;
+    }
+}
\ No newline at end of file