{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "type": "object",
    "properties": {
        "class": {
            "type": "string"
        },
        "id": {
            "description": "The unique identifier for this process object.",
            "type": "string"
        },
        "requirements": {
            "description": "Declares requirements that apply to either the runtime environment or the\n\nworkflow engine that must be met in order to execute this process.  If\n\nan implementation cannot satisfy all requirements, or a requirement is\n\nlisted which is not recognized by the implementation, it is a fatal\n\nerror and the implementation must not attempt to run the process,\n\nunless overridden at user option.",
            "$ref": "#/definitions/Requirements"
        },
        "hints": {
            "description": "Declares hints applying to either the runtime environment or the\n\nworkflow engine that may be helpful in executing this process.  It is\n\nnot an error if an implementation cannot satisfy all hints, however\n\nthe implementation may report a warning.",
            "oneOf": [
                {
                    "type": "array",
                    "items": {}
                },
                {
                    "type": "object"
                }
            ]
        },
        "label": {
            "description": "A short, human-readable label of this process object.",
            "type": "string"
        },
        "doc": {
            "description": "A long, human-readable description of this process object.",
            "type": "string"
        },
        "cwlVersion": {
            "description": "CWL document version. Always required at the document root. Not\n\nrequired for a Process embedded inside another Process.",
            "$ref": "#/definitions/CWLVersion"
        }
    },
    "required": [
        "class"
    ],
    "oneOf": [
        {
            "$ref": "#/definitions/CommandLineTool"
        },
        {
            "$ref": "#/definitions/ExpressionTool"
        },
        {
            "$ref": "#/definitions/Workflow"
        }
    ],
    "definitions": {
        "PrimitiveCwlType": {
            "type": "string",
            "enum": [
                "null",
                "boolean",
                "int",
                "long",
                "float",
                "string",
                "File",
                "Directory"
            ]
        },
        "AvroPrimitiveType": {
            "type": "object",
            "properties": {
                "type": {
                    "$ref": "#/definitions/PrimitiveCwlType"
                }
            }
        },
        "CwlType": {
            "anyOf": [
                {
                    "$ref": "#/definitions/PrimitiveCwlType"
                },
                {
                    "$ref": "#/definitions/AvroPrimitiveType"
                },
                {
                    "$ref": "#/definitions/OutputRecordSchema"
                },
                {
                    "$ref": "#/definitions/OutputEnumSchema"
                },
                {
                    "$ref": "#/definitions/OutputArraySchema"
                },
                {
                    "type": "string"
                },
                {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/CwlType"
                    }
                }
            ]
        },
        "StringOrArrayOfStrings": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                }
            ]
        },
        "ObjectWithId": {
            "type": "object",
            "properties": {
                "id": {
                    "description": "The unique identifier for this object.",
                    "type": "string"
                }
            },
            "required": [
                "id"
            ]
        },
        "ObjectWithClass": {
            "type": "object",
            "properties": {
                "class": {
                    "type": "string"
                }
            },
            "required": [
                "class"
            ]
        },
        "ProcessRequirement": {
            "description": "A process requirement declares a prerequisite that may or must be fulfilled\n\nbefore executing a process.  See [`Process.hints`](#process) and\n\n[`Process.requirements`](#process).\n\n\n\nProcess requirements are the primary mechanism for specifying extensions to\n\nthe CWL core specification.",
            "type": "object",
            "properties": {}
        },
        "CWLVersion": {
            "type": "string",
            "enum": [
                "v1.0"
            ]
        },
        "Requirements": {
            "oneOf": [
                {
                    "type": "array",
                    "items": {
                        "allOf": [
                            {
                                "$ref": "#/definitions/ProcessRequirement"
                            },
                            {
                                "$ref": "#/definitions/ObjectWithClass"
                            }
                        ]
                    }
                },
                {
                    "type": "object",
                    "additionalProperties": {
                        "$ref": "#/definitions/ProcessRequirement"
                    }
                }
            ]
        },
        "Parameter": {
            "type": "object",
            "properties": {
                "secondaryFiles": {
                    "description": "Only valid when `type: File` or is an array of `items: File`.\n\n\n\nDescribes files that must be included alongside the primary file(s).\n\n\n\nIf the value is an expression, the value of `self` in the expression\n\nmust be the primary input or output File to which this binding applies.\n\n\n\nIf the value is a string, it specifies that the following pattern\n\nshould be applied to the primary file:\n\n\n\n1. If string begins with one or more caret `^` characters, for each\n\ncaret, remove the last file extension from the path (the last\n\nperiod `.` and all following characters).  If there are no file\n\nextensions, the path is unchanged.\n\n2. Append the remainder of the string to the end of the file path.",
                    "$ref": "#/definitions/StringOrArrayOfStrings"
                },
                "format": {
                    "description": "Only valid when `type: File` or is an array of `items: File`.\n\n\n\nFor input parameters, this must be one or more IRIs of concept nodes\n\nthat represents file formats which are allowed as input to this\n\nparameter, preferrably defined within an ontology.  If no ontology is\n\navailable, file formats may be tested by exact match.\n\n\n\nFor output parameters, this is the file format that will be assigned to\n\nthe output parameter.",
                    "$ref": "#/definitions/StringOrArrayOfStrings"
                },
                "streamable": {
                    "description": "Only valid when `type: File` or is an array of `items: File`.\n\n\n\nA value of `true` indicates that the file is read or written\n\nsequentially without seeking.  An implementation may use this flag to\n\nindicate whether it is valid to stream file contents using a named\n\npipe.  Default: `false`.",
                    "type": "boolean"
                },
                "doc": {
                    "description": "A documentation string for this type, or an array of strings which should be concatenated.",
                    "$ref": "#/definitions/StringOrArrayOfStrings"
                },
                "label": {
                    "description": "A short, human-readable label of this object.",
                    "type": "string"
                }
            }
        },
        "OutputRecordSchema": {
            "type": "object",
            "properties": {
                "fields": {
                    "description": "Defines the fields of the record.",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/OutputRecordField"
                    }
                },
                "type": {
                    "description": "Must be `record`",
                    "type": "string",
                    "enum": [
                        "record"
                    ]
                },
                "label": {
                    "description": "A short, human-readable label of this object.",
                    "type": "string"
                }
            },
            "required": [
                "type"
            ]
        },
        "OutputRecordField": {
            "type": "object",
            "properties": {
                "outputBinding": {
                    "$ref": "#/definitions/OutputBinding"
                },
                "type": {
                    "description": "The field type",
                    "$ref": "#/definitions/CwlType"
                },
                "name": {
                    "description": "The name of the field",
                    "type": "string"
                },
                "doc": {
                    "description": "A documentation string for this field",
                    "type": "string"
                }
            },
            "required": [
                "type",
                "name"
            ]
        },
        "OutputBinding": {
            "type": "object",
            "properties": {}
        },
        "OutputEnumSchema": {
            "type": "object",
            "properties": {
                "outputBinding": {
                    "$ref": "#/definitions/OutputBinding"
                },
                "type": {
                    "description": "Must be `enum`",
                    "type": "string",
                    "enum": [
                        "enum"
                    ]
                },
                "symbols": {
                    "description": "Defines the set of valid symbols.",
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "label": {
                    "description": "A short, human-readable label of this object.",
                    "type": "string"
                }
            },
            "required": [
                "type",
                "symbols"
            ]
        },
        "OutputArraySchema": {
            "type": "object",
            "properties": {
                "outputBinding": {
                    "$ref": "#/definitions/OutputBinding"
                },
                "items": {
                    "description": "Defines the type of the array elements.",
                    "$ref": "#/definitions/CwlType"
                },
                "type": {
                    "description": "Must be `array`",
                    "type": "string",
                    "enum": [
                        "array"
                    ]
                },
                "label": {
                    "description": "A short, human-readable label of this object.",
                    "type": "string"
                }
            },
            "required": [
                "items",
                "type"
            ]
        },
        "InputParameter": {
            "allOf": [
                {
                    "type": "object",
                    "properties": {
                        "inputBinding": {
                            "$ref": "#/definitions/InputBinding",
                            "description": "Describes how to handle the inputs of a process and convert them\n\ninto a concrete form for execution, such as command line parameters."
                        },
                        "default": {
                            "description": "The default value for this parameter if not provided in the input\n\nobject."
                        },
                        "type": {
                            "description": "Specify valid types of data that may be assigned to this parameter.",
                            "$ref": "#/definitions/CwlType"
                        },
                        "secondaryFiles": {
                            "$ref": "#/definitions/StringOrArrayOfStrings"
                        }
                    }
                },
                {
                    "$ref": "#/definitions/Parameter"
                }
            ]
        },
        "InputBinding": {
            "type": "object",
            "properties": {
                "loadContents": {
                    "description": "Only valid when `type: File` or is an array of `items: File`.\n\n\n\nRead up to the first 64 KiB of text from the file and place it in the\n\n\"contents\" field of the file object for use by expressions.",
                    "type": "boolean"
                }
            }
        },
        "InputRecordSchema": {
            "type": "object",
            "properties": {
                "fields": {
                    "description": "Defines the fields of the record.",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/InputRecordField"
                    }
                },
                "type": {
                    "description": "Must be `record`",
                    "type": "string",
                    "enum": [
                        "record"
                    ]
                },
                "label": {
                    "description": "A short, human-readable label of this object.",
                    "type": "string"
                }
            },
            "required": [
                "type"
            ]
        },
        "InputRecordField": {
            "type": "object",
            "properties": {
                "inputBinding": {
                    "$ref": "#/definitions/InputBinding"
                },
                "label": {
                    "description": "A short, human-readable label of this process object.",
                    "type": "string"
                },
                "type": {
                    "description": "The field type",
                    "$ref": "#/definitions/CwlType"
                },
                "name": {
                    "description": "The name of the field",
                    "type": "string"
                },
                "doc": {
                    "description": "A documentation string for this field",
                    "type": "string"
                }
            },
            "required": [
                "type",
                "name"
            ]
        },
        "InputEnumSchema": {
            "type": "object",
            "properties": {
                "inputBinding": {
                    "$ref": "#/definitions/InputBinding"
                },
                "type": {
                    "description": "Must be `enum`",
                    "type": "string",
                    "enum": [
                        "enum"
                    ]
                },
                "symbols": {
                    "description": "Defines the set of valid symbols.",
                    "type": "array",
                    "items": {
                        "type": "string"
                    }
                },
                "label": {
                    "description": "A short, human-readable label of this object.",
                    "type": "string"
                }
            },
            "required": [
                "type",
                "symbols"
            ]
        },
        "InputArraySchema": {
            "type": "object",
            "properties": {
                "inputBinding": {
                    "$ref": "#/definitions/InputBinding"
                },
                "items": {
                    "description": "Defines the type of the array elements.",
                    "$ref": "#/definitions/CwlType"
                },
                "type": {
                    "description": "Must be `array`",
                    "type": "string",
                    "enum": [
                        "array"
                    ]
                },
                "label": {
                    "description": "A short, human-readable label of this object.",
                    "type": "string"
                }
            },
            "required": [
                "items",
                "type"
            ]
        },
        "Inputs": {
            "oneOf": [
                {
                    "type": "array",
                    "items": {
                        "allOf": [
                            {
                                "$ref": "#/definitions/InputParameter"
                            },
                            {
                                "$ref": "#/definitions/ObjectWithId"
                            }
                        ]
                    }
                },
                {
                    "type": "object",
                    "additionalProperties": {
                        "anyOf": [
                            {
                                "$ref": "#/definitions/InputParameter"
                            },
                            {
                                "$ref": "#/definitions/CwlType"
                            }
                        ]
                    }
                }
            ]
        },
        "ExpressionToolOutputParameter": {
            "allOf": [
                {
                    "type": "object",
                    "properties": {
                        "type": {
                            "description": "Specify valid types of data that may be assigned to this parameter.",
                            "$ref": "#/definitions/CwlType"
                        },
                        "outputBinding": {
                            "$ref": "#/definitions/OutputBinding",
                            "description": "Describes how to handle the outputs of a process."
                        }
                    }
                },
                {
                    "$ref": "#/definitions/Parameter"
                }
            ]
        },
        "ExpressionToolOutputParameters": {
            "oneOf": [
                {
                    "type": "array",
                    "items": {
                        "allOf": [
                            {
                                "$ref": "#/definitions/ExpressionToolOutputParameter"
                            },
                            {
                                "$ref": "#/definitions/ObjectWithId"
                            }
                        ]
                    }
                },
                {
                    "type": "object",
                    "additionalProperties": {
                        "$ref": "#/definitions/ExpressionToolOutputParameter"
                    }
                }
            ]
        },
        "ScatterMethod": {
            "anyOf": [
                {
                    "type": "string",
                    "enum": [
                        "dotproduct",
                        "nested_crossproduct",
                        "flat_crossproduct"
                    ]
                },
                {
                    "type": "null"
                }
            ]
        },
        "WorkflowStep": {
            "description": "A workflow step is an executable element of a workflow.  It specifies the\n\nunderlying process implementation (such as `CommandLineTool` or another\n\n`Workflow`) in the `run` field and connects the input and output parameters\n\nof the underlying process to workflow parameters.\n\n\n\n# Scatter/gather\n\n\n\nTo use scatter/gather,\n\n[ScatterFeatureRequirement](#ScatterFeatureRequirement) must be specified\n\nin the workflow or workflow step requirements.\n\n\n\nA \"scatter\" operation specifies that the associated workflow step or\n\nsubworkflow should execute separately over a list of input elements.  Each\n\njob making up a scatter operation is independent and may be executed\n\nconcurrently.\n\n\n\nThe `scatter` field specifies one or more input parameters which will be\n\nscattered.  An input parameter may be listed more than once.  The declared\n\ntype of each input parameter is implicitly wrapped in an array for each\n\ntime it appears in the `scatter` field.  As a result, upstream parameters\n\nwhich are connected to scattered parameters may be arrays.\n\n\n\nAll output parameter types are also implicitly wrapped in arrays.  Each job\n\nin the scatter results in an entry in the output array.\n\n\n\nIf `scatter` declares more than one input parameter, `scatterMethod`\n\ndescribes how to decompose the input into a discrete set of jobs.\n\n\n\n* **dotproduct** specifies that each of the input arrays are aligned and one\n\nelement taken from each array to construct each job.  It is an error\n\nif all input arrays are not the same length.\n\n\n\n* **nested_crossproduct** specifies the Cartesian product of the inputs,\n\nproducing a job for every combination of the scattered inputs.  The\n\noutput must be nested arrays for each level of scattering, in the\n\norder that the input arrays are listed in the `scatter` field.\n\n\n\n* **flat_crossproduct** specifies the Cartesian product of the inputs,\n\nproducing a job for every combination of the scattered inputs.  The\n\noutput arrays must be flattened to a single level, but otherwise listed in the\n\norder that the input arrays are listed in the `scatter` field.\n\n\n\n# Subworkflows\n\n\n\nTo specify a nested workflow as part of a workflow step,\n\n[SubworkflowFeatureRequirement](#SubworkflowFeatureRequirement) must be\n\nspecified in the workflow or workflow step requirements.",
            "type": "object",
            "properties": {
                "in": {
                    "description": "Defines the input parameters of the workflow step.  The process is ready to\n\nrun when all required input parameters are associated with concrete\n\nvalues.  Input parameters include a schema for each parameter which is\n\nused to validate the input object.  It may also be used build a user\n\ninterface for constructing the input object.",
                    "$ref": "#/definitions/WorkflowStepInputs"
                },
                "out": {
                    "description": "Defines the parameters representing the output of the process.  May be\n\nused to generate and/or validate the output object.",
                    "type": "array",
                    "items": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "$ref": "#/definitions/WorkflowStepOutput"
                            }
                        ]
                    }
                },
                "requirements": {
                    "description": "Declares requirements that apply to either the runtime environment or the\n\nworkflow engine that must be met in order to execute this process.  If\n\nan implementation cannot satisfy all requirements, or a requirement is\n\nlisted which is not recognized by the implementation, it is a fatal\n\nerror and the implementation must not attempt to run the process,\n\nunless overridden at user option.",
                    "$ref": "#/definitions/Requirements"
                },
                "hints": {
                    "description": "Declares hints applying to either the runtime environment or the\n\nworkflow engine that may be helpful in executing this process.  It is\n\nnot an error if an implementation cannot satisfy all hints, however\n\nthe implementation may report a warning.",
                    "oneOf": [
                        {
                            "type": "array",
                            "items": {}
                        },
                        {
                            "type": "object"
                        }
                    ]
                },
                "label": {
                    "description": "A short, human-readable label of this process object.",
                    "type": "string"
                },
                "doc": {
                    "description": "A long, human-readable description of this process object.",
                    "type": "string"
                },
                "run": {
                    "description": "Specifies the process to run.",
                    "anyOf": [
                        {
                            "type": "string"
                        },
                        {
                            "$ref": "#"
                        }
                    ]
                },
                "scatter": {
                    "anyOf": [
                        {
                            "type": "null"
                        },
                        {
                            "$ref": "#/definitions/StringOrArrayOfStrings"
                        }
                    ]
                },
                "scatterMethod": {
                    "$ref": "#/definitions/ScatterMethod",
                    "description": "Required if `scatter` is an array of more than one element."
                }
            },
            "required": [
                "in",
                "out",
                "run"
            ]
        },
        "WorkflowStepInput": {
            "description": "The input of a workflow step connects an upstream parameter (from the\n\nworkflow inputs, or the outputs of other workflows steps) with the input\n\nparameters of the underlying step.\n\n\n\n## Input object\n\n\n\nA WorkflowStepInput object must contain an `id` field in the form\n\n`#fieldname` or `#stepname.fieldname`.  When the `id` field contains a\n\nperiod `.` the field name consists of the characters following the final\n\nperiod.  This defines a field of the workflow step input object with the\n\nvalue of the `source` parameter(s).\n\n\n\n## Merging\n\n\n\nTo merge multiple inbound data links,\n\n[MultipleInputFeatureRequirement](#MultipleInputFeatureRequirement) must be specified\n\nin the workflow or workflow step requirements.\n\n\n\nIf the sink parameter is an array, or named in a [workflow\n\nscatter](#WorkflowStep) operation, there may be multiple inbound data links\n\nlisted in the `source` field.  The values from the input links are merged\n\ndepending on the method specified in the `linkMerge` field.  If not\n\nspecified, the default method is \"merge_nested\".\n\n\n\n* **merge_nested**\n\n\n\nThe input must be an array consisting of exactly one entry for each\n\ninput link.  If \"merge_nested\" is specified with a single link, the value\n\nfrom the link must be wrapped in a single-item list.\n\n\n\n* **merge_flattened**\n\n\n\n1. The source and sink parameters must be compatible types, or the source\n\ntype must be compatible with single element from the \"items\" type of\n\nthe destination array parameter.\n\n2. Source parameters which are arrays are concatenated.\n\nSource parameters which are single element types are appended as\n\nsingle elements.",
            "type": "object",
            "properties": {
                "default": {
                    "description": "The default value for this parameter if there is no `source`\n\nfield."
                },
                "valueFrom": {
                    "description": "To use valueFrom, [StepInputExpressionRequirement](#StepInputExpressionRequirement) must\n\nbe specified in the workflow or workflow step requirements.\n\n\n\nIf `valueFrom` is a constant string value, use this as the value for\n\nthis input parameter.\n\n\n\nIf `valueFrom` is a parameter reference or expression, it must be\n\nevaluated to yield the actual value to be assiged to the input field.\n\n\n\nThe `self` value of in the parameter reference or expression must be\n\nthe value of the parameter(s) specified in the `source` field, or\n\nnull if there is no `source` field.\n\n\n\nThe value of `inputs` in the parameter reference or expression must be\n\nthe input object to the workflow step after assigning the `source`\n\nvalues and then scattering.  The order of evaluating `valueFrom` among\n\nstep input parameters is undefined and the result of evaluating\n\n`valueFrom` on a parameter must not be visible to evaluation of\n\n`valueFrom` on other parameters.",
                    "type": "string"
                },
                "source": {
                    "description": "Specifies one or more workflow parameters that will provide input to\n\nthe underlying step parameter.",
                    "$ref": "#/definitions/StringOrArrayOfStrings"
                },
                "linkMerge": {
                    "$ref": "#/definitions/LinkMergeMethod",
                    "description": "The method to use to merge multiple inbound links into a single array.\n\nIf not specified, the default method is \"merge_nested\"."
                }
            }
        },
        "LinkMergeMethod": {
            "type": "string",
            "enum": [
                "merge_nested",
                "merge_flattened"
            ]
        },
        "WorkflowStepOutput": {
            "description": "Associate an output parameter of the underlying process with a workflow\n\nparameter.  The workflow parameter (given in the `id` field) be may be used\n\nas a `source` to connect with input parameters of other workflow steps, or\n\nwith an output parameter of the process.",
            "type": "object",
            "properties": {
                "id": {
                    "description": "A unique identifier for this workflow output parameter.  This is the\n\nidentifier to use in the `source` field of `WorkflowStepInput` to\n\nconnect the output value to downstream parameters.",
                    "type": "string"
                }
            },
            "required": [
                "id"
            ]
        },
        "WorkflowOutputParameter": {
            "description": "Describe an output parameter of a workflow.  The parameter must be\n\nconnected to one or more parameters defined in the workflow that will\n\nprovide the value of the output parameter.",
            "allOf": [
                {
                    "$ref": "#/definitions/Parameter"
                },
                {
                    "type": "object",
                    "properties": {
                        "outputSource": {
                            "description": "Specifies one or more workflow parameters that supply the value of to\n\nthe output parameter.",
                            "$ref": "#/definitions/StringOrArrayOfStrings"
                        },
                        "linkMerge": {
                            "$ref": "#/definitions/LinkMergeMethod",
                            "description": "The method to use to merge multiple sources into a single array.\n\nIf not specified, the default method is \"merge_nested\"."
                        }
                    }
                }
            ]
        },
        "WorkflowOutputParameters": {
            "oneOf": [
                {
                    "type": "array",
                    "items": {
                        "allOf": [
                            {
                                "$ref": "#/definitions/WorkflowOutputParameter"
                            },
                            {
                                "$ref": "#/definitions/ObjectWithId"
                            }
                        ]
                    }
                },
                {
                    "type": "object",
                    "additionalProperties": {
                        "anyOf": [
                            {
                                "$ref": "#/definitions/WorkflowOutputParameter"
                            },
                            {
                                "$ref": "#/definitions/CwlType"
                            }
                        ]
                    }
                }
            ]
        },
        "WorkflowStepInputs": {
            "oneOf": [
                {
                    "type": "array",
                    "items": {
                        "allOf": [
                            {
                                "$ref": "#/definitions/WorkflowStepInput"
                            },
                            {
                                "$ref": "#/definitions/ObjectWithId"
                            }
                        ]
                    }
                },
                {
                    "type": "object",
                    "additionalProperties": {
                        "anyOf": [
                            {
                                "$ref": "#/definitions/WorkflowStepInput"
                            },
                            {
                                "$ref": "#/definitions/StringOrArrayOfStrings"
                            }
                        ]
                    }
                }
            ]
        },
        "WorkflowSteps": {
            "oneOf": [
                {
                    "type": "array",
                    "items": {
                        "allOf": [
                            {
                                "$ref": "#/definitions/WorkflowStep"
                            },
                            {
                                "$ref": "#/definitions/ObjectWithId"
                            }
                        ]
                    }
                },
                {
                    "type": "object",
                    "additionalProperties": {
                        "$ref": "#/definitions/WorkflowStep"
                    }
                }
            ]
        },
        "CommandInputType": {
            "anyOf": [
                {
                    "$ref": "#/definitions/CwlType"
                },
                {
                    "$ref": "#/definitions/CommandInputRecordSchema"
                },
                {
                    "$ref": "#/definitions/CommandInputEnumSchema"
                },
                {
                    "$ref": "#/definitions/CommandInputArraySchema"
                },
                {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/CommandInputType"
                    }
                }
            ]
        },
        "CommandOutputType": {
            "anyOf": [
                {
                    "$ref": "#/definitions/CwlType"
                },
                {
                    "$ref": "#/definitions/CommandOutputRecordSchema"
                },
                {
                    "$ref": "#/definitions/CommandOutputEnumSchema"
                },
                {
                    "$ref": "#/definitions/CommandOutputArraySchema"
                },
                {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/CommandOutputType"
                    }
                }
            ]
        },
        "CommandLineBinding": {
            "description": "When listed under `inputBinding` in the input schema, the term\n\n\"value\" refers to the the corresponding value in the input object.  For\n\nbinding objects listed in `CommandLineTool.arguments`, the term \"value\"\n\nrefers to the effective value after evaluating `valueFrom`.\n\n\n\nThe binding behavior when building the command line depends on the data\n\ntype of the value.  If there is a mismatch between the type described by\n\nthe input schema and the effective value, such as resulting from an\n\nexpression evaluation, an implementation must use the data type of the\n\neffective value.\n\n\n\n- **string**: Add `prefix` and the string to the command line.\n\n\n\n- **number**: Add `prefix` and decimal representation to command line.\n\n\n\n- **boolean**: If true, add `prefix` to the command line.  If false, add\n\nnothing.\n\n\n\n- **File**: Add `prefix` and the value of\n\n[`File.path`](#File) to the command line.\n\n\n\n- **array**: If `itemSeparator` is specified, add `prefix` and the join\n\nthe array into a single string with `itemSeparator` separating the\n\nitems.  Otherwise first add `prefix`, then recursively process\n\nindividual elements.\n\n\n\n- **object**: Add `prefix` only, and recursively add object fields for\n\nwhich `inputBinding` is specified.\n\n\n\n- **null**: Add nothing.",
            "type": "object",
            "properties": {
                "position": {
                    "description": "The sorting key.  Default position is 0.",
                    "type": "number"
                },
                "prefix": {
                    "description": "Command line prefix to add before the value.",
                    "type": "string"
                },
                "separate": {
                    "description": "If true (default), then the prefix and value must be added as separate\n\ncommand line arguments; if false, prefix and value must be concatenated\n\ninto a single command line argument.",
                    "type": "boolean"
                },
                "itemSeparator": {
                    "description": "Join the array elements into a single string with the elements\n\nseparated by by `itemSeparator`.",
                    "type": "string"
                },
                "valueFrom": {
                    "description": "If `valueFrom` is a constant string value, use this as the value and\n\napply the binding rules above.\n\n\n\nIf `valueFrom` is an expression, evaluate the expression to yield the\n\nactual value to use to build the command line and apply the binding\n\nrules above.  If the inputBinding is associated with an input\n\nparameter, the value of `self` in the expression will be the value of the\n\ninput parameter.\n\n\n\nWhen a binding is part of the `CommandLineTool.arguments` field,\n\nthe `valueFrom` field is required.",
                    "type": "string"
                },
                "shellQuote": {
                    "description": "If `ShellCommandRequirement` is in the requirements for the current command,\n\nthis controls whether the value is quoted on the command line (default is true).\n\nUse `shellQuote: false` to inject metacharacters for operations such as pipes.",
                    "type": "boolean"
                },
                "loadContents": {
                    "description": "Only valid when `type: File` or is an array of `items: File`.\n\n\n\nRead up to the first 64 KiB of text from the file and place it in the\n\n\"contents\" field of the file object for use by expressions.",
                    "type": "boolean"
                }
            }
        },
        "CommandInputParameter": {
            "description": "An input parameter for a CommandLineTool.",
            "allOf": [
                {
                    "$ref": "#/definitions/InputParameter"
                },
                {
                    "type": "object",
                    "properties": {
                        "inputBinding": {
                            "$ref": "#/definitions/CommandLineBinding",
                            "description": "Describes how to handle the inputs of a process and convert them\n\ninto a concrete form for execution, such as command line parameters."
                        },
                        "type": {
                            "$ref": "#/definitions/CommandInputType"
                        }
                    }
                }
            ]
        },
        "CommandInputParameters": {
            "oneOf": [
                {
                    "type": "array",
                    "items": {
                        "allOf": [
                            {
                                "$ref": "#/definitions/CommandInputParameter"
                            },
                            {
                                "$ref": "#/definitions/ObjectWithId"
                            }
                        ]
                    }
                },
                {
                    "type": "object",
                    "additionalProperties": {
                        "anyOf": [
                            {
                                "$ref": "#/definitions/CommandInputParameter"
                            },
                            {
                                "$ref": "#/definitions/CommandInputType"
                            }
                        ]
                    }
                }
            ]
        },
        "CommandInputRecordSchema": {
            "type": "object",
            "properties": {
                "fields": {
                    "description": "Defines the fields of the record.",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/CommandInputType"
                    }
                },
                "type": {
                    "description": "Must be `record`",
                    "type": "string",
                    "enum": [
                        "record"
                    ]
                },
                "label": {
                    "description": "A short, human-readable label of this object.",
                    "type": "string"
                }
            },
            "required": [
                "type"
            ]
        },
        "CommandInputRecordField": {
            "allOf": [
                {
                    "$ref": "#/definitions/InputRecordField"
                },
                {
                    "type": "object",
                    "properties": {
                        "inputBinding": {
                            "$ref": "#/definitions/CommandLineBinding"
                        },
                        "type": {
                            "$ref": "#/definitions/CommandInputType"
                        }
                    }
                }
            ]
        },
        "CommandInputEnumSchema": {
            "allOf": [
                {
                    "$ref": "#/definitions/InputEnumSchema"
                },
                {
                    "type": "object",
                    "properties": {
                        "inputBinding": {
                            "$ref": "#/definitions/CommandLineBinding"
                        }
                    }
                }
            ]
        },
        "CommandInputArraySchema": {
            "allOf": [
                {
                    "$ref": "#/definitions/InputArraySchema"
                },
                {
                    "type": "object",
                    "properties": {
                        "items": {
                            "$ref": "#/definitions/CommandInputType"
                        },
                        "inputBinding": {
                            "$ref": "#/definitions/CommandLineBinding"
                        }
                    }
                }
            ]
        },
        "CommandOutputParameter": {
            "description": "An output parameter for a CommandLineTool.",
            "type": "object",
            "properties": {
                "outputBinding": {
                    "$ref": "#/definitions/CommandOutputBinding",
                    "description": "Describes how to handle the outputs of a process."
                },
                "type": {
                    "$ref": "#/definitions/CommandOutputType"
                },
                "secondaryFiles": {
                    "$ref": "#/definitions/StringOrArrayOfStrings"
                },
                "format": {
                    "$ref": "#/definitions/StringOrArrayOfStrings"
                },
                "streamable": {
                    "type": "boolean"
                },
                "doc": {
                    "$ref": "#/definitions/StringOrArrayOfStrings"
                },
                "label": {
                    "type": "string"
                }
            }
        },
        "CommandOutputParameters": {
            "oneOf": [
                {
                    "type": "array",
                    "items": {
                        "allOf": [
                            {
                                "$ref": "#/definitions/CommandOutputParameter"
                            },
                            {
                                "$ref": "#/definitions/ObjectWithId"
                            }
                        ]
                    }
                },
                {
                    "type": "object",
                    "additionalProperties": {
                        "anyOf": [
                            {
                                "$ref": "#/definitions/CommandOutputParameter"
                            },
                            {
                                "$ref": "#/definitions/CommandOutputType"
                            }
                        ]
                    }
                }
            ]
        },
        "CommandOutputRecordSchema": {
            "type": "object",
            "properties": {
                "fields": {
                    "description": "Defines the fields of the record.",
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/CommandOutputRecordField"
                    }
                },
                "type": {
                    "description": "Must be `record`",
                    "type": "string",
                    "enum": [
                        "record"
                    ]
                },
                "label": {
                    "description": "A short, human-readable label of this object.",
                    "type": "string"
                }
            },
            "required": [
                "type"
            ]
        },
        "CommandOutputRecordField": {
            "allOf": [
                {
                    "$ref": "#/definitions/OutputRecordField"
                },
                {
                    "type": "object",
                    "properties": {
                        "outputBinding": {
                            "$ref": "#/definitions/CommandOutputBinding"
                        },
                        "type": {
                            "$ref": "#/definitions/CommandOutputType"
                        }
                    }
                }
            ]
        },
        "CommandOutputBinding": {
            "type": "object",
            "properties": {
                "glob": {
                    "description": "Find files relative to the output directory, using POSIX glob(3)\n\npathname matching.  If an array is provided, find files that match any\n\npattern in the array.  If an expression is provided, the expression must\n\nreturn a string or an array of strings, which will then be evaluated as\n\none or more glob patterns.  Must only match and return files which\n\nactually exist.",
                    "$ref": "#/definitions/StringOrArrayOfStrings"
                },
                "loadContents": {
                    "description": "For each file matched in `glob`, read up to\n\nthe first 64 KiB of text from the file and place it in the `contents`\n\nfield of the file object for manipulation by `outputEval`.",
                    "type": "boolean"
                },
                "outputEval": {
                    "description": "Evaluate an expression to generate the output value.  If `glob` was\n\nspecified, the value of `self` must be an array containing file objects\n\nthat were matched.  If no files were matched, `self` must be a zero\n\nlength array; if a single file was matched, the value of `self` is an\n\narray of a single element.  Additionally, if `loadContents` is `true`,\n\nthe File objects must include up to the first 64 KiB of file contents\n\nin the `contents` field.",
                    "type": "string"
                }
            }
        },
        "CommandOutputEnumSchema": {
            "type": "object",
            "properties": {
                "outputBinding": {
                    "$ref": "#/definitions/CommandOutputBinding"
                }
            }
        },
        "CommandOutputArraySchema": {
            "type": "object",
            "properties": {
                "outputBinding": {
                    "$ref": "#/definitions/CommandOutputBinding"
                },
                "items": {
                    "$ref": "#/definitions/CommandOutputType"
                },
                "label": {
                    "type": "string"
                },
                "type": {
                    "type": "string",
                    "enum": [
                        "array"
                    ]
                }
            }
        },
        "CommandLineTool": {
            "description": "This defines the schema of the CWL Command Line Tool Description document.",
            "type": "object",
            "properties": {
                "class": {
                    "type": "string",
                    "enum": [
                        "CommandLineTool"
                    ]
                },
                "baseCommand": {
                    "description": "Specifies the program to execute.  If an array, the first element of\n\nthe array is the command to execute, and subsequent elements are\n\nmandatory command line arguments.  The elements in `baseCommand` must\n\nappear before any command line bindings from `inputBinding` or\n\n`arguments`.\n\n\n\nIf `baseCommand` is not provided or is an empty array, the first\n\nelement of the command line produced after processing `inputBinding` or\n\n`arguments` must be used as the program to execute.\n\n\n\nIf the program includes a path separator character it must\n\nbe an absolute path, otherwise it is an error.  If the program does not\n\ninclude a path separator, search the `$PATH` variable in the runtime\n\nenvironment of the workflow runner find the absolute path of the\n\nexecutable.",
                    "anyOf": [
                        {
                            "type": "string"
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    ]
                },
                "arguments": {
                    "description": "Command line bindings which are not directly associated with input parameters.",
                    "type": "array",
                    "items": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "string",
                                "enum": [
                                    "ExpressionPlaceholder"
                                ]
                            },
                            {
                                "$ref": "#/definitions/CommandLineBinding"
                            }
                        ]
                    }
                },
                "stdin": {
                    "description": "A path to a file whose contents must be piped into the command's\n\nstandard input stream.",
                    "type": "string"
                },
                "stderr": {
                    "description": "Capture the command's standard error stream to a file written to\n\nthe designated output directory.\n\n\n\nIf `stderr` is a string, it specifies the file name to use.\n\n\n\nIf `stderr` is an expression, the expression is evaluated and must\n\nreturn a string with the file name to use to capture stderr.  If the\n\nreturn value is not a string, or the resulting path contains illegal\n\ncharacters (such as the path separator `/`) it is an error.",
                    "type": "string"
                },
                "stdout": {
                    "description": "Capture the command's standard output stream to a file written to\n\nthe designated output directory.\n\n\n\nIf `stdout` is a string, it specifies the file name to use.\n\n\n\nIf `stdout` is an expression, the expression is evaluated and must\n\nreturn a string with the file name to use to capture stdout.  If the\n\nreturn value is not a string, or the resulting path contains illegal\n\ncharacters (such as the path separator `/`) it is an error.",
                    "type": "string"
                },
                "successCodes": {
                    "description": "Exit codes that indicate the process completed successfully.",
                    "type": "array",
                    "items": {
                        "type": "number"
                    }
                },
                "temporaryFailCodes": {
                    "description": "Exit codes that indicate the process failed due to a possibly\n\ntemporary condition, where executing the process with the same\n\nruntime environment and inputs may produce different results.",
                    "type": "array",
                    "items": {
                        "type": "number"
                    }
                },
                "permanentFailCodes": {
                    "description": "Exit codes that indicate the process failed due to a permanent logic error, where executing the process with the same runtime environment and same inputs is expected to always fail.",
                    "type": "array",
                    "items": {
                        "type": "number"
                    }
                },
                "inputs": {
                    "description": "Defines the input parameters of the process.  The process is ready to\n\nrun when all required input parameters are associated with concrete\n\nvalues.  Input parameters include a schema for each parameter which is\n\nused to validate the input object.  It may also be used to build a user\n\ninterface for constructing the input object.",
                    "$ref": "#/definitions/CommandInputParameters"
                },
                "outputs": {
                    "description": "Defines the parameters representing the output of the process.  May be\n\nused to generate and/or validate the output object.",
                    "$ref": "#/definitions/CommandOutputParameters"
                }
            },
            "required": [
                "class",
                "inputs",
                "outputs"
            ]
        },
        "ExpressionTool": {
            "description": "Execute an expression as a Workflow step.",
            "type": "object",
            "properties": {
                "class": {
                    "type": "string",
                    "enum": [
                        "ExpressionTool"
                    ]
                },
                "expression": {
                    "description": "The expression to execute.  The expression must return a JSON object which\n\nmatches the output parameters of the ExpressionTool.",
                    "type": "string"
                },
                "outputs": {
                    "description": "Defines the parameters representing the output of the process.  May be\n\nused to generate and/or validate the output object.",
                    "$ref": "#/definitions/ExpressionToolOutputParameters"
                },
                "inputs": {
                    "description": "Defines the input parameters of the process.  The process is ready to\n\nrun when all required input parameters are associated with concrete\n\nvalues.  Input parameters include a schema for each parameter which is\n\nused to validate the input object.  It may also be used to build a user\n\ninterface for constructing the input object.",
                    "$ref": "#/definitions/Inputs"
                }
            },
            "required": [
                "class",
                "expression",
                "outputs",
                "inputs"
            ]
        },
        "Workflow": {
            "description": "A workflow describes a set of **steps** and the **dependencies** between\n\nthose steps.  When a step produces output that will be consumed by a\n\nsecond step, the first step is a dependency of the second step.\n\n\n\nWhen there is a dependency, the workflow engine must execute the preceeding\n\nstep and wait for it to successfully produce output before executing the\n\ndependent step.  If two steps are defined in the workflow graph that\n\nare not directly or indirectly dependent, these steps are **independent**,\n\nand may execute in any order or execute concurrently.  A workflow is\n\ncomplete when all steps have been executed.\n\n\n\nDependencies between parameters are expressed using the `source` field on\n\n[workflow step input parameters](#WorkflowStepInput) and [workflow output\n\nparameters](#WorkflowOutputParameter).\n\n\n\nThe `source` field expresses the dependency of one parameter on another\n\nsuch that when a value is associated with the parameter specified by\n\n`source`, that value is propagated to the destination parameter.  When all\n\ndata links inbound to a given step are fufilled, the step is ready to\n\nexecute.\n\n\n\n## Workflow success and failure\n\n\n\nA completed step must result in one of `success`, `temporaryFailure` or\n\n`permanentFailure` states.  An implementation may choose to retry a step\n\nexecution which resulted in `temporaryFailure`.  An implementation may\n\nchoose to either continue running other steps of a workflow, or terminate\n\nimmediately upon `permanentFailure`.\n\n\n\n* If any step of a workflow execution results in `permanentFailure`, then\n\nthe workflow status is `permanentFailure`.\n\n\n\n* If one or more steps result in `temporaryFailure` and all other steps\n\ncomplete `success` or are not executed, then the workflow status is\n\n`temporaryFailure`.\n\n\n\n* If all workflow steps are executed and complete with `success`, then the\n\nworkflow status is `success`.\n\n\n\n# Extensions\n\n\n\n[ScatterFeatureRequirement](#ScatterFeatureRequirement) and\n\n[SubworkflowFeatureRequirement](#SubworkflowFeatureRequirement) are\n\navailable as standard [extensions](#Extensions_and_Metadata) to core\n\nworkflow semantics.",
            "type": "object",
            "properties": {
                "class": {
                    "type": "string",
                    "enum": [
                        "Workflow"
                    ]
                },
                "steps": {
                    "description": "The individual steps that make up the workflow.  Each step is executed when all of its\n\ninput data links are fufilled.  An implementation may choose to execute\n\nthe steps in a different order than listed and/or execute steps\n\nconcurrently, provided that dependencies between steps are met.",
                    "$ref": "#/definitions/WorkflowSteps"
                },
                "outputs": {
                    "description": "Defines the parameters representing the output of the process.  May be\n\nused to generate and/or validate the output object.",
                    "$ref": "#/definitions/WorkflowOutputParameters"
                },
                "inputs": {
                    "description": "Defines the input parameters of the process.  The process is ready to\n\nrun when all required input parameters are associated with concrete\n\nvalues.  Input parameters include a schema for each parameter which is\n\nused to validate the input object.  It may also be used to build a user\n\ninterface for constructing the input object.",
                    "$ref": "#/definitions/Inputs"
                }
            },
            "required": [
                "class",
                "steps",
                "outputs",
                "inputs"
            ]
        }
    }
}