Repository: common-workflow-language/cwl-utils

Issue:
Parser does not support cwltool extensions
Given the workflow below:
```cwl
#!/usr/bin/env cwl-runner

cwlVersion: v1.0
class: CommandLineTool
$namespaces:
  cwltool: "http://commonwl.org/cwltool#"

doc: |
  Trivial MPI test that prints the process IDs of each of the parallel
  processes. Requires Python (but you have cwltool running, right?)
  and an MPI implementation.

baseCommand: python
requirements:
  cwltool:MPIRequirement:
    processes: 2
arguments: [-c, 'import os; print(os.getpid())']
inputs: []
outputs:
  pids:
    type: stdout
```

`MPIRequirement` is part of the [cwltool extensions](https://github.com/common-workflow-language/cwltool/blob/6bb7b8913337eb07a532f7b372fde93ae447d3f3/cwltool/extensions.yml#L159). This workflow also works with both cwltool and toil-cwl-runner given the right flags, ex:
```
$ export PATH=$PATH:/home/heaucques/Documents/toil/src/toil/test/cwl/mock_mpi/ # where fake_mpi_run.py exists
$ cwltool --enable-dev --enable-ext --mpi-config-file /home/heaucques/Documents/toil/src/toil/test/cwl/mock_mpi/fake_mpi.yml file:///home/heaucques/Documents/toil/src/toil/test/cwl/mpi_simple.cwl
INFO /home/heaucques/Documents/toil/venv3.12/bin/cwltool 3.1.20240508115724
INFO [job mpi_simple.cwl] /tmp/1ez0it5c$ fake_mpi_run.py \
    --num \
    2 \
    --no-fail \
    python \
    -c \
    'import os; print(os.getpid())' > /tmp/1ez0it5c/c83195d490fa84f03f0cb9b142c6f385d736bd94
INFO [job mpi_simple.cwl] completed success
{
    "pids": {
        "location": "file:///home/heaucques/Documents/toil/c83195d490fa84f03f0cb9b142c6f385d736bd94",
        "basename": "c83195d490fa84f03f0cb9b142c6f385d736bd94",
        "class": "File",
        "checksum": "sha1$010210c4a6298629ae0653165e70c393bc831cad",
        "size": 12,
        "path": "/home/heaucques/Documents/toil/c83195d490fa84f03f0cb9b142c6f385d736bd94"
    }
}INFO Final process status is success
```
[And the toil equivalent](https://github.com/DataBiosphere/toil/blob/1b4af5442be30e6ac2e3b0b16035371fafe31fb1/src/toil/test/cwl/cwlTest.py#L369-L391)


However, running `cwl-docker-extract mpi_simple.cwl` crashes at parsing as by default, these extensions are disabled.
```
$ cwl-docker-extract file:///home/heaucques/Documents/toil/src/toil/test/cwl/mpi_simple.cwl
Traceback (most recent call last):
  File "/home/heaucques/Documents/toil/venv3.12/bin/cwl-docker-extract", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/heaucques/Documents/toil/venv3.12/lib/python3.12/site-packages/cwl_utils/docker_extract.py", line 139, in main
    run(arg_parser().parse_args(sys.argv[1:]))
  File "/home/heaucques/Documents/toil/venv3.12/lib/python3.12/site-packages/cwl_utils/docker_extract.py", line 55, in run
    top = cwl.load_document_by_uri(args.input)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/heaucques/Documents/toil/venv3.12/lib/python3.12/site-packages/cwl_utils/parser/__init__.py", line 183, in load_document_by_uri
    return load_document_by_string(doc, real_uri, loadingOptions, id_, load_all)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/heaucques/Documents/toil/venv3.12/lib/python3.12/site-packages/cwl_utils/parser/__init__.py", line 211, in load_document_by_string
    return load_document_by_yaml(result, uri, loadingOptions, id_, load_all)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/heaucques/Documents/toil/venv3.12/lib/python3.12/site-packages/cwl_utils/parser/__init__.py", line 227, in load_document_by_yaml
    result = cwl_v1_0.load_document_by_yaml(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/heaucques/Documents/toil/venv3.12/lib/python3.12/site-packages/cwl_utils/parser/cwl_v1_0.py", line 21054, in load_document_by_yaml
    result, metadata = _document_load(
                       ^^^^^^^^^^^^^^^
  File "/home/heaucques/Documents/toil/venv3.12/lib/python3.12/site-packages/cwl_utils/parser/cwl_v1_0.py", line 1038, in _document_load
    loader.load(doc, baseuri, loadingOptions, docRoot=baseuri),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/heaucques/Documents/toil/venv3.12/lib/python3.12/site-packages/cwl_utils/parser/cwl_v1_0.py", line 806, in load
    raise ValidationException("", None, errors, "*")
schema_salad.exceptions.ValidationException: src/toil/test/cwl/mpi_simple.cwl:3:1:   Object `mpi_simple.cwl` is not valid because:
src/toil/test/cwl/mpi_simple.cwl:14:1:   the `requirements` field is not valid because:
                                           Expected a <class 'NoneType'> but got list
```

`cwl-docker-extract` does not appear to support extensions:
```
$ cwl-docker-extract --help
usage: cwl-docker-extract [-h] [--dir DIR] [-s] [--container-engine CONTAINER_ENGINE] [--force-download] input

Save container images specified in a CWL document (Workflow or CommandLineTool). For CWL Workflows, all steps will also be searched (recursively).

positional arguments:
  input                 Input CWL document (CWL Workflow or CWL CommandLineTool)

options:
  -h, --help            show this help message and exit
  --dir DIR             Directory in which to save images
  -s, --singularity     Use singularity to pull the image
  --container-engine CONTAINER_ENGINE
                        Specify which command to use to run OCI containers. Defaults to 'docker' (or 'singularity' if --singularity/-s is passed).
  --force-download      Force pulling a newer container.
```

Is there a way to enable support for these extensions to allow the parser to pass for these cases?

Discussion:

Solution patch:
diff --git a/MANIFEST.in b/MANIFEST.in
index 5e22a597..4b76c329 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -21,6 +21,7 @@ include testdata/workflows/*.cwl
 include testdata/workflows/*.yaml
 include testdata/types/*.yml
 include testdata/checker_wf/*.cwl
+include testdata/extensions/*.cwl
 include cwl_utils/py.typed
 include docs/conf.py docs/Makefile docs/_static/favicon.ico docs/requirements.txt
 include docs/*.rst
diff --git a/Makefile b/Makefile
index 0a992b11..7723ba47 100644
--- a/Makefile
+++ b/Makefile
@@ -191,19 +191,19 @@ flake8: $(PYSOURCES)
 cwl_utils/parser/cwl_v1_0.py: FORCE
 	schema-salad-tool --codegen python \
 		--codegen-parser-info "org.w3id.cwl.v1_0" \
-		https://github.com/common-workflow-language/common-workflow-language/raw/codegen/v1.0/CommonWorkflowLanguage.yml \
+		https://github.com/common-workflow-language/common-workflow-language/raw/codegen/v1.0/extensions.yml \
 		> $@
 
 cwl_utils/parser/cwl_v1_1.py: FORCE
 	schema-salad-tool --codegen python \
 		--codegen-parser-info "org.w3id.cwl.v1_1" \
-		https://github.com/common-workflow-language/cwl-v1.1/raw/codegen/CommonWorkflowLanguage.yml \
+		https://github.com/common-workflow-language/cwl-v1.1/raw/codegen/extensions.yml \
 		> $@
 
 cwl_utils/parser/cwl_v1_2.py: FORCE
 	schema-salad-tool --codegen python \
 		--codegen-parser-info "org.w3id.cwl.v1_2" \
-		https://github.com/common-workflow-language/cwl-v1.2/raw/codegen/CommonWorkflowLanguage.yml \
+		https://github.com/common-workflow-language/cwl-v1.2/raw/codegen/extensions.yml \
 		> $@
 
 regen_parsers: cwl_utils/parser/cwl_v1_*.py
diff --git a/README.rst b/README.rst
index 685cb426..fab7cb30 100644
--- a/README.rst
+++ b/README.rst
@@ -152,13 +152,13 @@ Regenerate parsers
 To regenerate install the ``schema_salad`` package and run:
 
 ``cwl_utils/parser/cwl_v1_0.py`` was created via
-``schema-salad-tool --codegen python https://github.com/common-workflow-language/common-workflow-language/raw/codegen/v1.0/CommonWorkflowLanguage.yml --codegen-parser-info "org.w3id.cwl.v1_0" > cwl_utils/parser/cwl_v1_0.py``
+``schema-salad-tool --codegen python https://github.com/common-workflow-language/common-workflow-language/raw/codegen/v1.0/extensions.yml --codegen-parser-info "org.w3id.cwl.v1_0" > cwl_utils/parser/cwl_v1_0.py``
 
 ``cwl_utils/parser/cwl_v1_1.py`` was created via
-``schema-salad-tool --codegen python https://github.com/common-workflow-language/cwl-v1.1/raw/codegen/CommonWorkflowLanguage.yml --codegen-parser-info "org.w3id.cwl.v1_1" > cwl_utils/parser/cwl_v1_1.py``
+``schema-salad-tool --codegen python https://github.com/common-workflow-language/cwl-v1.1/raw/codegen/extensions.yml --codegen-parser-info "org.w3id.cwl.v1_1" > cwl_utils/parser/cwl_v1_1.py``
 
 ``cwl_utils/parser/cwl_v1_2.py`` was created via
-``schema-salad-tool --codegen python https://github.com/common-workflow-language/cwl-v1.2/raw/1.2.1_proposed/CommonWorkflowLanguage.yml --codegen-parser-info "org.w3id.cwl.v1_2" > cwl_utils/parser/cwl_v1_2.py``
+``schema-salad-tool --codegen python https://github.com/common-workflow-language/cwl-v1.2/raw/codegen/extensions.yml --codegen-parser-info "org.w3id.cwl.v1_2" > cwl_utils/parser/cwl_v1_2.py``
 
 Release
 ~~~~~~~
diff --git a/cwl_utils/parser/cwl_v1_0.py b/cwl_utils/parser/cwl_v1_0.py
index 366820ec..60c36570 100644
--- a/cwl_utils/parser/cwl_v1_0.py
+++ b/cwl_utils/parser/cwl_v1_0.py
@@ -1162,6 +1162,8 @@ class RecordField(Documented):
     A field of a record.
     """
 
+    class_uri = "https://w3id.org/cwl/salad#RecordField"
+
     def __init__(
         self,
         name: Any,
@@ -1428,6 +1430,8 @@ def save(
 
 
 class RecordSchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#RecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -1632,6 +1636,8 @@ class EnumSchema(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/salad#EnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -1898,6 +1904,8 @@ def save(
 
 
 class ArraySchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#ArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -2097,6 +2105,8 @@ def save(
 
 
 class MapSchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#MapSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -2296,6 +2306,8 @@ def save(
 
 
 class UnionSchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#UnionSchema"
+
     def __init__(
         self,
         names: Any,
@@ -2495,6 +2507,8 @@ def save(
 
 
 class CWLArraySchema(ArraySchema):
+    class_uri = "https://w3id.org/cwl/cwl#CWLArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -2694,6 +2708,8 @@ def save(
 
 
 class CWLRecordField(RecordField):
+    class_uri = "https://w3id.org/cwl/cwl#CWLRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -2960,6 +2976,8 @@ def save(
 
 
 class CWLRecordSchema(RecordSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CWLRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -3229,6 +3247,8 @@ class File(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#File"
+
     def __init__(
         self,
         location: Optional[Any] = None,
@@ -3316,12 +3336,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "File":
-            raise ValidationException("tried `File` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_File_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         location = None
         if "location" in _doc:
             try:
@@ -3891,8 +3920,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "File"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.location is not None:
             u = save_relative_uri(self.location, base_url, False, None, relative_uris)
             r["location"] = u
@@ -4012,6 +4042,8 @@ class Directory(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#Directory"
+
     def __init__(
         self,
         location: Optional[Any] = None,
@@ -4065,12 +4097,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "Directory":
-            raise ValidationException("tried `Directory` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_Directory_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         location = None
         if "location" in _doc:
             try:
@@ -4304,8 +4345,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "Directory"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.location is not None:
             u = save_relative_uri(self.location, base_url, False, None, relative_uris)
             r["location"] = u
@@ -4362,6 +4404,8 @@ class OutputSchema(SchemaBase):
 
 
 class InputRecordField(CWLRecordField):
+    class_uri = "https://w3id.org/cwl/cwl#InputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -4741,6 +4785,8 @@ def save(
 
 
 class InputRecordSchema(CWLRecordSchema, InputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#InputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -5062,6 +5108,8 @@ def save(
 
 
 class InputEnumSchema(EnumSchema, InputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#InputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -5443,6 +5491,8 @@ def save(
 
 
 class InputArraySchema(CWLArraySchema, InputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#InputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -5758,6 +5808,8 @@ def save(
 
 
 class OutputRecordField(CWLRecordField):
+    class_uri = "https://w3id.org/cwl/cwl#OutputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -6082,6 +6134,8 @@ def save(
 
 
 class OutputRecordSchema(CWLRecordSchema, OutputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#OutputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -6339,6 +6393,8 @@ def save(
 
 
 class OutputEnumSchema(EnumSchema, OutputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#OutputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -6720,6 +6776,8 @@ def save(
 
 
 class OutputArraySchema(CWLArraySchema, OutputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#OutputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -7035,6 +7093,8 @@ def save(
 
 
 class InputParameter(Parameter):
+    class_uri = "https://w3id.org/cwl/cwl#InputParameter"
+
     def __init__(
         self,
         id: Any,
@@ -7662,6 +7722,8 @@ def save(
 
 
 class OutputParameter(Parameter):
+    class_uri = "https://w3id.org/cwl/cwl#OutputParameter"
+
     def __init__(
         self,
         id: Any,
@@ -8208,6 +8270,8 @@ class InlineJavascriptRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#InlineJavascriptRequirement"
+
     def __init__(
         self,
         expressionLib: Optional[Any] = None,
@@ -8250,12 +8314,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "InlineJavascriptRequirement":
-            raise ValidationException("tried `InlineJavascriptRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_InlineJavascriptRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         expressionLib = None
         if "expressionLib" in _doc:
             try:
@@ -8345,8 +8418,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "InlineJavascriptRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.expressionLib is not None:
             r["expressionLib"] = save(
                 self.expressionLib,
@@ -8378,6 +8452,8 @@ class SchemaDefRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#SchemaDefRequirement"
+
     def __init__(
         self,
         types: Any,
@@ -8417,12 +8493,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "SchemaDefRequirement":
-            raise ValidationException("tried `SchemaDefRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_SchemaDefRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("types") is None:
                 raise ValidationException("missing required field `types`", None, [])
@@ -8513,8 +8598,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "SchemaDefRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.types is not None:
             r["types"] = save(
                 self.types, top=False, base_url=base_url, relative_uris=relative_uris
@@ -8539,6 +8625,8 @@ class EnvironmentDef(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#EnvironmentDef"
+
     def __init__(
         self,
         envName: Any,
@@ -8780,6 +8868,8 @@ class CommandLineBinding(InputBinding):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandLineBinding"
+
     def __init__(
         self,
         loadContents: Optional[Any] = None,
@@ -9302,6 +9392,8 @@ class CommandOutputBinding(OutputBinding):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputBinding"
+
     def __init__(
         self,
         glob: Optional[Any] = None,
@@ -9564,6 +9656,8 @@ def save(
 
 
 class CommandInputRecordField(InputRecordField):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -9943,6 +10037,8 @@ def save(
 
 
 class CommandInputRecordSchema(InputRecordSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -10264,6 +10360,8 @@ def save(
 
 
 class CommandInputEnumSchema(InputEnumSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -10645,6 +10743,8 @@ def save(
 
 
 class CommandInputArraySchema(InputArraySchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -10960,6 +11060,8 @@ def save(
 
 
 class CommandOutputRecordField(OutputRecordField):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -11284,6 +11386,8 @@ def save(
 
 
 class CommandOutputRecordSchema(OutputRecordSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -11605,6 +11709,8 @@ def save(
 
 
 class CommandOutputEnumSchema(OutputEnumSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -11986,6 +12092,8 @@ def save(
 
 
 class CommandOutputArraySchema(OutputArraySchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -12305,6 +12413,8 @@ class CommandInputParameter(InputParameter):
     An input parameter for a CommandLineTool.
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputParameter"
+
     def __init__(
         self,
         id: Any,
@@ -12936,6 +13046,8 @@ class CommandOutputParameter(OutputParameter):
     An output parameter for a CommandLineTool.
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputParameter"
+
     def __init__(
         self,
         id: Any,
@@ -13511,6 +13623,8 @@ class CommandLineTool(Process):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandLineTool"
+
     def __init__(
         self,
         inputs: Any,
@@ -13618,12 +13732,6 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
-
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "CommandLineTool":
-            raise ValidationException("tried `CommandLineTool` but")
-
         id = None
         if "id" in _doc:
             try:
@@ -13680,6 +13788,21 @@ def fromDoc(
                 id = "_:" + str(_uuid__.uuid4())
         if not __original_id_is_none:
             baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_CommandLineTool_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("inputs") is None:
                 raise ValidationException("missing required field `inputs`", None, [])
@@ -13781,7 +13904,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -13828,7 +13951,7 @@ def fromDoc(
             try:
                 hints = load_field(
                     _doc.get("hints"),
-                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("hints")
@@ -14445,11 +14568,12 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "CommandLineTool"
         if self.id is not None:
             u = save_relative_uri(self.id, base_url, True, None, relative_uris)
             r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
         if self.inputs is not None:
             r["inputs"] = save(
                 self.inputs, top=False, base_url=self.id, relative_uris=relative_uris
@@ -14594,6 +14718,8 @@ class DockerRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#DockerRequirement"
+
     def __init__(
         self,
         dockerPull: Optional[Any] = None,
@@ -14661,12 +14787,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "DockerRequirement":
-            raise ValidationException("tried `DockerRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_DockerRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         dockerPull = None
         if "dockerPull" in _doc:
             try:
@@ -14996,8 +15131,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "DockerRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.dockerPull is not None:
             r["dockerPull"] = save(
                 self.dockerPull,
@@ -15069,6 +15205,8 @@ class SoftwareRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#SoftwareRequirement"
+
     def __init__(
         self,
         packages: Any,
@@ -15108,12 +15246,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "SoftwareRequirement":
-            raise ValidationException("tried `SoftwareRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_SoftwareRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("packages") is None:
                 raise ValidationException("missing required field `packages`", None, [])
@@ -15204,8 +15351,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "SoftwareRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.packages is not None:
             r["packages"] = save(
                 self.packages, top=False, base_url=base_url, relative_uris=relative_uris
@@ -15223,6 +15371,8 @@ def save(
 
 
 class SoftwarePackage(Saveable):
+    class_uri = "https://w3id.org/cwl/cwl#SoftwarePackage"
+
     def __init__(
         self,
         package: Any,
@@ -15487,6 +15637,8 @@ class Dirent(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#Dirent"
+
     def __init__(
         self,
         entry: Any,
@@ -15751,6 +15903,8 @@ class InitialWorkDirRequirement(ProcessRequirement):
     Define a list of files and subdirectories that must be created by the workflow platform in the designated output directory prior to executing the command line tool.
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#InitialWorkDirRequirement"
+
     def __init__(
         self,
         listing: Any,
@@ -15790,12 +15944,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "InitialWorkDirRequirement":
-            raise ValidationException("tried `InitialWorkDirRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_InitialWorkDirRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("listing") is None:
                 raise ValidationException("missing required field `listing`", None, [])
@@ -15886,8 +16049,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "InitialWorkDirRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.listing is not None:
             r["listing"] = save(
                 self.listing, top=False, base_url=base_url, relative_uris=relative_uris
@@ -15911,6 +16075,8 @@ class EnvVarRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#EnvVarRequirement"
+
     def __init__(
         self,
         envDef: Any,
@@ -15950,12 +16116,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "EnvVarRequirement":
-            raise ValidationException("tried `EnvVarRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_EnvVarRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("envDef") is None:
                 raise ValidationException("missing required field `envDef`", None, [])
@@ -16046,8 +16221,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "EnvVarRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.envDef is not None:
             r["envDef"] = save(
                 self.envDef, top=False, base_url=base_url, relative_uris=relative_uris
@@ -16076,6 +16252,8 @@ class ShellCommandRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ShellCommandRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -16113,12 +16291,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ShellCommandRequirement":
-            raise ValidationException("tried `ShellCommandRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ShellCommandRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -16158,8 +16345,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ShellCommandRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -16197,6 +16385,8 @@ class ResourceRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ResourceRequirement"
+
     def __init__(
         self,
         coresMin: Optional[Any] = None,
@@ -16272,12 +16462,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ResourceRequirement":
-            raise ValidationException("tried `ResourceRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ResourceRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         coresMin = None
         if "coresMin" in _doc:
             try:
@@ -16703,8 +16902,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ResourceRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.coresMin is not None:
             r["coresMin"] = save(
                 self.coresMin, top=False, base_url=base_url, relative_uris=relative_uris
@@ -16774,6 +16974,8 @@ def save(
 
 
 class ExpressionToolOutputParameter(OutputParameter):
+    class_uri = "https://w3id.org/cwl/cwl#ExpressionToolOutputParameter"
+
     def __init__(
         self,
         id: Any,
@@ -17349,6 +17551,8 @@ class ExpressionTool(Process):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ExpressionTool"
+
     def __init__(
         self,
         inputs: Any,
@@ -17428,12 +17632,6 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
-
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ExpressionTool":
-            raise ValidationException("tried `ExpressionTool` but")
-
         id = None
         if "id" in _doc:
             try:
@@ -17490,6 +17688,21 @@ def fromDoc(
                 id = "_:" + str(_uuid__.uuid4())
         if not __original_id_is_none:
             baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ExpressionTool_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("inputs") is None:
                 raise ValidationException("missing required field `inputs`", None, [])
@@ -17591,7 +17804,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -17638,7 +17851,7 @@ def fromDoc(
             try:
                 hints = load_field(
                     _doc.get("hints"),
-                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("hints")
@@ -17920,11 +18133,12 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ExpressionTool"
         if self.id is not None:
             u = save_relative_uri(self.id, base_url, True, None, relative_uris)
             r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
         if self.inputs is not None:
             r["inputs"] = save(
                 self.inputs, top=False, base_url=self.id, relative_uris=relative_uris
@@ -17995,6 +18209,8 @@ class WorkflowOutputParameter(OutputParameter):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowOutputParameter"
+
     def __init__(
         self,
         id: Any,
@@ -18725,6 +18941,8 @@ class WorkflowStepInput(Sink):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowStepInput"
+
     def __init__(
         self,
         id: Any,
@@ -19109,6 +19327,8 @@ class WorkflowStepOutput(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowStepOutput"
+
     def __init__(
         self,
         id: Any,
@@ -19319,6 +19539,8 @@ class WorkflowStep(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowStep"
+
     def __init__(
         self,
         id: Any,
@@ -19556,7 +19778,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -19745,7 +19967,7 @@ def fromDoc(
 
             run = load_field(
                 _doc.get("run"),
-                uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_False_False_None_None,
+                uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_False_False_None_None,
                 baseuri,
                 loadingOptions,
                 lc=_doc.get("run")
@@ -20048,6 +20270,8 @@ class Workflow(Process):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#Workflow"
+
     def __init__(
         self,
         inputs: Any,
@@ -20127,12 +20351,6 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
-
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "Workflow":
-            raise ValidationException("tried `Workflow` but")
-
         id = None
         if "id" in _doc:
             try:
@@ -20189,6 +20407,21 @@ def fromDoc(
                 id = "_:" + str(_uuid__.uuid4())
         if not __original_id_is_none:
             baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_Workflow_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("inputs") is None:
                 raise ValidationException("missing required field `inputs`", None, [])
@@ -20290,7 +20523,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -20337,7 +20570,7 @@ def fromDoc(
             try:
                 hints = load_field(
                     _doc.get("hints"),
-                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("hints")
@@ -20619,11 +20852,12 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "Workflow"
         if self.id is not None:
             u = save_relative_uri(self.id, base_url, True, None, relative_uris)
             r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
         if self.inputs is not None:
             r["inputs"] = save(
                 self.inputs, top=False, base_url=self.id, relative_uris=relative_uris
@@ -20690,6 +20924,8 @@ class SubworkflowFeatureRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#SubworkflowFeatureRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -20727,12 +20963,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "SubworkflowFeatureRequirement":
-            raise ValidationException("tried `SubworkflowFeatureRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_SubworkflowFeatureRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -20772,8 +21017,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "SubworkflowFeatureRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -20793,6 +21039,8 @@ class ScatterFeatureRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ScatterFeatureRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -20830,12 +21078,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ScatterFeatureRequirement":
-            raise ValidationException("tried `ScatterFeatureRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ScatterFeatureRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -20875,8 +21132,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ScatterFeatureRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -20896,6 +21154,8 @@ class MultipleInputFeatureRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#MultipleInputFeatureRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -20933,12 +21193,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "MultipleInputFeatureRequirement":
-            raise ValidationException("tried `MultipleInputFeatureRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_MultipleInputFeatureRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -20978,8 +21247,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "MultipleInputFeatureRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -20999,6 +21269,8 @@ class StepInputExpressionRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#StepInputExpressionRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -21036,12 +21308,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "StepInputExpressionRequirement":
-            raise ValidationException("tried `StepInputExpressionRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_StepInputExpressionRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -21081,8 +21362,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "StepInputExpressionRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -21095,85 +21377,2515 @@ def save(
     attrs = frozenset(["class"])
 
 
-_vocab = {
-    "Any": "https://w3id.org/cwl/salad#Any",
-    "ArraySchema": "https://w3id.org/cwl/salad#ArraySchema",
-    "CWLArraySchema": "https://w3id.org/cwl/cwl#CWLArraySchema",
-    "CWLInputFile": "https://w3id.org/cwl/cwl#CWLInputFile",
-    "CWLObjectType": "https://w3id.org/cwl/cwl#CWLObjectType",
-    "CWLRecordField": "https://w3id.org/cwl/cwl#CWLRecordField",
-    "CWLRecordSchema": "https://w3id.org/cwl/cwl#CWLRecordSchema",
-    "CWLType": "https://w3id.org/cwl/cwl#CWLType",
-    "CWLVersion": "https://w3id.org/cwl/cwl#CWLVersion",
-    "CommandInputArraySchema": "https://w3id.org/cwl/cwl#CommandInputArraySchema",
-    "CommandInputEnumSchema": "https://w3id.org/cwl/cwl#CommandInputEnumSchema",
-    "CommandInputParameter": "https://w3id.org/cwl/cwl#CommandInputParameter",
-    "CommandInputRecordField": "https://w3id.org/cwl/cwl#CommandInputRecordField",
-    "CommandInputRecordSchema": "https://w3id.org/cwl/cwl#CommandInputRecordSchema",
-    "CommandLineBinding": "https://w3id.org/cwl/cwl#CommandLineBinding",
-    "CommandLineTool": "https://w3id.org/cwl/cwl#CommandLineTool",
-    "CommandOutputArraySchema": "https://w3id.org/cwl/cwl#CommandOutputArraySchema",
-    "CommandOutputBinding": "https://w3id.org/cwl/cwl#CommandOutputBinding",
-    "CommandOutputEnumSchema": "https://w3id.org/cwl/cwl#CommandOutputEnumSchema",
-    "CommandOutputParameter": "https://w3id.org/cwl/cwl#CommandOutputParameter",
-    "CommandOutputRecordField": "https://w3id.org/cwl/cwl#CommandOutputRecordField",
-    "CommandOutputRecordSchema": "https://w3id.org/cwl/cwl#CommandOutputRecordSchema",
-    "Directory": "https://w3id.org/cwl/cwl#Directory",
-    "Dirent": "https://w3id.org/cwl/cwl#Dirent",
-    "DockerRequirement": "https://w3id.org/cwl/cwl#DockerRequirement",
-    "Documented": "https://w3id.org/cwl/salad#Documented",
-    "EnumSchema": "https://w3id.org/cwl/salad#EnumSchema",
-    "EnvVarRequirement": "https://w3id.org/cwl/cwl#EnvVarRequirement",
-    "EnvironmentDef": "https://w3id.org/cwl/cwl#EnvironmentDef",
-    "Expression": "https://w3id.org/cwl/cwl#Expression",
-    "ExpressionPlaceholder": "https://w3id.org/cwl/cwl#ExpressionPlaceholder",
-    "ExpressionTool": "https://w3id.org/cwl/cwl#ExpressionTool",
-    "ExpressionToolOutputParameter": "https://w3id.org/cwl/cwl#ExpressionToolOutputParameter",
-    "File": "https://w3id.org/cwl/cwl#File",
-    "InitialWorkDirRequirement": "https://w3id.org/cwl/cwl#InitialWorkDirRequirement",
-    "InlineJavascriptRequirement": "https://w3id.org/cwl/cwl#InlineJavascriptRequirement",
-    "InputArraySchema": "https://w3id.org/cwl/cwl#InputArraySchema",
-    "InputBinding": "https://w3id.org/cwl/cwl#InputBinding",
-    "InputEnumSchema": "https://w3id.org/cwl/cwl#InputEnumSchema",
-    "InputParameter": "https://w3id.org/cwl/cwl#InputParameter",
-    "InputRecordField": "https://w3id.org/cwl/cwl#InputRecordField",
-    "InputRecordSchema": "https://w3id.org/cwl/cwl#InputRecordSchema",
-    "InputSchema": "https://w3id.org/cwl/cwl#InputSchema",
-    "LinkMergeMethod": "https://w3id.org/cwl/cwl#LinkMergeMethod",
-    "MapSchema": "https://w3id.org/cwl/salad#MapSchema",
-    "MultipleInputFeatureRequirement": "https://w3id.org/cwl/cwl#MultipleInputFeatureRequirement",
-    "OutputArraySchema": "https://w3id.org/cwl/cwl#OutputArraySchema",
-    "OutputBinding": "https://w3id.org/cwl/cwl#OutputBinding",
-    "OutputEnumSchema": "https://w3id.org/cwl/cwl#OutputEnumSchema",
-    "OutputParameter": "https://w3id.org/cwl/cwl#OutputParameter",
-    "OutputRecordField": "https://w3id.org/cwl/cwl#OutputRecordField",
-    "OutputRecordSchema": "https://w3id.org/cwl/cwl#OutputRecordSchema",
-    "OutputSchema": "https://w3id.org/cwl/cwl#OutputSchema",
-    "Parameter": "https://w3id.org/cwl/cwl#Parameter",
-    "PrimitiveType": "https://w3id.org/cwl/salad#PrimitiveType",
-    "Process": "https://w3id.org/cwl/cwl#Process",
-    "ProcessRequirement": "https://w3id.org/cwl/cwl#ProcessRequirement",
-    "RecordField": "https://w3id.org/cwl/salad#RecordField",
-    "RecordSchema": "https://w3id.org/cwl/salad#RecordSchema",
-    "ResourceRequirement": "https://w3id.org/cwl/cwl#ResourceRequirement",
-    "ScatterFeatureRequirement": "https://w3id.org/cwl/cwl#ScatterFeatureRequirement",
-    "ScatterMethod": "https://w3id.org/cwl/cwl#ScatterMethod",
-    "SchemaBase": "https://w3id.org/cwl/cwl#SchemaBase",
-    "SchemaDefRequirement": "https://w3id.org/cwl/cwl#SchemaDefRequirement",
-    "ShellCommandRequirement": "https://w3id.org/cwl/cwl#ShellCommandRequirement",
-    "Sink": "https://w3id.org/cwl/cwl#Sink",
-    "SoftwarePackage": "https://w3id.org/cwl/cwl#SoftwarePackage",
-    "SoftwareRequirement": "https://w3id.org/cwl/cwl#SoftwareRequirement",
-    "StepInputExpressionRequirement": "https://w3id.org/cwl/cwl#StepInputExpressionRequirement",
-    "SubworkflowFeatureRequirement": "https://w3id.org/cwl/cwl#SubworkflowFeatureRequirement",
-    "UnionSchema": "https://w3id.org/cwl/salad#UnionSchema",
-    "Workflow": "https://w3id.org/cwl/cwl#Workflow",
-    "WorkflowOutputParameter": "https://w3id.org/cwl/cwl#WorkflowOutputParameter",
-    "WorkflowStep": "https://w3id.org/cwl/cwl#WorkflowStep",
+class LoadListingRequirement(ProcessRequirement):
+    class_uri = "http://commonwl.org/cwltool#LoadListingRequirement"
+
+    def __init__(
+        self,
+        loadListing: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "LoadListingRequirement"
+        self.loadListing = loadListing
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, LoadListingRequirement):
+            return bool(
+                self.class_ == other.class_ and self.loadListing == other.loadListing
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.loadListing))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "LoadListingRequirement":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("loadListing") is None:
+                raise ValidationException("missing required field `loadListing`", None, [])
+
+            loadListing = load_field(
+                _doc.get("loadListing"),
+                union_of_LoadListingEnumLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("loadListing")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `loadListing`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("loadListing")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `loadListing` field is not valid because:",
+                            SourceLine(_doc, "loadListing", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `loadListing` field is not valid because:",
+                            SourceLine(_doc, "loadListing", str),
+                            [e],
+                            detailed_message=f"the `loadListing` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `loadListing`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            loadListing=loadListing,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.loadListing is not None:
+            r["loadListing"] = save(
+                self.loadListing,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "loadListing"])
+
+
+class InplaceUpdateRequirement(ProcessRequirement):
+    class_uri = "http://commonwl.org/cwltool#InplaceUpdateRequirement"
+
+    def __init__(
+        self,
+        inplaceUpdate: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "InplaceUpdateRequirement"
+        self.inplaceUpdate = inplaceUpdate
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, InplaceUpdateRequirement):
+            return bool(
+                self.class_ == other.class_
+                and self.inplaceUpdate == other.inplaceUpdate
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.inplaceUpdate))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "InplaceUpdateRequirement":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("inplaceUpdate") is None:
+                raise ValidationException("missing required field `inplaceUpdate`", None, [])
+
+            inplaceUpdate = load_field(
+                _doc.get("inplaceUpdate"),
+                booltype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("inplaceUpdate")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `inplaceUpdate`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("inplaceUpdate")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `inplaceUpdate` field is not valid because:",
+                            SourceLine(_doc, "inplaceUpdate", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `inplaceUpdate` field is not valid because:",
+                            SourceLine(_doc, "inplaceUpdate", str),
+                            [e],
+                            detailed_message=f"the `inplaceUpdate` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `inplaceUpdate`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            inplaceUpdate=inplaceUpdate,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.inplaceUpdate is not None:
+            r["inplaceUpdate"] = save(
+                self.inplaceUpdate,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "inplaceUpdate"])
+
+
+class Secrets(ProcessRequirement):
+    class_uri = "http://commonwl.org/cwltool#Secrets"
+
+    def __init__(
+        self,
+        secrets: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "Secrets"
+        self.secrets = secrets
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, Secrets):
+            return bool(self.class_ == other.class_ and self.secrets == other.secrets)
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.secrets))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "Secrets":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("secrets") is None:
+                raise ValidationException("missing required field `secrets`", None, [])
+
+            secrets = load_field(
+                _doc.get("secrets"),
+                uri_array_of_strtype_False_False_0_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("secrets")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `secrets`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("secrets")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `secrets` field is not valid because:",
+                            SourceLine(_doc, "secrets", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `secrets` field is not valid because:",
+                            SourceLine(_doc, "secrets", str),
+                            [e],
+                            detailed_message=f"the `secrets` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `secrets`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            secrets=secrets,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.secrets is not None:
+            u = save_relative_uri(self.secrets, base_url, False, 0, relative_uris)
+            r["secrets"] = u
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "secrets"])
+
+
+class TimeLimit(ProcessRequirement):
+    """
+    Set an upper limit on the execution time of a CommandLineTool or
+    ExpressionTool.  A tool execution which exceeds the time limit may
+    be preemptively terminated and considered failed.  May also be
+    used by batch systems to make scheduling decisions.
+
+    """
+
+    class_uri = "http://commonwl.org/cwltool#TimeLimit"
+
+    def __init__(
+        self,
+        timelimit: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "TimeLimit"
+        self.timelimit = timelimit
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, TimeLimit):
+            return bool(
+                self.class_ == other.class_ and self.timelimit == other.timelimit
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.timelimit))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "TimeLimit":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("timelimit") is None:
+                raise ValidationException("missing required field `timelimit`", None, [])
+
+            timelimit = load_field(
+                _doc.get("timelimit"),
+                union_of_inttype_or_strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("timelimit")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `timelimit`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("timelimit")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `timelimit` field is not valid because:",
+                            SourceLine(_doc, "timelimit", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `timelimit` field is not valid because:",
+                            SourceLine(_doc, "timelimit", str),
+                            [e],
+                            detailed_message=f"the `timelimit` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `timelimit`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            timelimit=timelimit,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.timelimit is not None:
+            r["timelimit"] = save(
+                self.timelimit,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "timelimit"])
+
+
+class WorkReuse(ProcessRequirement):
+    """
+    For implementations that support reusing output from past work (on
+    the assumption that same code and same input produce same
+    results), control whether to enable or disable the reuse behavior
+    for a particular tool or step (to accommodate situations where that
+    assumption is incorrect).  A reused step is not executed but
+    instead returns the same output as the original execution.
+
+    If `enableReuse` is not specified, correct tools should assume it
+    is enabled by default.
+
+    """
+
+    class_uri = "http://commonwl.org/cwltool#WorkReuse"
+
+    def __init__(
+        self,
+        enableReuse: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "WorkReuse"
+        self.enableReuse = enableReuse
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, WorkReuse):
+            return bool(
+                self.class_ == other.class_ and self.enableReuse == other.enableReuse
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.enableReuse))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "WorkReuse":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("enableReuse") is None:
+                raise ValidationException("missing required field `enableReuse`", None, [])
+
+            enableReuse = load_field(
+                _doc.get("enableReuse"),
+                union_of_booltype_or_strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("enableReuse")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `enableReuse`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("enableReuse")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `enableReuse` field is not valid because:",
+                            SourceLine(_doc, "enableReuse", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `enableReuse` field is not valid because:",
+                            SourceLine(_doc, "enableReuse", str),
+                            [e],
+                            detailed_message=f"the `enableReuse` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `enableReuse`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            enableReuse=enableReuse,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.enableReuse is not None:
+            r["enableReuse"] = save(
+                self.enableReuse,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "enableReuse"])
+
+
+class NetworkAccess(ProcessRequirement):
+    """
+    Indicate whether a process requires outgoing IPv4/IPv6 network
+    access.  Choice of IPv4 or IPv6 is implementation and site
+    specific, correct tools must support both.
+
+    If `networkAccess` is false or not specified, tools must not
+    assume network access, except for localhost (the loopback device).
+
+    If `networkAccess` is true, the tool must be able to make outgoing
+    connections to network resources.  Resources may be on a private
+    subnet or the public Internet.  However, implementations and sites
+    may apply their own security policies to restrict what is
+    accessible by the tool.
+
+    Enabling network access does not imply a publicly routable IP
+    address or the ability to accept inbound connections.
+
+    """
+
+    class_uri = "http://commonwl.org/cwltool#NetworkAccess"
+
+    def __init__(
+        self,
+        networkAccess: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "NetworkAccess"
+        self.networkAccess = networkAccess
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, NetworkAccess):
+            return bool(
+                self.class_ == other.class_
+                and self.networkAccess == other.networkAccess
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.networkAccess))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "NetworkAccess":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("networkAccess") is None:
+                raise ValidationException("missing required field `networkAccess`", None, [])
+
+            networkAccess = load_field(
+                _doc.get("networkAccess"),
+                union_of_booltype_or_strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("networkAccess")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `networkAccess`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("networkAccess")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `networkAccess` field is not valid because:",
+                            SourceLine(_doc, "networkAccess", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `networkAccess` field is not valid because:",
+                            SourceLine(_doc, "networkAccess", str),
+                            [e],
+                            detailed_message=f"the `networkAccess` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `networkAccess`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            networkAccess=networkAccess,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.networkAccess is not None:
+            r["networkAccess"] = save(
+                self.networkAccess,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "networkAccess"])
+
+
+class ProcessGenerator(Process):
+    class_uri = "http://commonwl.org/cwltool#ProcessGenerator"
+
+    def __init__(
+        self,
+        inputs: Any,
+        outputs: Any,
+        run: Any,
+        id: Optional[Any] = None,
+        requirements: Optional[Any] = None,
+        hints: Optional[Any] = None,
+        label: Optional[Any] = None,
+        doc: Optional[Any] = None,
+        cwlVersion: Optional[Any] = None,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.id = id
+        self.inputs = inputs
+        self.outputs = outputs
+        self.requirements = requirements
+        self.hints = hints
+        self.label = label
+        self.doc = doc
+        self.cwlVersion = cwlVersion
+        self.class_ = "ProcessGenerator"
+        self.run = run
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, ProcessGenerator):
+            return bool(
+                self.id == other.id
+                and self.inputs == other.inputs
+                and self.outputs == other.outputs
+                and self.requirements == other.requirements
+                and self.hints == other.hints
+                and self.label == other.label
+                and self.doc == other.doc
+                and self.cwlVersion == other.cwlVersion
+                and self.class_ == other.class_
+                and self.run == other.run
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash(
+            (
+                self.id,
+                self.inputs,
+                self.outputs,
+                self.requirements,
+                self.hints,
+                self.label,
+                self.doc,
+                self.cwlVersion,
+                self.class_,
+                self.run,
+            )
+        )
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "ProcessGenerator":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        id = None
+        if "id" in _doc:
+            try:
+                id = load_field(
+                    _doc.get("id"),
+                    uri_union_of_None_type_or_strtype_True_False_None_None,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("id")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `id`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("id")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `id` field is not valid because:",
+                                SourceLine(_doc, "id", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `id` field is not valid because:",
+                                SourceLine(_doc, "id", str),
+                                [e],
+                                detailed_message=f"the `id` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+
+        __original_id_is_none = id is None
+        if id is None:
+            if docRoot is not None:
+                id = docRoot
+            else:
+                id = "_:" + str(_uuid__.uuid4())
+        if not __original_id_is_none:
+            baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("inputs") is None:
+                raise ValidationException("missing required field `inputs`", None, [])
+
+            inputs = load_field(
+                _doc.get("inputs"),
+                idmap_inputs_array_of_InputParameterLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("inputs")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `inputs`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("inputs")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `inputs` field is not valid because:",
+                            SourceLine(_doc, "inputs", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `inputs` field is not valid because:",
+                            SourceLine(_doc, "inputs", str),
+                            [e],
+                            detailed_message=f"the `inputs` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        try:
+            if _doc.get("outputs") is None:
+                raise ValidationException("missing required field `outputs`", None, [])
+
+            outputs = load_field(
+                _doc.get("outputs"),
+                idmap_outputs_array_of_OutputParameterLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("outputs")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `outputs`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("outputs")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `outputs` field is not valid because:",
+                            SourceLine(_doc, "outputs", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `outputs` field is not valid because:",
+                            SourceLine(_doc, "outputs", str),
+                            [e],
+                            detailed_message=f"the `outputs` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        requirements = None
+        if "requirements" in _doc:
+            try:
+                requirements = load_field(
+                    _doc.get("requirements"),
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("requirements")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `requirements`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("requirements")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `requirements` field is not valid because:",
+                                SourceLine(_doc, "requirements", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `requirements` field is not valid because:",
+                                SourceLine(_doc, "requirements", str),
+                                [e],
+                                detailed_message=f"the `requirements` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        hints = None
+        if "hints" in _doc:
+            try:
+                hints = load_field(
+                    _doc.get("hints"),
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("hints")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `hints`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("hints")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `hints` field is not valid because:",
+                                SourceLine(_doc, "hints", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `hints` field is not valid because:",
+                                SourceLine(_doc, "hints", str),
+                                [e],
+                                detailed_message=f"the `hints` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        label = None
+        if "label" in _doc:
+            try:
+                label = load_field(
+                    _doc.get("label"),
+                    union_of_None_type_or_strtype,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("label")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `label`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("label")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `label` field is not valid because:",
+                                SourceLine(_doc, "label", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `label` field is not valid because:",
+                                SourceLine(_doc, "label", str),
+                                [e],
+                                detailed_message=f"the `label` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        doc = None
+        if "doc" in _doc:
+            try:
+                doc = load_field(
+                    _doc.get("doc"),
+                    union_of_None_type_or_strtype,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("doc")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `doc`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("doc")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `doc` field is not valid because:",
+                                SourceLine(_doc, "doc", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `doc` field is not valid because:",
+                                SourceLine(_doc, "doc", str),
+                                [e],
+                                detailed_message=f"the `doc` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        cwlVersion = None
+        if "cwlVersion" in _doc:
+            try:
+                cwlVersion = load_field(
+                    _doc.get("cwlVersion"),
+                    uri_union_of_None_type_or_CWLVersionLoader_False_True_None_None,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("cwlVersion")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `cwlVersion`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("cwlVersion")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `cwlVersion` field is not valid because:",
+                                SourceLine(_doc, "cwlVersion", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `cwlVersion` field is not valid because:",
+                                SourceLine(_doc, "cwlVersion", str),
+                                [e],
+                                detailed_message=f"the `cwlVersion` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        try:
+            if _doc.get("run") is None:
+                raise ValidationException("missing required field `run`", None, [])
+
+            run = load_field(
+                _doc.get("run"),
+                uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_False_False_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("run")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `run`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("run")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `run` field is not valid because:",
+                            SourceLine(_doc, "run", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `run` field is not valid because:",
+                            SourceLine(_doc, "run", str),
+                            [e],
+                            detailed_message=f"the `run` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `id`, `inputs`, `outputs`, `requirements`, `hints`, `label`, `doc`, `cwlVersion`, `class`, `run`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            id=id,
+            inputs=inputs,
+            outputs=outputs,
+            requirements=requirements,
+            hints=hints,
+            label=label,
+            doc=doc,
+            cwlVersion=cwlVersion,
+            run=run,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        loadingOptions.idx[cast(str, id)] = (_constructed, loadingOptions)
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.id is not None:
+            u = save_relative_uri(self.id, base_url, True, None, relative_uris)
+            r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
+        if self.inputs is not None:
+            r["inputs"] = save(
+                self.inputs, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.outputs is not None:
+            r["outputs"] = save(
+                self.outputs, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.requirements is not None:
+            r["requirements"] = save(
+                self.requirements,
+                top=False,
+                base_url=self.id,
+                relative_uris=relative_uris,
+            )
+        if self.hints is not None:
+            r["hints"] = save(
+                self.hints, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.label is not None:
+            r["label"] = save(
+                self.label, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.doc is not None:
+            r["doc"] = save(
+                self.doc, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.cwlVersion is not None:
+            u = save_relative_uri(self.cwlVersion, self.id, False, None, relative_uris)
+            r["cwlVersion"] = u
+        if self.run is not None:
+            u = save_relative_uri(self.run, self.id, False, None, relative_uris)
+            r["run"] = u
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(
+        [
+            "id",
+            "inputs",
+            "outputs",
+            "requirements",
+            "hints",
+            "label",
+            "doc",
+            "cwlVersion",
+            "class",
+            "run",
+        ]
+    )
+
+
+class MPIRequirement(ProcessRequirement):
+    """
+    Indicates that a process requires an MPI runtime.
+
+    """
+
+    class_uri = "http://commonwl.org/cwltool#MPIRequirement"
+
+    def __init__(
+        self,
+        processes: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "MPIRequirement"
+        self.processes = processes
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, MPIRequirement):
+            return bool(
+                self.class_ == other.class_ and self.processes == other.processes
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.processes))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "MPIRequirement":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("processes") is None:
+                raise ValidationException("missing required field `processes`", None, [])
+
+            processes = load_field(
+                _doc.get("processes"),
+                union_of_inttype_or_ExpressionLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("processes")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `processes`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("processes")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `processes` field is not valid because:",
+                            SourceLine(_doc, "processes", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `processes` field is not valid because:",
+                            SourceLine(_doc, "processes", str),
+                            [e],
+                            detailed_message=f"the `processes` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `processes`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            processes=processes,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.processes is not None:
+            r["processes"] = save(
+                self.processes,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "processes"])
+
+
+class CUDARequirement(ProcessRequirement):
+    """
+    Require support for NVIDA CUDA (GPU hardware acceleration).
+
+    """
+
+    class_uri = "http://commonwl.org/cwltool#CUDARequirement"
+
+    def __init__(
+        self,
+        cudaComputeCapability: Any,
+        cudaVersionMin: Any,
+        cudaDeviceCountMax: Optional[Any] = None,
+        cudaDeviceCountMin: Optional[Any] = None,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "CUDARequirement"
+        self.cudaComputeCapability = cudaComputeCapability
+        self.cudaDeviceCountMax = cudaDeviceCountMax
+        self.cudaDeviceCountMin = cudaDeviceCountMin
+        self.cudaVersionMin = cudaVersionMin
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, CUDARequirement):
+            return bool(
+                self.class_ == other.class_
+                and self.cudaComputeCapability == other.cudaComputeCapability
+                and self.cudaDeviceCountMax == other.cudaDeviceCountMax
+                and self.cudaDeviceCountMin == other.cudaDeviceCountMin
+                and self.cudaVersionMin == other.cudaVersionMin
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash(
+            (
+                self.class_,
+                self.cudaComputeCapability,
+                self.cudaDeviceCountMax,
+                self.cudaDeviceCountMin,
+                self.cudaVersionMin,
+            )
+        )
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "CUDARequirement":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("cudaComputeCapability") is None:
+                raise ValidationException("missing required field `cudaComputeCapability`", None, [])
+
+            cudaComputeCapability = load_field(
+                _doc.get("cudaComputeCapability"),
+                union_of_strtype_or_array_of_strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("cudaComputeCapability")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `cudaComputeCapability`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("cudaComputeCapability")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaComputeCapability` field is not valid because:",
+                            SourceLine(_doc, "cudaComputeCapability", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaComputeCapability` field is not valid because:",
+                            SourceLine(_doc, "cudaComputeCapability", str),
+                            [e],
+                            detailed_message=f"the `cudaComputeCapability` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        cudaDeviceCountMax = None
+        if "cudaDeviceCountMax" in _doc:
+            try:
+                cudaDeviceCountMax = load_field(
+                    _doc.get("cudaDeviceCountMax"),
+                    union_of_None_type_or_inttype_or_ExpressionLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("cudaDeviceCountMax")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `cudaDeviceCountMax`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("cudaDeviceCountMax")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMax` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMax", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMax` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMax", str),
+                                [e],
+                                detailed_message=f"the `cudaDeviceCountMax` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        cudaDeviceCountMin = None
+        if "cudaDeviceCountMin" in _doc:
+            try:
+                cudaDeviceCountMin = load_field(
+                    _doc.get("cudaDeviceCountMin"),
+                    union_of_None_type_or_inttype_or_ExpressionLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("cudaDeviceCountMin")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `cudaDeviceCountMin`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("cudaDeviceCountMin")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMin` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMin", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMin` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMin", str),
+                                [e],
+                                detailed_message=f"the `cudaDeviceCountMin` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        try:
+            if _doc.get("cudaVersionMin") is None:
+                raise ValidationException("missing required field `cudaVersionMin`", None, [])
+
+            cudaVersionMin = load_field(
+                _doc.get("cudaVersionMin"),
+                strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("cudaVersionMin")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `cudaVersionMin`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("cudaVersionMin")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaVersionMin` field is not valid because:",
+                            SourceLine(_doc, "cudaVersionMin", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaVersionMin` field is not valid because:",
+                            SourceLine(_doc, "cudaVersionMin", str),
+                            [e],
+                            detailed_message=f"the `cudaVersionMin` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `cudaComputeCapability`, `cudaDeviceCountMax`, `cudaDeviceCountMin`, `cudaVersionMin`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            cudaComputeCapability=cudaComputeCapability,
+            cudaDeviceCountMax=cudaDeviceCountMax,
+            cudaDeviceCountMin=cudaDeviceCountMin,
+            cudaVersionMin=cudaVersionMin,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.cudaComputeCapability is not None:
+            r["cudaComputeCapability"] = save(
+                self.cudaComputeCapability,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+        if self.cudaDeviceCountMax is not None:
+            r["cudaDeviceCountMax"] = save(
+                self.cudaDeviceCountMax,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+        if self.cudaDeviceCountMin is not None:
+            r["cudaDeviceCountMin"] = save(
+                self.cudaDeviceCountMin,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+        if self.cudaVersionMin is not None:
+            r["cudaVersionMin"] = save(
+                self.cudaVersionMin,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(
+        [
+            "class",
+            "cudaComputeCapability",
+            "cudaDeviceCountMax",
+            "cudaDeviceCountMin",
+            "cudaVersionMin",
+        ]
+    )
+
+
+class ShmSize(ProcessRequirement):
+    class_uri = "http://commonwl.org/cwltool#ShmSize"
+
+    def __init__(
+        self,
+        shmSize: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "ShmSize"
+        self.shmSize = shmSize
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, ShmSize):
+            return bool(self.class_ == other.class_ and self.shmSize == other.shmSize)
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.shmSize))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "ShmSize":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("shmSize") is None:
+                raise ValidationException("missing required field `shmSize`", None, [])
+
+            shmSize = load_field(
+                _doc.get("shmSize"),
+                strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("shmSize")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `shmSize`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("shmSize")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `shmSize` field is not valid because:",
+                            SourceLine(_doc, "shmSize", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `shmSize` field is not valid because:",
+                            SourceLine(_doc, "shmSize", str),
+                            [e],
+                            detailed_message=f"the `shmSize` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `shmSize`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            shmSize=shmSize,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.shmSize is not None:
+            r["shmSize"] = save(
+                self.shmSize, top=False, base_url=base_url, relative_uris=relative_uris
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "shmSize"])
+
+
+_vocab = {
+    "Any": "https://w3id.org/cwl/salad#Any",
+    "ArraySchema": "https://w3id.org/cwl/salad#ArraySchema",
+    "CUDARequirement": "http://commonwl.org/cwltool#CUDARequirement",
+    "CWLArraySchema": "https://w3id.org/cwl/cwl#CWLArraySchema",
+    "CWLInputFile": "https://w3id.org/cwl/cwl#CWLInputFile",
+    "CWLObjectType": "https://w3id.org/cwl/cwl#CWLObjectType",
+    "CWLRecordField": "https://w3id.org/cwl/cwl#CWLRecordField",
+    "CWLRecordSchema": "https://w3id.org/cwl/cwl#CWLRecordSchema",
+    "CWLType": "https://w3id.org/cwl/cwl#CWLType",
+    "CWLVersion": "https://w3id.org/cwl/cwl#CWLVersion",
+    "CommandInputArraySchema": "https://w3id.org/cwl/cwl#CommandInputArraySchema",
+    "CommandInputEnumSchema": "https://w3id.org/cwl/cwl#CommandInputEnumSchema",
+    "CommandInputParameter": "https://w3id.org/cwl/cwl#CommandInputParameter",
+    "CommandInputRecordField": "https://w3id.org/cwl/cwl#CommandInputRecordField",
+    "CommandInputRecordSchema": "https://w3id.org/cwl/cwl#CommandInputRecordSchema",
+    "CommandLineBinding": "https://w3id.org/cwl/cwl#CommandLineBinding",
+    "CommandLineTool": "https://w3id.org/cwl/cwl#CommandLineTool",
+    "CommandOutputArraySchema": "https://w3id.org/cwl/cwl#CommandOutputArraySchema",
+    "CommandOutputBinding": "https://w3id.org/cwl/cwl#CommandOutputBinding",
+    "CommandOutputEnumSchema": "https://w3id.org/cwl/cwl#CommandOutputEnumSchema",
+    "CommandOutputParameter": "https://w3id.org/cwl/cwl#CommandOutputParameter",
+    "CommandOutputRecordField": "https://w3id.org/cwl/cwl#CommandOutputRecordField",
+    "CommandOutputRecordSchema": "https://w3id.org/cwl/cwl#CommandOutputRecordSchema",
+    "Directory": "https://w3id.org/cwl/cwl#Directory",
+    "Dirent": "https://w3id.org/cwl/cwl#Dirent",
+    "DockerRequirement": "https://w3id.org/cwl/cwl#DockerRequirement",
+    "Documented": "https://w3id.org/cwl/salad#Documented",
+    "EnumSchema": "https://w3id.org/cwl/salad#EnumSchema",
+    "EnvVarRequirement": "https://w3id.org/cwl/cwl#EnvVarRequirement",
+    "EnvironmentDef": "https://w3id.org/cwl/cwl#EnvironmentDef",
+    "Expression": "https://w3id.org/cwl/cwl#Expression",
+    "ExpressionPlaceholder": "https://w3id.org/cwl/cwl#ExpressionPlaceholder",
+    "ExpressionTool": "https://w3id.org/cwl/cwl#ExpressionTool",
+    "ExpressionToolOutputParameter": "https://w3id.org/cwl/cwl#ExpressionToolOutputParameter",
+    "File": "https://w3id.org/cwl/cwl#File",
+    "InitialWorkDirRequirement": "https://w3id.org/cwl/cwl#InitialWorkDirRequirement",
+    "InlineJavascriptRequirement": "https://w3id.org/cwl/cwl#InlineJavascriptRequirement",
+    "InplaceUpdateRequirement": "http://commonwl.org/cwltool#InplaceUpdateRequirement",
+    "InputArraySchema": "https://w3id.org/cwl/cwl#InputArraySchema",
+    "InputBinding": "https://w3id.org/cwl/cwl#InputBinding",
+    "InputEnumSchema": "https://w3id.org/cwl/cwl#InputEnumSchema",
+    "InputParameter": "https://w3id.org/cwl/cwl#InputParameter",
+    "InputRecordField": "https://w3id.org/cwl/cwl#InputRecordField",
+    "InputRecordSchema": "https://w3id.org/cwl/cwl#InputRecordSchema",
+    "InputSchema": "https://w3id.org/cwl/cwl#InputSchema",
+    "LinkMergeMethod": "https://w3id.org/cwl/cwl#LinkMergeMethod",
+    "LoadListingRequirement": "http://commonwl.org/cwltool#LoadListingRequirement",
+    "MPIRequirement": "http://commonwl.org/cwltool#MPIRequirement",
+    "MapSchema": "https://w3id.org/cwl/salad#MapSchema",
+    "MultipleInputFeatureRequirement": "https://w3id.org/cwl/cwl#MultipleInputFeatureRequirement",
+    "NetworkAccess": "http://commonwl.org/cwltool#NetworkAccess",
+    "OutputArraySchema": "https://w3id.org/cwl/cwl#OutputArraySchema",
+    "OutputBinding": "https://w3id.org/cwl/cwl#OutputBinding",
+    "OutputEnumSchema": "https://w3id.org/cwl/cwl#OutputEnumSchema",
+    "OutputParameter": "https://w3id.org/cwl/cwl#OutputParameter",
+    "OutputRecordField": "https://w3id.org/cwl/cwl#OutputRecordField",
+    "OutputRecordSchema": "https://w3id.org/cwl/cwl#OutputRecordSchema",
+    "OutputSchema": "https://w3id.org/cwl/cwl#OutputSchema",
+    "Parameter": "https://w3id.org/cwl/cwl#Parameter",
+    "PrimitiveType": "https://w3id.org/cwl/salad#PrimitiveType",
+    "Process": "https://w3id.org/cwl/cwl#Process",
+    "ProcessGenerator": "http://commonwl.org/cwltool#ProcessGenerator",
+    "ProcessRequirement": "https://w3id.org/cwl/cwl#ProcessRequirement",
+    "RecordField": "https://w3id.org/cwl/salad#RecordField",
+    "RecordSchema": "https://w3id.org/cwl/salad#RecordSchema",
+    "ResourceRequirement": "https://w3id.org/cwl/cwl#ResourceRequirement",
+    "ScatterFeatureRequirement": "https://w3id.org/cwl/cwl#ScatterFeatureRequirement",
+    "ScatterMethod": "https://w3id.org/cwl/cwl#ScatterMethod",
+    "SchemaBase": "https://w3id.org/cwl/cwl#SchemaBase",
+    "SchemaDefRequirement": "https://w3id.org/cwl/cwl#SchemaDefRequirement",
+    "Secrets": "http://commonwl.org/cwltool#Secrets",
+    "ShellCommandRequirement": "https://w3id.org/cwl/cwl#ShellCommandRequirement",
+    "ShmSize": "http://commonwl.org/cwltool#ShmSize",
+    "Sink": "https://w3id.org/cwl/cwl#Sink",
+    "SoftwarePackage": "https://w3id.org/cwl/cwl#SoftwarePackage",
+    "SoftwareRequirement": "https://w3id.org/cwl/cwl#SoftwareRequirement",
+    "StepInputExpressionRequirement": "https://w3id.org/cwl/cwl#StepInputExpressionRequirement",
+    "SubworkflowFeatureRequirement": "https://w3id.org/cwl/cwl#SubworkflowFeatureRequirement",
+    "TimeLimit": "http://commonwl.org/cwltool#TimeLimit",
+    "UnionSchema": "https://w3id.org/cwl/salad#UnionSchema",
+    "WorkReuse": "http://commonwl.org/cwltool#WorkReuse",
+    "Workflow": "https://w3id.org/cwl/cwl#Workflow",
+    "WorkflowOutputParameter": "https://w3id.org/cwl/cwl#WorkflowOutputParameter",
+    "WorkflowStep": "https://w3id.org/cwl/cwl#WorkflowStep",
     "WorkflowStepInput": "https://w3id.org/cwl/cwl#WorkflowStepInput",
     "WorkflowStepOutput": "https://w3id.org/cwl/cwl#WorkflowStepOutput",
     "array": "https://w3id.org/cwl/salad#array",
     "boolean": "http://www.w3.org/2001/XMLSchema#boolean",
+    "deep_listing": "http://commonwl.org/cwltool#LoadListingRequirement/loadListing/LoadListingEnum/deep_listing",
     "dotproduct": "https://w3id.org/cwl/cwl#ScatterMethod/dotproduct",
     "double": "http://www.w3.org/2001/XMLSchema#double",
     "draft-2": "https://w3id.org/cwl/cwl#draft-2",
@@ -21195,8 +23907,10 @@ def save(
     "merge_flattened": "https://w3id.org/cwl/cwl#LinkMergeMethod/merge_flattened",
     "merge_nested": "https://w3id.org/cwl/cwl#LinkMergeMethod/merge_nested",
     "nested_crossproduct": "https://w3id.org/cwl/cwl#ScatterMethod/nested_crossproduct",
+    "no_listing": "http://commonwl.org/cwltool#LoadListingRequirement/loadListing/LoadListingEnum/no_listing",
     "null": "https://w3id.org/cwl/salad#null",
     "record": "https://w3id.org/cwl/salad#record",
+    "shallow_listing": "http://commonwl.org/cwltool#LoadListingRequirement/loadListing/LoadListingEnum/shallow_listing",
     "stderr": "https://w3id.org/cwl/cwl#stderr",
     "stdout": "https://w3id.org/cwl/cwl#stdout",
     "string": "http://www.w3.org/2001/XMLSchema#string",
@@ -21207,6 +23921,7 @@ def save(
 _rvocab = {
     "https://w3id.org/cwl/salad#Any": "Any",
     "https://w3id.org/cwl/salad#ArraySchema": "ArraySchema",
+    "http://commonwl.org/cwltool#CUDARequirement": "CUDARequirement",
     "https://w3id.org/cwl/cwl#CWLArraySchema": "CWLArraySchema",
     "https://w3id.org/cwl/cwl#CWLInputFile": "CWLInputFile",
     "https://w3id.org/cwl/cwl#CWLObjectType": "CWLObjectType",
@@ -21241,6 +23956,7 @@ def save(
     "https://w3id.org/cwl/cwl#File": "File",
     "https://w3id.org/cwl/cwl#InitialWorkDirRequirement": "InitialWorkDirRequirement",
     "https://w3id.org/cwl/cwl#InlineJavascriptRequirement": "InlineJavascriptRequirement",
+    "http://commonwl.org/cwltool#InplaceUpdateRequirement": "InplaceUpdateRequirement",
     "https://w3id.org/cwl/cwl#InputArraySchema": "InputArraySchema",
     "https://w3id.org/cwl/cwl#InputBinding": "InputBinding",
     "https://w3id.org/cwl/cwl#InputEnumSchema": "InputEnumSchema",
@@ -21249,8 +23965,11 @@ def save(
     "https://w3id.org/cwl/cwl#InputRecordSchema": "InputRecordSchema",
     "https://w3id.org/cwl/cwl#InputSchema": "InputSchema",
     "https://w3id.org/cwl/cwl#LinkMergeMethod": "LinkMergeMethod",
+    "http://commonwl.org/cwltool#LoadListingRequirement": "LoadListingRequirement",
+    "http://commonwl.org/cwltool#MPIRequirement": "MPIRequirement",
     "https://w3id.org/cwl/salad#MapSchema": "MapSchema",
     "https://w3id.org/cwl/cwl#MultipleInputFeatureRequirement": "MultipleInputFeatureRequirement",
+    "http://commonwl.org/cwltool#NetworkAccess": "NetworkAccess",
     "https://w3id.org/cwl/cwl#OutputArraySchema": "OutputArraySchema",
     "https://w3id.org/cwl/cwl#OutputBinding": "OutputBinding",
     "https://w3id.org/cwl/cwl#OutputEnumSchema": "OutputEnumSchema",
@@ -21261,6 +23980,7 @@ def save(
     "https://w3id.org/cwl/cwl#Parameter": "Parameter",
     "https://w3id.org/cwl/salad#PrimitiveType": "PrimitiveType",
     "https://w3id.org/cwl/cwl#Process": "Process",
+    "http://commonwl.org/cwltool#ProcessGenerator": "ProcessGenerator",
     "https://w3id.org/cwl/cwl#ProcessRequirement": "ProcessRequirement",
     "https://w3id.org/cwl/salad#RecordField": "RecordField",
     "https://w3id.org/cwl/salad#RecordSchema": "RecordSchema",
@@ -21269,13 +23989,17 @@ def save(
     "https://w3id.org/cwl/cwl#ScatterMethod": "ScatterMethod",
     "https://w3id.org/cwl/cwl#SchemaBase": "SchemaBase",
     "https://w3id.org/cwl/cwl#SchemaDefRequirement": "SchemaDefRequirement",
+    "http://commonwl.org/cwltool#Secrets": "Secrets",
     "https://w3id.org/cwl/cwl#ShellCommandRequirement": "ShellCommandRequirement",
+    "http://commonwl.org/cwltool#ShmSize": "ShmSize",
     "https://w3id.org/cwl/cwl#Sink": "Sink",
     "https://w3id.org/cwl/cwl#SoftwarePackage": "SoftwarePackage",
     "https://w3id.org/cwl/cwl#SoftwareRequirement": "SoftwareRequirement",
     "https://w3id.org/cwl/cwl#StepInputExpressionRequirement": "StepInputExpressionRequirement",
     "https://w3id.org/cwl/cwl#SubworkflowFeatureRequirement": "SubworkflowFeatureRequirement",
+    "http://commonwl.org/cwltool#TimeLimit": "TimeLimit",
     "https://w3id.org/cwl/salad#UnionSchema": "UnionSchema",
+    "http://commonwl.org/cwltool#WorkReuse": "WorkReuse",
     "https://w3id.org/cwl/cwl#Workflow": "Workflow",
     "https://w3id.org/cwl/cwl#WorkflowOutputParameter": "WorkflowOutputParameter",
     "https://w3id.org/cwl/cwl#WorkflowStep": "WorkflowStep",
@@ -21283,6 +24007,7 @@ def save(
     "https://w3id.org/cwl/cwl#WorkflowStepOutput": "WorkflowStepOutput",
     "https://w3id.org/cwl/salad#array": "array",
     "http://www.w3.org/2001/XMLSchema#boolean": "boolean",
+    "http://commonwl.org/cwltool#LoadListingRequirement/loadListing/LoadListingEnum/deep_listing": "deep_listing",
     "https://w3id.org/cwl/cwl#ScatterMethod/dotproduct": "dotproduct",
     "http://www.w3.org/2001/XMLSchema#double": "double",
     "https://w3id.org/cwl/cwl#draft-2": "draft-2",
@@ -21304,8 +24029,10 @@ def save(
     "https://w3id.org/cwl/cwl#LinkMergeMethod/merge_flattened": "merge_flattened",
     "https://w3id.org/cwl/cwl#LinkMergeMethod/merge_nested": "merge_nested",
     "https://w3id.org/cwl/cwl#ScatterMethod/nested_crossproduct": "nested_crossproduct",
+    "http://commonwl.org/cwltool#LoadListingRequirement/loadListing/LoadListingEnum/no_listing": "no_listing",
     "https://w3id.org/cwl/salad#null": "null",
     "https://w3id.org/cwl/salad#record": "record",
+    "http://commonwl.org/cwltool#LoadListingRequirement/loadListing/LoadListingEnum/shallow_listing": "shallow_listing",
     "https://w3id.org/cwl/cwl#stderr": "stderr",
     "https://w3id.org/cwl/cwl#stdout": "stdout",
     "http://www.w3.org/2001/XMLSchema#string": "string",
@@ -21579,6 +24306,16 @@ def save(
 StepInputExpressionRequirementLoader = _RecordLoader(
     StepInputExpressionRequirement, None, None
 )
+LoadListingRequirementLoader = _RecordLoader(LoadListingRequirement, None, None)
+InplaceUpdateRequirementLoader = _RecordLoader(InplaceUpdateRequirement, None, None)
+SecretsLoader = _RecordLoader(Secrets, None, None)
+TimeLimitLoader = _RecordLoader(TimeLimit, None, None)
+WorkReuseLoader = _RecordLoader(WorkReuse, None, None)
+NetworkAccessLoader = _RecordLoader(NetworkAccess, None, None)
+ProcessGeneratorLoader = _RecordLoader(ProcessGenerator, None, None)
+MPIRequirementLoader = _RecordLoader(MPIRequirement, None, None)
+CUDARequirementLoader = _RecordLoader(CUDARequirement, None, None)
+ShmSizeLoader = _RecordLoader(ShmSize, None, None)
 array_of_strtype = _ArrayLoader(strtype)
 union_of_None_type_or_strtype_or_array_of_strtype = _UnionLoader(
     (
@@ -21909,7 +24646,7 @@ def save(
 idmap_outputs_array_of_OutputParameterLoader = _IdMapLoader(
     array_of_OutputParameterLoader, "id", "type"
 )
-union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _UnionLoader(
+union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader = _UnionLoader(
     (
         InlineJavascriptRequirementLoader,
         SchemaDefRequirementLoader,
@@ -21923,23 +24660,32 @@ def save(
         ScatterFeatureRequirementLoader,
         MultipleInputFeatureRequirementLoader,
         StepInputExpressionRequirementLoader,
+        LoadListingRequirementLoader,
+        InplaceUpdateRequirementLoader,
+        SecretsLoader,
+        TimeLimitLoader,
+        WorkReuseLoader,
+        NetworkAccessLoader,
+        MPIRequirementLoader,
+        CUDARequirementLoader,
+        ShmSizeLoader,
     )
 )
-array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _ArrayLoader(
-    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader
+array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader = _ArrayLoader(
+    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader
 )
-union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _UnionLoader(
+union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader = _UnionLoader(
     (
         None_type,
-        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
     )
 )
-idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _IdMapLoader(
-    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader = _IdMapLoader(
+    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
     "class",
     "None",
 )
-union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _UnionLoader(
+union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type = _UnionLoader(
     (
         InlineJavascriptRequirementLoader,
         SchemaDefRequirementLoader,
@@ -21953,20 +24699,29 @@ def save(
         ScatterFeatureRequirementLoader,
         MultipleInputFeatureRequirementLoader,
         StepInputExpressionRequirementLoader,
+        LoadListingRequirementLoader,
+        InplaceUpdateRequirementLoader,
+        SecretsLoader,
+        TimeLimitLoader,
+        WorkReuseLoader,
+        NetworkAccessLoader,
+        MPIRequirementLoader,
+        CUDARequirementLoader,
+        ShmSizeLoader,
         Any_type,
     )
 )
-array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _ArrayLoader(
-    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type
+array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type = _ArrayLoader(
+    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type
 )
-union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _UnionLoader(
+union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type = _UnionLoader(
     (
         None_type,
-        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
     )
 )
-idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _IdMapLoader(
-    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type = _IdMapLoader(
+    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_LoadListingRequirementLoader_or_InplaceUpdateRequirementLoader_or_SecretsLoader_or_TimeLimitLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
     "class",
     "None",
 )
@@ -22323,18 +25078,17 @@ def save(
 idmap_hints_union_of_None_type_or_array_of_Any_type = _IdMapLoader(
     union_of_None_type_or_array_of_Any_type, "class", "None"
 )
-union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader = (
-    _UnionLoader(
-        (
-            strtype,
-            CommandLineToolLoader,
-            ExpressionToolLoader,
-            WorkflowLoader,
-        )
+union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader = _UnionLoader(
+    (
+        strtype,
+        CommandLineToolLoader,
+        ExpressionToolLoader,
+        WorkflowLoader,
+        ProcessGeneratorLoader,
     )
 )
-uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_False_False_None_None = _URILoader(
-    union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_False_False_None_None = _URILoader(
+    union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
     False,
     False,
     None,
@@ -22389,24 +25143,68 @@ def save(
 uri_StepInputExpressionRequirement_classLoader_False_True_None_None = _URILoader(
     StepInputExpressionRequirement_classLoader, False, True, None, None
 )
-union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader = _UnionLoader(
+uri_strtype_False_True_None_None = _URILoader(strtype, False, True, None, None)
+LoadListingEnumLoader = _EnumLoader(
+    (
+        "no_listing",
+        "shallow_listing",
+        "deep_listing",
+    ),
+    "LoadListingEnum",
+)
+union_of_LoadListingEnumLoader = _UnionLoader((LoadListingEnumLoader,))
+uri_array_of_strtype_False_False_0_None = _URILoader(
+    array_of_strtype, False, False, 0, None
+)
+union_of_inttype_or_strtype = _UnionLoader(
+    (
+        inttype,
+        strtype,
+    )
+)
+union_of_booltype_or_strtype = _UnionLoader(
+    (
+        booltype,
+        strtype,
+    )
+)
+union_of_inttype_or_ExpressionLoader = _UnionLoader(
+    (
+        inttype,
+        ExpressionLoader,
+    )
+)
+union_of_strtype_or_array_of_strtype = _UnionLoader(
+    (
+        strtype,
+        array_of_strtype,
+    )
+)
+union_of_None_type_or_inttype_or_ExpressionLoader = _UnionLoader(
+    (
+        None_type,
+        inttype,
+        ExpressionLoader,
+    )
+)
+union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader = _UnionLoader(
     (
         CommandLineToolLoader,
         ExpressionToolLoader,
         WorkflowLoader,
+        ProcessGeneratorLoader,
     )
 )
-array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader = (
-    _ArrayLoader(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader
-    )
+array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader = _ArrayLoader(
+    union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader
 )
-union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader = _UnionLoader(
+union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader = _UnionLoader(
     (
         CommandLineToolLoader,
         ExpressionToolLoader,
         WorkflowLoader,
-        array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+        ProcessGeneratorLoader,
+        array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
     )
 )
 
@@ -22434,7 +25232,7 @@ def load_document(
     if loadingOptions is None:
         loadingOptions = LoadingOptions()
     result, metadata = _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
         doc,
         baseuri,
         loadingOptions,
@@ -22453,7 +25251,7 @@ def load_document_with_metadata(
     if loadingOptions is None:
         loadingOptions = LoadingOptions(fileuri=baseuri)
     return _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
         doc,
         baseuri,
         loadingOptions,
@@ -22474,7 +25272,7 @@ def load_document_by_string(
         loadingOptions = LoadingOptions(fileuri=uri)
 
     result, metadata = _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
         result,
         uri,
         loadingOptions,
@@ -22497,7 +25295,7 @@ def load_document_by_yaml(
         loadingOptions = LoadingOptions(fileuri=uri)
 
     result, metadata = _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
         yaml,
         uri,
         loadingOptions,
diff --git a/cwl_utils/parser/cwl_v1_0_utils.py b/cwl_utils/parser/cwl_v1_0_utils.py
index 783e34dd..bf96d680 100644
--- a/cwl_utils/parser/cwl_v1_0_utils.py
+++ b/cwl_utils/parser/cwl_v1_0_utils.py
@@ -5,7 +5,7 @@
 from collections import namedtuple
 from collections.abc import MutableMapping, MutableSequence
 from io import StringIO
-from typing import IO, Any, Optional, Union, cast
+from typing import Any, IO, Optional, Union, cast
 from urllib.parse import urldefrag
 
 from schema_salad.exceptions import ValidationException
@@ -417,7 +417,7 @@ def type_for_step_output(
     raise ValidationException(
         "param {} not found in {}.".format(
             sourcename,
-            yaml_dumps(cwl.save(step_run)),
+            yaml_dumps(cwl.save(step)),
         )
     )
 
@@ -551,6 +551,6 @@ def param_for_source_id(
         "param {} not found in {}\n{}.".format(
             sourcename,
             yaml_dumps(cwl.save(process)),
-            f" or\n {yaml_dumps(cwl.save(parent))}" if parent is not None else "",
+            (f" or\n {yaml_dumps(cwl.save(parent))}" if parent is not None else ""),
         )
     )
diff --git a/cwl_utils/parser/cwl_v1_1.py b/cwl_utils/parser/cwl_v1_1.py
index 3421dfc8..672ccd80 100644
--- a/cwl_utils/parser/cwl_v1_1.py
+++ b/cwl_utils/parser/cwl_v1_1.py
@@ -1162,6 +1162,8 @@ class RecordField(Documented):
     A field of a record.
     """
 
+    class_uri = "https://w3id.org/cwl/salad#RecordField"
+
     def __init__(
         self,
         name: Any,
@@ -1428,6 +1430,8 @@ def save(
 
 
 class RecordSchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#RecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -1632,6 +1636,8 @@ class EnumSchema(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/salad#EnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -1898,6 +1904,8 @@ def save(
 
 
 class ArraySchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#ArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -2097,6 +2105,8 @@ def save(
 
 
 class MapSchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#MapSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -2296,6 +2306,8 @@ def save(
 
 
 class UnionSchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#UnionSchema"
+
     def __init__(
         self,
         names: Any,
@@ -2495,6 +2507,8 @@ def save(
 
 
 class CWLArraySchema(ArraySchema):
+    class_uri = "https://w3id.org/cwl/cwl#CWLArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -2694,6 +2708,8 @@ def save(
 
 
 class CWLRecordField(RecordField):
+    class_uri = "https://w3id.org/cwl/cwl#CWLRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -2960,6 +2976,8 @@ def save(
 
 
 class CWLRecordSchema(RecordSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CWLRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -3229,6 +3247,8 @@ class File(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#File"
+
     def __init__(
         self,
         location: Optional[Any] = None,
@@ -3316,12 +3336,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "File":
-            raise ValidationException("tried `File` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_File_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         location = None
         if "location" in _doc:
             try:
@@ -3891,8 +3920,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "File"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.location is not None:
             u = save_relative_uri(self.location, base_url, False, None, relative_uris)
             r["location"] = u
@@ -4012,6 +4042,8 @@ class Directory(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#Directory"
+
     def __init__(
         self,
         location: Optional[Any] = None,
@@ -4065,12 +4097,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "Directory":
-            raise ValidationException("tried `Directory` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_Directory_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         location = None
         if "location" in _doc:
             try:
@@ -4304,8 +4345,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "Directory"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.location is not None:
             u = save_relative_uri(self.location, base_url, False, None, relative_uris)
             r["location"] = u
@@ -4366,6 +4408,8 @@ class Parameter(FieldBase, Documented, Identified):
 
 
 class InputBinding(Saveable):
+    class_uri = "https://w3id.org/cwl/cwl#InputBinding"
+
     def __init__(
         self,
         loadContents: Optional[Any] = None,
@@ -4525,6 +4569,8 @@ class OutputSchema(IOSchema):
 
 
 class InputRecordField(CWLRecordField, FieldBase, InputFormat, LoadContents):
+    class_uri = "https://w3id.org/cwl/cwl#InputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -5156,6 +5202,8 @@ def save(
 
 
 class InputRecordSchema(CWLRecordSchema, InputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#InputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -5532,6 +5580,8 @@ def save(
 
 
 class InputEnumSchema(EnumSchema, InputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#InputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -5908,6 +5958,8 @@ def save(
 
 
 class InputArraySchema(CWLArraySchema, InputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#InputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -6284,6 +6336,8 @@ def save(
 
 
 class OutputRecordField(CWLRecordField, FieldBase, OutputFormat):
+    class_uri = "https://w3id.org/cwl/cwl#OutputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -6787,6 +6841,8 @@ def save(
 
 
 class OutputRecordSchema(CWLRecordSchema, OutputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#OutputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -7163,6 +7219,8 @@ def save(
 
 
 class OutputEnumSchema(EnumSchema, OutputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#OutputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -7539,6 +7597,8 @@ def save(
 
 
 class OutputArraySchema(CWLArraySchema, OutputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#OutputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -7956,6 +8016,8 @@ class InlineJavascriptRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#InlineJavascriptRequirement"
+
     def __init__(
         self,
         expressionLib: Optional[Any] = None,
@@ -7998,12 +8060,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "InlineJavascriptRequirement":
-            raise ValidationException("tried `InlineJavascriptRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_InlineJavascriptRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         expressionLib = None
         if "expressionLib" in _doc:
             try:
@@ -8093,8 +8164,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "InlineJavascriptRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.expressionLib is not None:
             r["expressionLib"] = save(
                 self.expressionLib,
@@ -8130,6 +8202,8 @@ class SchemaDefRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#SchemaDefRequirement"
+
     def __init__(
         self,
         types: Any,
@@ -8169,12 +8243,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "SchemaDefRequirement":
-            raise ValidationException("tried `SchemaDefRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_SchemaDefRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("types") is None:
                 raise ValidationException("missing required field `types`", None, [])
@@ -8265,8 +8348,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "SchemaDefRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.types is not None:
             r["types"] = save(
                 self.types, top=False, base_url=base_url, relative_uris=relative_uris
@@ -8284,6 +8368,8 @@ def save(
 
 
 class SecondaryFileSchema(Saveable):
+    class_uri = "https://w3id.org/cwl/cwl#SecondaryFileSchema"
+
     def __init__(
         self,
         pattern: Any,
@@ -8491,6 +8577,8 @@ class LoadListingRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#LoadListingRequirement"
+
     def __init__(
         self,
         loadListing: Optional[Any] = None,
@@ -8532,12 +8620,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "LoadListingRequirement":
-            raise ValidationException("tried `LoadListingRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_LoadListingRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         loadListing = None
         if "loadListing" in _doc:
             try:
@@ -8627,8 +8724,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "LoadListingRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.loadListing is not None:
             r["loadListing"] = save(
                 self.loadListing,
@@ -8656,6 +8754,8 @@ class EnvironmentDef(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#EnvironmentDef"
+
     def __init__(
         self,
         envName: Any,
@@ -8897,6 +8997,8 @@ class CommandLineBinding(InputBinding):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandLineBinding"
+
     def __init__(
         self,
         loadContents: Optional[Any] = None,
@@ -9419,6 +9521,8 @@ class CommandOutputBinding(LoadContents):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputBinding"
+
     def __init__(
         self,
         loadContents: Optional[Any] = None,
@@ -9739,6 +9843,8 @@ def save(
 
 
 class CommandLineBindable(Saveable):
+    class_uri = "https://w3id.org/cwl/cwl#CommandLineBindable"
+
     def __init__(
         self,
         inputBinding: Optional[Any] = None,
@@ -9886,6 +9992,8 @@ def save(
 
 
 class CommandInputRecordField(InputRecordField, CommandLineBindable):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -10579,6 +10687,8 @@ def save(
 class CommandInputRecordSchema(
     InputRecordSchema, CommandInputSchema, CommandLineBindable
 ):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -11022,6 +11132,8 @@ def save(
 
 
 class CommandInputEnumSchema(InputEnumSchema, CommandInputSchema, CommandLineBindable):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -11467,6 +11579,8 @@ def save(
 class CommandInputArraySchema(
     InputArraySchema, CommandInputSchema, CommandLineBindable
 ):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -11903,6 +12017,8 @@ def save(
 
 
 class CommandOutputRecordField(OutputRecordField):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -12474,6 +12590,8 @@ def save(
 
 
 class CommandOutputRecordSchema(OutputRecordSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -12850,6 +12968,8 @@ def save(
 
 
 class CommandOutputEnumSchema(OutputEnumSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -13226,6 +13346,8 @@ def save(
 
 
 class CommandOutputArraySchema(OutputArraySchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -13606,6 +13728,8 @@ class CommandInputParameter(InputParameter):
     An input parameter for a CommandLineTool.
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -14358,6 +14482,8 @@ class CommandOutputParameter(OutputParameter):
     An output parameter for a CommandLineTool.
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -14934,6 +15060,8 @@ class CommandLineTool(Process):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandLineTool"
+
     def __init__(
         self,
         inputs: Any,
@@ -15041,12 +15169,6 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
-
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "CommandLineTool":
-            raise ValidationException("tried `CommandLineTool` but")
-
         id = None
         if "id" in _doc:
             try:
@@ -15103,6 +15225,21 @@ def fromDoc(
                 id = "_:" + str(_uuid__.uuid4())
         if not __original_id_is_none:
             baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_CommandLineTool_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         label = None
         if "label" in _doc:
             try:
@@ -15298,7 +15435,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -15345,7 +15482,7 @@ def fromDoc(
             try:
                 hints = load_field(
                     _doc.get("hints"),
-                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("hints")
@@ -15868,11 +16005,12 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "CommandLineTool"
         if self.id is not None:
             u = save_relative_uri(self.id, base_url, True, None, relative_uris)
             r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
         if self.label is not None:
             r["label"] = save(
                 self.label, top=False, base_url=self.id, relative_uris=relative_uris
@@ -16035,6 +16173,8 @@ class DockerRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#DockerRequirement"
+
     def __init__(
         self,
         dockerPull: Optional[Any] = None,
@@ -16102,12 +16242,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "DockerRequirement":
-            raise ValidationException("tried `DockerRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_DockerRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         dockerPull = None
         if "dockerPull" in _doc:
             try:
@@ -16437,8 +16586,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "DockerRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.dockerPull is not None:
             r["dockerPull"] = save(
                 self.dockerPull,
@@ -16510,6 +16660,8 @@ class SoftwareRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#SoftwareRequirement"
+
     def __init__(
         self,
         packages: Any,
@@ -16549,12 +16701,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "SoftwareRequirement":
-            raise ValidationException("tried `SoftwareRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_SoftwareRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("packages") is None:
                 raise ValidationException("missing required field `packages`", None, [])
@@ -16645,8 +16806,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "SoftwareRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.packages is not None:
             r["packages"] = save(
                 self.packages, top=False, base_url=base_url, relative_uris=relative_uris
@@ -16664,6 +16826,8 @@ def save(
 
 
 class SoftwarePackage(Saveable):
+    class_uri = "https://w3id.org/cwl/cwl#SoftwarePackage"
+
     def __init__(
         self,
         package: Any,
@@ -16928,6 +17092,8 @@ class Dirent(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#Dirent"
+
     def __init__(
         self,
         entry: Any,
@@ -17192,6 +17358,8 @@ class InitialWorkDirRequirement(ProcessRequirement):
     Define a list of files and subdirectories that must be created by the workflow platform in the designated output directory prior to executing the command line tool.
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#InitialWorkDirRequirement"
+
     def __init__(
         self,
         listing: Any,
@@ -17231,12 +17399,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "InitialWorkDirRequirement":
-            raise ValidationException("tried `InitialWorkDirRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_InitialWorkDirRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("listing") is None:
                 raise ValidationException("missing required field `listing`", None, [])
@@ -17327,8 +17504,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "InitialWorkDirRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.listing is not None:
             r["listing"] = save(
                 self.listing, top=False, base_url=base_url, relative_uris=relative_uris
@@ -17352,6 +17530,8 @@ class EnvVarRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#EnvVarRequirement"
+
     def __init__(
         self,
         envDef: Any,
@@ -17391,12 +17571,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "EnvVarRequirement":
-            raise ValidationException("tried `EnvVarRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_EnvVarRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("envDef") is None:
                 raise ValidationException("missing required field `envDef`", None, [])
@@ -17487,8 +17676,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "EnvVarRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.envDef is not None:
             r["envDef"] = save(
                 self.envDef, top=False, base_url=base_url, relative_uris=relative_uris
@@ -17517,6 +17707,8 @@ class ShellCommandRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ShellCommandRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -17554,12 +17746,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ShellCommandRequirement":
-            raise ValidationException("tried `ShellCommandRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ShellCommandRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -17599,8 +17800,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ShellCommandRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -17638,6 +17840,8 @@ class ResourceRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ResourceRequirement"
+
     def __init__(
         self,
         coresMin: Optional[Any] = None,
@@ -17713,12 +17917,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ResourceRequirement":
-            raise ValidationException("tried `ResourceRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ResourceRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         coresMin = None
         if "coresMin" in _doc:
             try:
@@ -18144,8 +18357,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ResourceRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.coresMin is not None:
             r["coresMin"] = save(
                 self.coresMin, top=False, base_url=base_url, relative_uris=relative_uris
@@ -18228,6 +18442,8 @@ class WorkReuse(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkReuse"
+
     def __init__(
         self,
         enableReuse: Any,
@@ -18269,12 +18485,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "WorkReuse":
-            raise ValidationException("tried `WorkReuse` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_WorkReuse_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("enableReuse") is None:
                 raise ValidationException("missing required field `enableReuse`", None, [])
@@ -18365,8 +18590,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "WorkReuse"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.enableReuse is not None:
             r["enableReuse"] = save(
                 self.enableReuse,
@@ -18406,6 +18632,8 @@ class NetworkAccess(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#NetworkAccess"
+
     def __init__(
         self,
         networkAccess: Any,
@@ -18448,12 +18676,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "NetworkAccess":
-            raise ValidationException("tried `NetworkAccess` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_NetworkAccess_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("networkAccess") is None:
                 raise ValidationException("missing required field `networkAccess`", None, [])
@@ -18544,8 +18781,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "NetworkAccess"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.networkAccess is not None:
             r["networkAccess"] = save(
                 self.networkAccess,
@@ -18600,6 +18838,8 @@ class InplaceUpdateRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#InplaceUpdateRequirement"
+
     def __init__(
         self,
         inplaceUpdate: Any,
@@ -18642,12 +18882,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "InplaceUpdateRequirement":
-            raise ValidationException("tried `InplaceUpdateRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_InplaceUpdateRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("inplaceUpdate") is None:
                 raise ValidationException("missing required field `inplaceUpdate`", None, [])
@@ -18738,8 +18987,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "InplaceUpdateRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.inplaceUpdate is not None:
             r["inplaceUpdate"] = save(
                 self.inplaceUpdate,
@@ -18771,6 +19021,8 @@ class ToolTimeLimit(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ToolTimeLimit"
+
     def __init__(
         self,
         timelimit: Any,
@@ -18812,12 +19064,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ToolTimeLimit":
-            raise ValidationException("tried `ToolTimeLimit` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ToolTimeLimit_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("timelimit") is None:
                 raise ValidationException("missing required field `timelimit`", None, [])
@@ -18908,8 +19169,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ToolTimeLimit"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.timelimit is not None:
             r["timelimit"] = save(
                 self.timelimit,
@@ -18930,6 +19192,8 @@ def save(
 
 
 class ExpressionToolOutputParameter(OutputParameter):
+    class_uri = "https://w3id.org/cwl/cwl#ExpressionToolOutputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -19433,6 +19697,8 @@ def save(
 
 
 class WorkflowInputParameter(InputParameter):
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowInputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -20192,6 +20458,8 @@ class ExpressionTool(Process):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ExpressionTool"
+
     def __init__(
         self,
         inputs: Any,
@@ -20271,12 +20539,6 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
-
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ExpressionTool":
-            raise ValidationException("tried `ExpressionTool` but")
-
         id = None
         if "id" in _doc:
             try:
@@ -20333,6 +20595,21 @@ def fromDoc(
                 id = "_:" + str(_uuid__.uuid4())
         if not __original_id_is_none:
             baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ExpressionTool_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         label = None
         if "label" in _doc:
             try:
@@ -20528,7 +20805,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -20575,7 +20852,7 @@ def fromDoc(
             try:
                 hints = load_field(
                     _doc.get("hints"),
-                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("hints")
@@ -20763,11 +21040,12 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ExpressionTool"
         if self.id is not None:
             u = save_relative_uri(self.id, base_url, True, None, relative_uris)
             r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
         if self.label is not None:
             r["label"] = save(
                 self.label, top=False, base_url=self.id, relative_uris=relative_uris
@@ -20839,6 +21117,8 @@ class WorkflowOutputParameter(OutputParameter):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowOutputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -21514,6 +21794,8 @@ class WorkflowStepInput(Identified, Sink, LoadContents, Labeled):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowStepInput"
+
     def __init__(
         self,
         id: Optional[Any] = None,
@@ -22093,6 +22375,8 @@ class WorkflowStepOutput(Identified):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowStepOutput"
+
     def __init__(
         self,
         id: Optional[Any] = None,
@@ -22303,6 +22587,8 @@ class WorkflowStep(Identified, Labeled, Documented):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowStep"
+
     def __init__(
         self,
         in_: Any,
@@ -22634,7 +22920,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -22731,7 +23017,7 @@ def fromDoc(
 
             run = load_field(
                 _doc.get("run"),
-                uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_False_False_None_None,
+                uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_False_False_None_None,
                 subscope_baseuri,
                 loadingOptions,
                 lc=_doc.get("run")
@@ -23034,6 +23320,8 @@ class Workflow(Process):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#Workflow"
+
     def __init__(
         self,
         inputs: Any,
@@ -23113,12 +23401,6 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
-
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "Workflow":
-            raise ValidationException("tried `Workflow` but")
-
         id = None
         if "id" in _doc:
             try:
@@ -23175,6 +23457,21 @@ def fromDoc(
                 id = "_:" + str(_uuid__.uuid4())
         if not __original_id_is_none:
             baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_Workflow_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         label = None
         if "label" in _doc:
             try:
@@ -23370,7 +23667,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -23417,7 +23714,7 @@ def fromDoc(
             try:
                 hints = load_field(
                     _doc.get("hints"),
-                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("hints")
@@ -23605,11 +23902,12 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "Workflow"
         if self.id is not None:
             u = save_relative_uri(self.id, base_url, True, None, relative_uris)
             r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
         if self.label is not None:
             r["label"] = save(
                 self.label, top=False, base_url=self.id, relative_uris=relative_uris
@@ -23676,6 +23974,8 @@ class SubworkflowFeatureRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#SubworkflowFeatureRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -23713,12 +24013,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "SubworkflowFeatureRequirement":
-            raise ValidationException("tried `SubworkflowFeatureRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_SubworkflowFeatureRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -23758,8 +24067,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "SubworkflowFeatureRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -23779,6 +24089,8 @@ class ScatterFeatureRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ScatterFeatureRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -23816,12 +24128,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ScatterFeatureRequirement":
-            raise ValidationException("tried `ScatterFeatureRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ScatterFeatureRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -23861,8 +24182,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ScatterFeatureRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -23882,6 +24204,8 @@ class MultipleInputFeatureRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#MultipleInputFeatureRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -23919,12 +24243,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "MultipleInputFeatureRequirement":
-            raise ValidationException("tried `MultipleInputFeatureRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_MultipleInputFeatureRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -23964,8 +24297,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "MultipleInputFeatureRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -23985,6 +24319,8 @@ class StepInputExpressionRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#StepInputExpressionRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -24022,12 +24358,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "StepInputExpressionRequirement":
-            raise ValidationException("tried `StepInputExpressionRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_StepInputExpressionRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -24067,8 +24412,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "StepInputExpressionRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -24081,39 +24427,1564 @@ def save(
     attrs = frozenset(["class"])
 
 
-_vocab = {
-    "Any": "https://w3id.org/cwl/salad#Any",
-    "ArraySchema": "https://w3id.org/cwl/salad#ArraySchema",
-    "CWLArraySchema": "https://w3id.org/cwl/cwl#CWLArraySchema",
-    "CWLInputFile": "https://w3id.org/cwl/cwl#CWLInputFile",
-    "CWLObjectType": "https://w3id.org/cwl/cwl#CWLObjectType",
-    "CWLRecordField": "https://w3id.org/cwl/cwl#CWLRecordField",
-    "CWLRecordSchema": "https://w3id.org/cwl/cwl#CWLRecordSchema",
-    "CWLType": "https://w3id.org/cwl/cwl#CWLType",
-    "CWLVersion": "https://w3id.org/cwl/cwl#CWLVersion",
-    "CommandInputArraySchema": "https://w3id.org/cwl/cwl#CommandInputArraySchema",
-    "CommandInputEnumSchema": "https://w3id.org/cwl/cwl#CommandInputEnumSchema",
-    "CommandInputParameter": "https://w3id.org/cwl/cwl#CommandInputParameter",
-    "CommandInputRecordField": "https://w3id.org/cwl/cwl#CommandInputRecordField",
-    "CommandInputRecordSchema": "https://w3id.org/cwl/cwl#CommandInputRecordSchema",
-    "CommandInputSchema": "https://w3id.org/cwl/cwl#CommandInputSchema",
-    "CommandLineBindable": "https://w3id.org/cwl/cwl#CommandLineBindable",
-    "CommandLineBinding": "https://w3id.org/cwl/cwl#CommandLineBinding",
-    "CommandLineTool": "https://w3id.org/cwl/cwl#CommandLineTool",
-    "CommandOutputArraySchema": "https://w3id.org/cwl/cwl#CommandOutputArraySchema",
-    "CommandOutputBinding": "https://w3id.org/cwl/cwl#CommandOutputBinding",
-    "CommandOutputEnumSchema": "https://w3id.org/cwl/cwl#CommandOutputEnumSchema",
-    "CommandOutputParameter": "https://w3id.org/cwl/cwl#CommandOutputParameter",
-    "CommandOutputRecordField": "https://w3id.org/cwl/cwl#CommandOutputRecordField",
-    "CommandOutputRecordSchema": "https://w3id.org/cwl/cwl#CommandOutputRecordSchema",
-    "Directory": "https://w3id.org/cwl/cwl#Directory",
-    "Dirent": "https://w3id.org/cwl/cwl#Dirent",
-    "DockerRequirement": "https://w3id.org/cwl/cwl#DockerRequirement",
-    "Documented": "https://w3id.org/cwl/salad#Documented",
-    "EnumSchema": "https://w3id.org/cwl/salad#EnumSchema",
-    "EnvVarRequirement": "https://w3id.org/cwl/cwl#EnvVarRequirement",
-    "EnvironmentDef": "https://w3id.org/cwl/cwl#EnvironmentDef",
-    "Expression": "https://w3id.org/cwl/cwl#Expression",
+class Secrets(ProcessRequirement):
+    class_uri = "http://commonwl.org/cwltool#Secrets"
+
+    def __init__(
+        self,
+        secrets: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "Secrets"
+        self.secrets = secrets
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, Secrets):
+            return bool(self.class_ == other.class_ and self.secrets == other.secrets)
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.secrets))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "Secrets":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("secrets") is None:
+                raise ValidationException("missing required field `secrets`", None, [])
+
+            secrets = load_field(
+                _doc.get("secrets"),
+                uri_array_of_strtype_False_False_0_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("secrets")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `secrets`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("secrets")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `secrets` field is not valid because:",
+                            SourceLine(_doc, "secrets", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `secrets` field is not valid because:",
+                            SourceLine(_doc, "secrets", str),
+                            [e],
+                            detailed_message=f"the `secrets` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `secrets`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            secrets=secrets,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.secrets is not None:
+            u = save_relative_uri(self.secrets, base_url, False, 0, relative_uris)
+            r["secrets"] = u
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "secrets"])
+
+
+class ProcessGenerator(Process):
+    class_uri = "http://commonwl.org/cwltool#ProcessGenerator"
+
+    def __init__(
+        self,
+        inputs: Any,
+        outputs: Any,
+        run: Any,
+        id: Optional[Any] = None,
+        label: Optional[Any] = None,
+        doc: Optional[Any] = None,
+        requirements: Optional[Any] = None,
+        hints: Optional[Any] = None,
+        cwlVersion: Optional[Any] = None,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.id = id
+        self.label = label
+        self.doc = doc
+        self.inputs = inputs
+        self.outputs = outputs
+        self.requirements = requirements
+        self.hints = hints
+        self.cwlVersion = cwlVersion
+        self.class_ = "ProcessGenerator"
+        self.run = run
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, ProcessGenerator):
+            return bool(
+                self.id == other.id
+                and self.label == other.label
+                and self.doc == other.doc
+                and self.inputs == other.inputs
+                and self.outputs == other.outputs
+                and self.requirements == other.requirements
+                and self.hints == other.hints
+                and self.cwlVersion == other.cwlVersion
+                and self.class_ == other.class_
+                and self.run == other.run
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash(
+            (
+                self.id,
+                self.label,
+                self.doc,
+                self.inputs,
+                self.outputs,
+                self.requirements,
+                self.hints,
+                self.cwlVersion,
+                self.class_,
+                self.run,
+            )
+        )
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "ProcessGenerator":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        id = None
+        if "id" in _doc:
+            try:
+                id = load_field(
+                    _doc.get("id"),
+                    uri_union_of_None_type_or_strtype_True_False_None_None,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("id")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `id`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("id")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `id` field is not valid because:",
+                                SourceLine(_doc, "id", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `id` field is not valid because:",
+                                SourceLine(_doc, "id", str),
+                                [e],
+                                detailed_message=f"the `id` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+
+        __original_id_is_none = id is None
+        if id is None:
+            if docRoot is not None:
+                id = docRoot
+            else:
+                id = "_:" + str(_uuid__.uuid4())
+        if not __original_id_is_none:
+            baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        label = None
+        if "label" in _doc:
+            try:
+                label = load_field(
+                    _doc.get("label"),
+                    union_of_None_type_or_strtype,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("label")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `label`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("label")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `label` field is not valid because:",
+                                SourceLine(_doc, "label", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `label` field is not valid because:",
+                                SourceLine(_doc, "label", str),
+                                [e],
+                                detailed_message=f"the `label` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        doc = None
+        if "doc" in _doc:
+            try:
+                doc = load_field(
+                    _doc.get("doc"),
+                    union_of_None_type_or_strtype_or_array_of_strtype,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("doc")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `doc`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("doc")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `doc` field is not valid because:",
+                                SourceLine(_doc, "doc", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `doc` field is not valid because:",
+                                SourceLine(_doc, "doc", str),
+                                [e],
+                                detailed_message=f"the `doc` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        try:
+            if _doc.get("inputs") is None:
+                raise ValidationException("missing required field `inputs`", None, [])
+
+            inputs = load_field(
+                _doc.get("inputs"),
+                idmap_inputs_array_of_union_of_CommandInputParameterLoader_or_WorkflowInputParameterLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("inputs")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `inputs`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("inputs")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `inputs` field is not valid because:",
+                            SourceLine(_doc, "inputs", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `inputs` field is not valid because:",
+                            SourceLine(_doc, "inputs", str),
+                            [e],
+                            detailed_message=f"the `inputs` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        try:
+            if _doc.get("outputs") is None:
+                raise ValidationException("missing required field `outputs`", None, [])
+
+            outputs = load_field(
+                _doc.get("outputs"),
+                idmap_outputs_array_of_union_of_CommandOutputParameterLoader_or_ExpressionToolOutputParameterLoader_or_WorkflowOutputParameterLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("outputs")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `outputs`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("outputs")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `outputs` field is not valid because:",
+                            SourceLine(_doc, "outputs", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `outputs` field is not valid because:",
+                            SourceLine(_doc, "outputs", str),
+                            [e],
+                            detailed_message=f"the `outputs` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        requirements = None
+        if "requirements" in _doc:
+            try:
+                requirements = load_field(
+                    _doc.get("requirements"),
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("requirements")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `requirements`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("requirements")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `requirements` field is not valid because:",
+                                SourceLine(_doc, "requirements", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `requirements` field is not valid because:",
+                                SourceLine(_doc, "requirements", str),
+                                [e],
+                                detailed_message=f"the `requirements` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        hints = None
+        if "hints" in _doc:
+            try:
+                hints = load_field(
+                    _doc.get("hints"),
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("hints")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `hints`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("hints")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `hints` field is not valid because:",
+                                SourceLine(_doc, "hints", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `hints` field is not valid because:",
+                                SourceLine(_doc, "hints", str),
+                                [e],
+                                detailed_message=f"the `hints` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        cwlVersion = None
+        if "cwlVersion" in _doc:
+            try:
+                cwlVersion = load_field(
+                    _doc.get("cwlVersion"),
+                    uri_union_of_None_type_or_CWLVersionLoader_False_True_None_None,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("cwlVersion")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `cwlVersion`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("cwlVersion")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `cwlVersion` field is not valid because:",
+                                SourceLine(_doc, "cwlVersion", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `cwlVersion` field is not valid because:",
+                                SourceLine(_doc, "cwlVersion", str),
+                                [e],
+                                detailed_message=f"the `cwlVersion` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+
+        subscope_baseuri = expand_url('run', baseuri, loadingOptions, True)
+        try:
+            if _doc.get("run") is None:
+                raise ValidationException("missing required field `run`", None, [])
+
+            run = load_field(
+                _doc.get("run"),
+                uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_False_False_None_None,
+                subscope_baseuri,
+                loadingOptions,
+                lc=_doc.get("run")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `run`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("run")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `run` field is not valid because:",
+                            SourceLine(_doc, "run", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `run` field is not valid because:",
+                            SourceLine(_doc, "run", str),
+                            [e],
+                            detailed_message=f"the `run` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `id`, `label`, `doc`, `inputs`, `outputs`, `requirements`, `hints`, `cwlVersion`, `class`, `run`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            id=id,
+            label=label,
+            doc=doc,
+            inputs=inputs,
+            outputs=outputs,
+            requirements=requirements,
+            hints=hints,
+            cwlVersion=cwlVersion,
+            run=run,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        loadingOptions.idx[cast(str, id)] = (_constructed, loadingOptions)
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.id is not None:
+            u = save_relative_uri(self.id, base_url, True, None, relative_uris)
+            r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
+        if self.label is not None:
+            r["label"] = save(
+                self.label, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.doc is not None:
+            r["doc"] = save(
+                self.doc, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.inputs is not None:
+            r["inputs"] = save(
+                self.inputs, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.outputs is not None:
+            r["outputs"] = save(
+                self.outputs, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.requirements is not None:
+            r["requirements"] = save(
+                self.requirements,
+                top=False,
+                base_url=self.id,
+                relative_uris=relative_uris,
+            )
+        if self.hints is not None:
+            r["hints"] = save(
+                self.hints, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.cwlVersion is not None:
+            u = save_relative_uri(self.cwlVersion, self.id, False, None, relative_uris)
+            r["cwlVersion"] = u
+        if self.run is not None:
+            u = save_relative_uri(self.run, self.id, False, None, relative_uris)
+            r["run"] = u
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(
+        [
+            "id",
+            "label",
+            "doc",
+            "inputs",
+            "outputs",
+            "requirements",
+            "hints",
+            "cwlVersion",
+            "class",
+            "run",
+        ]
+    )
+
+
+class MPIRequirement(ProcessRequirement):
+    """
+    Indicates that a process requires an MPI runtime.
+
+    """
+
+    class_uri = "http://commonwl.org/cwltool#MPIRequirement"
+
+    def __init__(
+        self,
+        processes: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "MPIRequirement"
+        self.processes = processes
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, MPIRequirement):
+            return bool(
+                self.class_ == other.class_ and self.processes == other.processes
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.processes))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "MPIRequirement":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("processes") is None:
+                raise ValidationException("missing required field `processes`", None, [])
+
+            processes = load_field(
+                _doc.get("processes"),
+                union_of_inttype_or_ExpressionLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("processes")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `processes`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("processes")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `processes` field is not valid because:",
+                            SourceLine(_doc, "processes", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `processes` field is not valid because:",
+                            SourceLine(_doc, "processes", str),
+                            [e],
+                            detailed_message=f"the `processes` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `processes`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            processes=processes,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.processes is not None:
+            r["processes"] = save(
+                self.processes,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "processes"])
+
+
+class CUDARequirement(ProcessRequirement):
+    """
+    Require support for NVIDA CUDA (GPU hardware acceleration).
+
+    """
+
+    class_uri = "http://commonwl.org/cwltool#CUDARequirement"
+
+    def __init__(
+        self,
+        cudaComputeCapability: Any,
+        cudaVersionMin: Any,
+        cudaDeviceCountMax: Optional[Any] = None,
+        cudaDeviceCountMin: Optional[Any] = None,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "CUDARequirement"
+        self.cudaComputeCapability = cudaComputeCapability
+        self.cudaDeviceCountMax = cudaDeviceCountMax
+        self.cudaDeviceCountMin = cudaDeviceCountMin
+        self.cudaVersionMin = cudaVersionMin
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, CUDARequirement):
+            return bool(
+                self.class_ == other.class_
+                and self.cudaComputeCapability == other.cudaComputeCapability
+                and self.cudaDeviceCountMax == other.cudaDeviceCountMax
+                and self.cudaDeviceCountMin == other.cudaDeviceCountMin
+                and self.cudaVersionMin == other.cudaVersionMin
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash(
+            (
+                self.class_,
+                self.cudaComputeCapability,
+                self.cudaDeviceCountMax,
+                self.cudaDeviceCountMin,
+                self.cudaVersionMin,
+            )
+        )
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "CUDARequirement":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("cudaComputeCapability") is None:
+                raise ValidationException("missing required field `cudaComputeCapability`", None, [])
+
+            cudaComputeCapability = load_field(
+                _doc.get("cudaComputeCapability"),
+                union_of_strtype_or_array_of_strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("cudaComputeCapability")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `cudaComputeCapability`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("cudaComputeCapability")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaComputeCapability` field is not valid because:",
+                            SourceLine(_doc, "cudaComputeCapability", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaComputeCapability` field is not valid because:",
+                            SourceLine(_doc, "cudaComputeCapability", str),
+                            [e],
+                            detailed_message=f"the `cudaComputeCapability` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        cudaDeviceCountMax = None
+        if "cudaDeviceCountMax" in _doc:
+            try:
+                cudaDeviceCountMax = load_field(
+                    _doc.get("cudaDeviceCountMax"),
+                    union_of_None_type_or_inttype_or_ExpressionLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("cudaDeviceCountMax")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `cudaDeviceCountMax`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("cudaDeviceCountMax")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMax` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMax", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMax` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMax", str),
+                                [e],
+                                detailed_message=f"the `cudaDeviceCountMax` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        cudaDeviceCountMin = None
+        if "cudaDeviceCountMin" in _doc:
+            try:
+                cudaDeviceCountMin = load_field(
+                    _doc.get("cudaDeviceCountMin"),
+                    union_of_None_type_or_inttype_or_ExpressionLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("cudaDeviceCountMin")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `cudaDeviceCountMin`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("cudaDeviceCountMin")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMin` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMin", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMin` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMin", str),
+                                [e],
+                                detailed_message=f"the `cudaDeviceCountMin` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        try:
+            if _doc.get("cudaVersionMin") is None:
+                raise ValidationException("missing required field `cudaVersionMin`", None, [])
+
+            cudaVersionMin = load_field(
+                _doc.get("cudaVersionMin"),
+                strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("cudaVersionMin")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `cudaVersionMin`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("cudaVersionMin")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaVersionMin` field is not valid because:",
+                            SourceLine(_doc, "cudaVersionMin", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaVersionMin` field is not valid because:",
+                            SourceLine(_doc, "cudaVersionMin", str),
+                            [e],
+                            detailed_message=f"the `cudaVersionMin` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `cudaComputeCapability`, `cudaDeviceCountMax`, `cudaDeviceCountMin`, `cudaVersionMin`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            cudaComputeCapability=cudaComputeCapability,
+            cudaDeviceCountMax=cudaDeviceCountMax,
+            cudaDeviceCountMin=cudaDeviceCountMin,
+            cudaVersionMin=cudaVersionMin,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.cudaComputeCapability is not None:
+            r["cudaComputeCapability"] = save(
+                self.cudaComputeCapability,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+        if self.cudaDeviceCountMax is not None:
+            r["cudaDeviceCountMax"] = save(
+                self.cudaDeviceCountMax,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+        if self.cudaDeviceCountMin is not None:
+            r["cudaDeviceCountMin"] = save(
+                self.cudaDeviceCountMin,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+        if self.cudaVersionMin is not None:
+            r["cudaVersionMin"] = save(
+                self.cudaVersionMin,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(
+        [
+            "class",
+            "cudaComputeCapability",
+            "cudaDeviceCountMax",
+            "cudaDeviceCountMin",
+            "cudaVersionMin",
+        ]
+    )
+
+
+class ShmSize(ProcessRequirement):
+    class_uri = "http://commonwl.org/cwltool#ShmSize"
+
+    def __init__(
+        self,
+        shmSize: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "ShmSize"
+        self.shmSize = shmSize
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, ShmSize):
+            return bool(self.class_ == other.class_ and self.shmSize == other.shmSize)
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.shmSize))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "ShmSize":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("shmSize") is None:
+                raise ValidationException("missing required field `shmSize`", None, [])
+
+            shmSize = load_field(
+                _doc.get("shmSize"),
+                strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("shmSize")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `shmSize`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("shmSize")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `shmSize` field is not valid because:",
+                            SourceLine(_doc, "shmSize", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `shmSize` field is not valid because:",
+                            SourceLine(_doc, "shmSize", str),
+                            [e],
+                            detailed_message=f"the `shmSize` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `shmSize`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            shmSize=shmSize,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.shmSize is not None:
+            r["shmSize"] = save(
+                self.shmSize, top=False, base_url=base_url, relative_uris=relative_uris
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "shmSize"])
+
+
+_vocab = {
+    "Any": "https://w3id.org/cwl/salad#Any",
+    "ArraySchema": "https://w3id.org/cwl/salad#ArraySchema",
+    "CUDARequirement": "http://commonwl.org/cwltool#CUDARequirement",
+    "CWLArraySchema": "https://w3id.org/cwl/cwl#CWLArraySchema",
+    "CWLInputFile": "https://w3id.org/cwl/cwl#CWLInputFile",
+    "CWLObjectType": "https://w3id.org/cwl/cwl#CWLObjectType",
+    "CWLRecordField": "https://w3id.org/cwl/cwl#CWLRecordField",
+    "CWLRecordSchema": "https://w3id.org/cwl/cwl#CWLRecordSchema",
+    "CWLType": "https://w3id.org/cwl/cwl#CWLType",
+    "CWLVersion": "https://w3id.org/cwl/cwl#CWLVersion",
+    "CommandInputArraySchema": "https://w3id.org/cwl/cwl#CommandInputArraySchema",
+    "CommandInputEnumSchema": "https://w3id.org/cwl/cwl#CommandInputEnumSchema",
+    "CommandInputParameter": "https://w3id.org/cwl/cwl#CommandInputParameter",
+    "CommandInputRecordField": "https://w3id.org/cwl/cwl#CommandInputRecordField",
+    "CommandInputRecordSchema": "https://w3id.org/cwl/cwl#CommandInputRecordSchema",
+    "CommandInputSchema": "https://w3id.org/cwl/cwl#CommandInputSchema",
+    "CommandLineBindable": "https://w3id.org/cwl/cwl#CommandLineBindable",
+    "CommandLineBinding": "https://w3id.org/cwl/cwl#CommandLineBinding",
+    "CommandLineTool": "https://w3id.org/cwl/cwl#CommandLineTool",
+    "CommandOutputArraySchema": "https://w3id.org/cwl/cwl#CommandOutputArraySchema",
+    "CommandOutputBinding": "https://w3id.org/cwl/cwl#CommandOutputBinding",
+    "CommandOutputEnumSchema": "https://w3id.org/cwl/cwl#CommandOutputEnumSchema",
+    "CommandOutputParameter": "https://w3id.org/cwl/cwl#CommandOutputParameter",
+    "CommandOutputRecordField": "https://w3id.org/cwl/cwl#CommandOutputRecordField",
+    "CommandOutputRecordSchema": "https://w3id.org/cwl/cwl#CommandOutputRecordSchema",
+    "Directory": "https://w3id.org/cwl/cwl#Directory",
+    "Dirent": "https://w3id.org/cwl/cwl#Dirent",
+    "DockerRequirement": "https://w3id.org/cwl/cwl#DockerRequirement",
+    "Documented": "https://w3id.org/cwl/salad#Documented",
+    "EnumSchema": "https://w3id.org/cwl/salad#EnumSchema",
+    "EnvVarRequirement": "https://w3id.org/cwl/cwl#EnvVarRequirement",
+    "EnvironmentDef": "https://w3id.org/cwl/cwl#EnvironmentDef",
+    "Expression": "https://w3id.org/cwl/cwl#Expression",
     "ExpressionPlaceholder": "https://w3id.org/cwl/cwl#ExpressionPlaceholder",
     "ExpressionTool": "https://w3id.org/cwl/cwl#ExpressionTool",
     "ExpressionToolOutputParameter": "https://w3id.org/cwl/cwl#ExpressionToolOutputParameter",
@@ -24137,6 +26008,7 @@ def save(
     "LoadContents": "https://w3id.org/cwl/cwl#LoadContents",
     "LoadListingEnum": "https://w3id.org/cwl/cwl#LoadListingEnum",
     "LoadListingRequirement": "https://w3id.org/cwl/cwl#LoadListingRequirement",
+    "MPIRequirement": "http://commonwl.org/cwltool#MPIRequirement",
     "MapSchema": "https://w3id.org/cwl/salad#MapSchema",
     "MultipleInputFeatureRequirement": "https://w3id.org/cwl/cwl#MultipleInputFeatureRequirement",
     "NetworkAccess": "https://w3id.org/cwl/cwl#NetworkAccess",
@@ -24150,6 +26022,7 @@ def save(
     "Parameter": "https://w3id.org/cwl/cwl#Parameter",
     "PrimitiveType": "https://w3id.org/cwl/salad#PrimitiveType",
     "Process": "https://w3id.org/cwl/cwl#Process",
+    "ProcessGenerator": "http://commonwl.org/cwltool#ProcessGenerator",
     "ProcessRequirement": "https://w3id.org/cwl/cwl#ProcessRequirement",
     "RecordField": "https://w3id.org/cwl/salad#RecordField",
     "RecordSchema": "https://w3id.org/cwl/salad#RecordSchema",
@@ -24158,7 +26031,9 @@ def save(
     "ScatterMethod": "https://w3id.org/cwl/cwl#ScatterMethod",
     "SchemaDefRequirement": "https://w3id.org/cwl/cwl#SchemaDefRequirement",
     "SecondaryFileSchema": "https://w3id.org/cwl/cwl#SecondaryFileSchema",
+    "Secrets": "http://commonwl.org/cwltool#Secrets",
     "ShellCommandRequirement": "https://w3id.org/cwl/cwl#ShellCommandRequirement",
+    "ShmSize": "http://commonwl.org/cwltool#ShmSize",
     "Sink": "https://w3id.org/cwl/cwl#Sink",
     "SoftwarePackage": "https://w3id.org/cwl/cwl#SoftwarePackage",
     "SoftwareRequirement": "https://w3id.org/cwl/cwl#SoftwareRequirement",
@@ -24214,6 +26089,7 @@ def save(
 _rvocab = {
     "https://w3id.org/cwl/salad#Any": "Any",
     "https://w3id.org/cwl/salad#ArraySchema": "ArraySchema",
+    "http://commonwl.org/cwltool#CUDARequirement": "CUDARequirement",
     "https://w3id.org/cwl/cwl#CWLArraySchema": "CWLArraySchema",
     "https://w3id.org/cwl/cwl#CWLInputFile": "CWLInputFile",
     "https://w3id.org/cwl/cwl#CWLObjectType": "CWLObjectType",
@@ -24267,6 +26143,7 @@ def save(
     "https://w3id.org/cwl/cwl#LoadContents": "LoadContents",
     "https://w3id.org/cwl/cwl#LoadListingEnum": "LoadListingEnum",
     "https://w3id.org/cwl/cwl#LoadListingRequirement": "LoadListingRequirement",
+    "http://commonwl.org/cwltool#MPIRequirement": "MPIRequirement",
     "https://w3id.org/cwl/salad#MapSchema": "MapSchema",
     "https://w3id.org/cwl/cwl#MultipleInputFeatureRequirement": "MultipleInputFeatureRequirement",
     "https://w3id.org/cwl/cwl#NetworkAccess": "NetworkAccess",
@@ -24280,6 +26157,7 @@ def save(
     "https://w3id.org/cwl/cwl#Parameter": "Parameter",
     "https://w3id.org/cwl/salad#PrimitiveType": "PrimitiveType",
     "https://w3id.org/cwl/cwl#Process": "Process",
+    "http://commonwl.org/cwltool#ProcessGenerator": "ProcessGenerator",
     "https://w3id.org/cwl/cwl#ProcessRequirement": "ProcessRequirement",
     "https://w3id.org/cwl/salad#RecordField": "RecordField",
     "https://w3id.org/cwl/salad#RecordSchema": "RecordSchema",
@@ -24288,7 +26166,9 @@ def save(
     "https://w3id.org/cwl/cwl#ScatterMethod": "ScatterMethod",
     "https://w3id.org/cwl/cwl#SchemaDefRequirement": "SchemaDefRequirement",
     "https://w3id.org/cwl/cwl#SecondaryFileSchema": "SecondaryFileSchema",
+    "http://commonwl.org/cwltool#Secrets": "Secrets",
     "https://w3id.org/cwl/cwl#ShellCommandRequirement": "ShellCommandRequirement",
+    "http://commonwl.org/cwltool#ShmSize": "ShmSize",
     "https://w3id.org/cwl/cwl#Sink": "Sink",
     "https://w3id.org/cwl/cwl#SoftwarePackage": "SoftwarePackage",
     "https://w3id.org/cwl/cwl#SoftwareRequirement": "SoftwareRequirement",
@@ -24446,7 +26326,11 @@ def save(
 StepInputExpressionRequirementLoader = _RecordLoader(
     StepInputExpressionRequirement, None, None
 )
-union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _UnionLoader(
+SecretsLoader = _RecordLoader(Secrets, None, None)
+MPIRequirementLoader = _RecordLoader(MPIRequirement, None, None)
+CUDARequirementLoader = _RecordLoader(CUDARequirement, None, None)
+ShmSizeLoader = _RecordLoader(ShmSize, None, None)
+union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader = _UnionLoader(
     (
         InlineJavascriptRequirementLoader,
         SchemaDefRequirementLoader,
@@ -24465,25 +26349,29 @@ def save(
         ScatterFeatureRequirementLoader,
         MultipleInputFeatureRequirementLoader,
         StepInputExpressionRequirementLoader,
+        SecretsLoader,
+        MPIRequirementLoader,
+        CUDARequirementLoader,
+        ShmSizeLoader,
     )
 )
-array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _ArrayLoader(
-    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader
+array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader = _ArrayLoader(
+    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader
 )
-union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_CWLObjectTypeLoader = _UnionLoader(
+union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_CWLObjectTypeLoader = _UnionLoader(
     (
         None_type,
-        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
         CWLObjectTypeLoader,
     )
 )
-map_of_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_CWLObjectTypeLoader = _MapLoader(
-    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_CWLObjectTypeLoader,
+map_of_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_CWLObjectTypeLoader = _MapLoader(
+    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_CWLObjectTypeLoader,
     "CWLInputFile",
     "@list",
     True,
 )
-CWLInputFileLoader = map_of_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_CWLObjectTypeLoader
+CWLInputFileLoader = map_of_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_CWLObjectTypeLoader
 CWLVersionLoader = _EnumLoader(
     (
         "draft-2",
@@ -24691,6 +26579,7 @@ def save(
 """
 WorkflowStepLoader = _RecordLoader(WorkflowStep, None, None)
 WorkflowLoader = _RecordLoader(Workflow, None, None)
+ProcessGeneratorLoader = _RecordLoader(ProcessGenerator, None, None)
 array_of_strtype = _ArrayLoader(strtype)
 union_of_None_type_or_strtype_or_array_of_strtype = _UnionLoader(
     (
@@ -25027,18 +26916,18 @@ def save(
     "id",
     "type",
 )
-union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _UnionLoader(
+union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader = _UnionLoader(
     (
         None_type,
-        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
     )
 )
-idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _IdMapLoader(
-    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader = _IdMapLoader(
+    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader,
     "class",
     "None",
 )
-union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _UnionLoader(
+union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type = _UnionLoader(
     (
         InlineJavascriptRequirementLoader,
         SchemaDefRequirementLoader,
@@ -25057,20 +26946,24 @@ def save(
         ScatterFeatureRequirementLoader,
         MultipleInputFeatureRequirementLoader,
         StepInputExpressionRequirementLoader,
+        SecretsLoader,
+        MPIRequirementLoader,
+        CUDARequirementLoader,
+        ShmSizeLoader,
         Any_type,
     )
 )
-array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _ArrayLoader(
-    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type
+array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type = _ArrayLoader(
+    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type
 )
-union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _UnionLoader(
+union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type = _UnionLoader(
     (
         None_type,
-        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
     )
 )
-idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _IdMapLoader(
-    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type = _IdMapLoader(
+    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_ShmSizeLoader_or_Any_type,
     "class",
     "None",
 )
@@ -25484,18 +27377,17 @@ def save(
 idmap_hints_union_of_None_type_or_array_of_Any_type = _IdMapLoader(
     union_of_None_type_or_array_of_Any_type, "class", "None"
 )
-union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader = (
-    _UnionLoader(
-        (
-            strtype,
-            CommandLineToolLoader,
-            ExpressionToolLoader,
-            WorkflowLoader,
-        )
+union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader = _UnionLoader(
+    (
+        strtype,
+        CommandLineToolLoader,
+        ExpressionToolLoader,
+        WorkflowLoader,
+        ProcessGeneratorLoader,
     )
 )
-uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_False_False_None_None = _URILoader(
-    union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_False_False_None_None = _URILoader(
+    union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
     False,
     False,
     None,
@@ -25550,24 +27442,34 @@ def save(
 uri_StepInputExpressionRequirement_classLoader_False_True_None_None = _URILoader(
     StepInputExpressionRequirement_classLoader, False, True, None, None
 )
-union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader = _UnionLoader(
+uri_strtype_False_True_None_None = _URILoader(strtype, False, True, None, None)
+uri_array_of_strtype_False_False_0_None = _URILoader(
+    array_of_strtype, False, False, 0, None
+)
+union_of_strtype_or_array_of_strtype = _UnionLoader(
+    (
+        strtype,
+        array_of_strtype,
+    )
+)
+union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader = _UnionLoader(
     (
         CommandLineToolLoader,
         ExpressionToolLoader,
         WorkflowLoader,
+        ProcessGeneratorLoader,
     )
 )
-array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader = (
-    _ArrayLoader(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader
-    )
+array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader = _ArrayLoader(
+    union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader
 )
-union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader = _UnionLoader(
+union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader = _UnionLoader(
     (
         CommandLineToolLoader,
         ExpressionToolLoader,
         WorkflowLoader,
-        array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+        ProcessGeneratorLoader,
+        array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
     )
 )
 
@@ -25595,7 +27497,7 @@ def load_document(
     if loadingOptions is None:
         loadingOptions = LoadingOptions()
     result, metadata = _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
         doc,
         baseuri,
         loadingOptions,
@@ -25614,7 +27516,7 @@ def load_document_with_metadata(
     if loadingOptions is None:
         loadingOptions = LoadingOptions(fileuri=baseuri)
     return _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
         doc,
         baseuri,
         loadingOptions,
@@ -25635,7 +27537,7 @@ def load_document_by_string(
         loadingOptions = LoadingOptions(fileuri=uri)
 
     result, metadata = _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
         result,
         uri,
         loadingOptions,
@@ -25658,7 +27560,7 @@ def load_document_by_yaml(
         loadingOptions = LoadingOptions(fileuri=uri)
 
     result, metadata = _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_ProcessGeneratorLoader,
         yaml,
         uri,
         loadingOptions,
diff --git a/cwl_utils/parser/cwl_v1_1_utils.py b/cwl_utils/parser/cwl_v1_1_utils.py
index 7db4bfba..4bdf78e6 100644
--- a/cwl_utils/parser/cwl_v1_1_utils.py
+++ b/cwl_utils/parser/cwl_v1_1_utils.py
@@ -5,10 +5,9 @@
 from collections import namedtuple
 from collections.abc import MutableMapping, MutableSequence
 from io import StringIO
-from typing import IO, Any, Optional, Union, cast
+from typing import Any, IO, Optional, Union, cast
 from urllib.parse import urldefrag
 
-from ruamel import yaml
 from schema_salad.exceptions import ValidationException
 from schema_salad.sourceline import SourceLine, add_lc_filename
 from schema_salad.utils import aslist, json_dumps, yaml_no_ts
@@ -17,6 +16,7 @@
 import cwl_utils.parser.cwl_v1_1 as cwl
 import cwl_utils.parser.utils
 from cwl_utils.errors import WorkflowException
+from cwl_utils.utils import yaml_dumps
 
 CONTENT_LIMIT: int = 64 * 1024
 
@@ -434,7 +434,7 @@ def type_for_step_output(
     raise ValidationException(
         "param {} not found in {}.".format(
             sourcename,
-            yaml.main.round_trip_dump(cwl.save(step)),
+            yaml_dumps(cwl.save(step)),
         )
     )
 
@@ -568,11 +568,7 @@ def param_for_source_id(
     raise WorkflowException(
         "param {} not found in {}\n{}.".format(
             sourcename,
-            yaml.main.round_trip_dump(cwl.save(process)),
-            (
-                f" or\n {yaml.main.round_trip_dump(cwl.save(parent))}"
-                if parent is not None
-                else ""
-            ),
+            yaml_dumps(cwl.save(process)),
+            (f" or\n {yaml_dumps(cwl.save(parent))}" if parent is not None else ""),
         )
     )
diff --git a/cwl_utils/parser/cwl_v1_2.py b/cwl_utils/parser/cwl_v1_2.py
index 2f3c8abe..65d4dbb7 100644
--- a/cwl_utils/parser/cwl_v1_2.py
+++ b/cwl_utils/parser/cwl_v1_2.py
@@ -1162,6 +1162,8 @@ class RecordField(Documented):
     A field of a record.
     """
 
+    class_uri = "https://w3id.org/cwl/salad#RecordField"
+
     def __init__(
         self,
         name: Any,
@@ -1428,6 +1430,8 @@ def save(
 
 
 class RecordSchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#RecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -1632,6 +1636,8 @@ class EnumSchema(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/salad#EnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -1898,6 +1904,8 @@ def save(
 
 
 class ArraySchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#ArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -2097,6 +2105,8 @@ def save(
 
 
 class MapSchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#MapSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -2296,6 +2306,8 @@ def save(
 
 
 class UnionSchema(Saveable):
+    class_uri = "https://w3id.org/cwl/salad#UnionSchema"
+
     def __init__(
         self,
         names: Any,
@@ -2495,6 +2507,8 @@ def save(
 
 
 class CWLArraySchema(ArraySchema):
+    class_uri = "https://w3id.org/cwl/cwl#CWLArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -2694,6 +2708,8 @@ def save(
 
 
 class CWLRecordField(RecordField):
+    class_uri = "https://w3id.org/cwl/cwl#CWLRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -2960,6 +2976,8 @@ def save(
 
 
 class CWLRecordSchema(RecordSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CWLRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -3229,6 +3247,8 @@ class File(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#File"
+
     def __init__(
         self,
         location: Optional[Any] = None,
@@ -3316,12 +3336,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "File":
-            raise ValidationException("tried `File` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_File_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         location = None
         if "location" in _doc:
             try:
@@ -3891,8 +3920,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "File"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.location is not None:
             u = save_relative_uri(self.location, base_url, False, None, relative_uris)
             r["location"] = u
@@ -4012,6 +4042,8 @@ class Directory(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#Directory"
+
     def __init__(
         self,
         location: Optional[Any] = None,
@@ -4065,12 +4097,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "Directory":
-            raise ValidationException("tried `Directory` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_Directory_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         location = None
         if "location" in _doc:
             try:
@@ -4304,8 +4345,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "Directory"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.location is not None:
             u = save_relative_uri(self.location, base_url, False, None, relative_uris)
             r["location"] = u
@@ -4366,6 +4408,8 @@ class Parameter(FieldBase, Documented, Identified):
 
 
 class InputBinding(Saveable):
+    class_uri = "https://w3id.org/cwl/cwl#InputBinding"
+
     def __init__(
         self,
         loadContents: Optional[Any] = None,
@@ -4525,6 +4569,8 @@ class OutputSchema(IOSchema):
 
 
 class InputRecordField(CWLRecordField, FieldBase, InputFormat, LoadContents):
+    class_uri = "https://w3id.org/cwl/cwl#InputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -5156,6 +5202,8 @@ def save(
 
 
 class InputRecordSchema(CWLRecordSchema, InputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#InputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -5532,6 +5580,8 @@ def save(
 
 
 class InputEnumSchema(EnumSchema, InputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#InputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -5908,6 +5958,8 @@ def save(
 
 
 class InputArraySchema(CWLArraySchema, InputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#InputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -6284,6 +6336,8 @@ def save(
 
 
 class OutputRecordField(CWLRecordField, FieldBase, OutputFormat):
+    class_uri = "https://w3id.org/cwl/cwl#OutputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -6787,6 +6841,8 @@ def save(
 
 
 class OutputRecordSchema(CWLRecordSchema, OutputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#OutputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -7163,6 +7219,8 @@ def save(
 
 
 class OutputEnumSchema(EnumSchema, OutputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#OutputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -7539,6 +7597,8 @@ def save(
 
 
 class OutputArraySchema(CWLArraySchema, OutputSchema):
+    class_uri = "https://w3id.org/cwl/cwl#OutputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -7956,6 +8016,8 @@ class InlineJavascriptRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#InlineJavascriptRequirement"
+
     def __init__(
         self,
         expressionLib: Optional[Any] = None,
@@ -7998,12 +8060,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "InlineJavascriptRequirement":
-            raise ValidationException("tried `InlineJavascriptRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_InlineJavascriptRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         expressionLib = None
         if "expressionLib" in _doc:
             try:
@@ -8093,8 +8164,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "InlineJavascriptRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.expressionLib is not None:
             r["expressionLib"] = save(
                 self.expressionLib,
@@ -8135,6 +8207,8 @@ class SchemaDefRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#SchemaDefRequirement"
+
     def __init__(
         self,
         types: Any,
@@ -8174,12 +8248,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "SchemaDefRequirement":
-            raise ValidationException("tried `SchemaDefRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_SchemaDefRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("types") is None:
                 raise ValidationException("missing required field `types`", None, [])
@@ -8270,8 +8353,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "SchemaDefRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.types is not None:
             r["types"] = save(
                 self.types, top=False, base_url=base_url, relative_uris=relative_uris
@@ -8306,6 +8390,8 @@ class SecondaryFileSchema(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#SecondaryFileSchema"
+
     def __init__(
         self,
         pattern: Any,
@@ -8513,6 +8599,8 @@ class LoadListingRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#LoadListingRequirement"
+
     def __init__(
         self,
         loadListing: Optional[Any] = None,
@@ -8554,12 +8642,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "LoadListingRequirement":
-            raise ValidationException("tried `LoadListingRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_LoadListingRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         loadListing = None
         if "loadListing" in _doc:
             try:
@@ -8649,8 +8746,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "LoadListingRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.loadListing is not None:
             r["loadListing"] = save(
                 self.loadListing,
@@ -8678,6 +8776,8 @@ class EnvironmentDef(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#EnvironmentDef"
+
     def __init__(
         self,
         envName: Any,
@@ -8919,6 +9019,8 @@ class CommandLineBinding(InputBinding):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandLineBinding"
+
     def __init__(
         self,
         loadContents: Optional[Any] = None,
@@ -9441,6 +9543,8 @@ class CommandOutputBinding(LoadContents):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputBinding"
+
     def __init__(
         self,
         loadContents: Optional[Any] = None,
@@ -9761,6 +9865,8 @@ def save(
 
 
 class CommandLineBindable(Saveable):
+    class_uri = "https://w3id.org/cwl/cwl#CommandLineBindable"
+
     def __init__(
         self,
         inputBinding: Optional[Any] = None,
@@ -9908,6 +10014,8 @@ def save(
 
 
 class CommandInputRecordField(InputRecordField, CommandLineBindable):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -10601,6 +10709,8 @@ def save(
 class CommandInputRecordSchema(
     InputRecordSchema, CommandInputSchema, CommandLineBindable
 ):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -11044,6 +11154,8 @@ def save(
 
 
 class CommandInputEnumSchema(InputEnumSchema, CommandInputSchema, CommandLineBindable):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -11489,6 +11601,8 @@ def save(
 class CommandInputArraySchema(
     InputArraySchema, CommandInputSchema, CommandLineBindable
 ):
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -11925,6 +12039,8 @@ def save(
 
 
 class CommandOutputRecordField(OutputRecordField):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputRecordField"
+
     def __init__(
         self,
         name: Any,
@@ -12496,6 +12612,8 @@ def save(
 
 
 class CommandOutputRecordSchema(OutputRecordSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputRecordSchema"
+
     def __init__(
         self,
         type_: Any,
@@ -12872,6 +12990,8 @@ def save(
 
 
 class CommandOutputEnumSchema(OutputEnumSchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputEnumSchema"
+
     def __init__(
         self,
         symbols: Any,
@@ -13248,6 +13368,8 @@ def save(
 
 
 class CommandOutputArraySchema(OutputArraySchema):
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputArraySchema"
+
     def __init__(
         self,
         items: Any,
@@ -13628,6 +13750,8 @@ class CommandInputParameter(InputParameter):
     An input parameter for a CommandLineTool.
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandInputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -14380,6 +14504,8 @@ class CommandOutputParameter(OutputParameter):
     An output parameter for a CommandLineTool.
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandOutputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -14956,6 +15082,8 @@ class CommandLineTool(Process):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#CommandLineTool"
+
     def __init__(
         self,
         inputs: Any,
@@ -15067,12 +15195,6 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
-
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "CommandLineTool":
-            raise ValidationException("tried `CommandLineTool` but")
-
         id = None
         if "id" in _doc:
             try:
@@ -15129,6 +15251,21 @@ def fromDoc(
                 id = "_:" + str(_uuid__.uuid4())
         if not __original_id_is_none:
             baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_CommandLineTool_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         label = None
         if "label" in _doc:
             try:
@@ -15324,7 +15461,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -15371,7 +15508,7 @@ def fromDoc(
             try:
                 hints = load_field(
                     _doc.get("hints"),
-                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("hints")
@@ -15942,11 +16079,12 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "CommandLineTool"
         if self.id is not None:
             u = save_relative_uri(self.id, base_url, True, None, relative_uris)
             r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
         if self.label is not None:
             r["label"] = save(
                 self.label, top=False, base_url=self.id, relative_uris=relative_uris
@@ -16113,6 +16251,8 @@ class DockerRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#DockerRequirement"
+
     def __init__(
         self,
         dockerPull: Optional[Any] = None,
@@ -16180,12 +16320,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "DockerRequirement":
-            raise ValidationException("tried `DockerRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_DockerRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         dockerPull = None
         if "dockerPull" in _doc:
             try:
@@ -16515,8 +16664,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "DockerRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.dockerPull is not None:
             r["dockerPull"] = save(
                 self.dockerPull,
@@ -16588,6 +16738,8 @@ class SoftwareRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#SoftwareRequirement"
+
     def __init__(
         self,
         packages: Any,
@@ -16627,12 +16779,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "SoftwareRequirement":
-            raise ValidationException("tried `SoftwareRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_SoftwareRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("packages") is None:
                 raise ValidationException("missing required field `packages`", None, [])
@@ -16723,8 +16884,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "SoftwareRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.packages is not None:
             r["packages"] = save(
                 self.packages, top=False, base_url=base_url, relative_uris=relative_uris
@@ -16742,6 +16904,8 @@ def save(
 
 
 class SoftwarePackage(Saveable):
+    class_uri = "https://w3id.org/cwl/cwl#SoftwarePackage"
+
     def __init__(
         self,
         package: Any,
@@ -17010,6 +17174,8 @@ class Dirent(Saveable):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#Dirent"
+
     def __init__(
         self,
         entry: Any,
@@ -17275,6 +17441,8 @@ class InitialWorkDirRequirement(ProcessRequirement):
     Normally files are staged within the designated output directory. However, when running inside containers, files may be staged at arbitrary locations, see discussion for [`Dirent.entryname`](#Dirent). Together with `DockerRequirement.dockerOutputDirectory` it is possible to control the locations of both input and output files when running in containers.
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#InitialWorkDirRequirement"
+
     def __init__(
         self,
         listing: Any,
@@ -17314,12 +17482,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "InitialWorkDirRequirement":
-            raise ValidationException("tried `InitialWorkDirRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_InitialWorkDirRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("listing") is None:
                 raise ValidationException("missing required field `listing`", None, [])
@@ -17410,8 +17587,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "InitialWorkDirRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.listing is not None:
             r["listing"] = save(
                 self.listing, top=False, base_url=base_url, relative_uris=relative_uris
@@ -17435,6 +17613,8 @@ class EnvVarRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#EnvVarRequirement"
+
     def __init__(
         self,
         envDef: Any,
@@ -17474,12 +17654,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "EnvVarRequirement":
-            raise ValidationException("tried `EnvVarRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_EnvVarRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("envDef") is None:
                 raise ValidationException("missing required field `envDef`", None, [])
@@ -17570,8 +17759,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "EnvVarRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.envDef is not None:
             r["envDef"] = save(
                 self.envDef, top=False, base_url=base_url, relative_uris=relative_uris
@@ -17600,6 +17790,8 @@ class ShellCommandRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ShellCommandRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -17637,12 +17829,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ShellCommandRequirement":
-            raise ValidationException("tried `ShellCommandRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ShellCommandRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -17682,8 +17883,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ShellCommandRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -17726,6 +17928,8 @@ class ResourceRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ResourceRequirement"
+
     def __init__(
         self,
         coresMin: Optional[Any] = None,
@@ -17801,12 +18005,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ResourceRequirement":
-            raise ValidationException("tried `ResourceRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ResourceRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         coresMin = None
         if "coresMin" in _doc:
             try:
@@ -18232,8 +18445,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ResourceRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.coresMin is not None:
             r["coresMin"] = save(
                 self.coresMin, top=False, base_url=base_url, relative_uris=relative_uris
@@ -18316,6 +18530,8 @@ class WorkReuse(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkReuse"
+
     def __init__(
         self,
         enableReuse: Any,
@@ -18357,12 +18573,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "WorkReuse":
-            raise ValidationException("tried `WorkReuse` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_WorkReuse_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("enableReuse") is None:
                 raise ValidationException("missing required field `enableReuse`", None, [])
@@ -18453,8 +18678,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "WorkReuse"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.enableReuse is not None:
             r["enableReuse"] = save(
                 self.enableReuse,
@@ -18494,6 +18720,8 @@ class NetworkAccess(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#NetworkAccess"
+
     def __init__(
         self,
         networkAccess: Any,
@@ -18536,12 +18764,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "NetworkAccess":
-            raise ValidationException("tried `NetworkAccess` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_NetworkAccess_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("networkAccess") is None:
                 raise ValidationException("missing required field `networkAccess`", None, [])
@@ -18632,8 +18869,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "NetworkAccess"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.networkAccess is not None:
             r["networkAccess"] = save(
                 self.networkAccess,
@@ -18688,6 +18926,8 @@ class InplaceUpdateRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#InplaceUpdateRequirement"
+
     def __init__(
         self,
         inplaceUpdate: Any,
@@ -18730,12 +18970,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "InplaceUpdateRequirement":
-            raise ValidationException("tried `InplaceUpdateRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_InplaceUpdateRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("inplaceUpdate") is None:
                 raise ValidationException("missing required field `inplaceUpdate`", None, [])
@@ -18826,8 +19075,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "InplaceUpdateRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.inplaceUpdate is not None:
             r["inplaceUpdate"] = save(
                 self.inplaceUpdate,
@@ -18859,6 +19109,8 @@ class ToolTimeLimit(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ToolTimeLimit"
+
     def __init__(
         self,
         timelimit: Any,
@@ -18900,12 +19152,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ToolTimeLimit":
-            raise ValidationException("tried `ToolTimeLimit` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ToolTimeLimit_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         try:
             if _doc.get("timelimit") is None:
                 raise ValidationException("missing required field `timelimit`", None, [])
@@ -18996,8 +19257,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ToolTimeLimit"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
         if self.timelimit is not None:
             r["timelimit"] = save(
                 self.timelimit,
@@ -19018,6 +19280,8 @@ def save(
 
 
 class ExpressionToolOutputParameter(OutputParameter):
+    class_uri = "https://w3id.org/cwl/cwl#ExpressionToolOutputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -19521,6 +19785,8 @@ def save(
 
 
 class WorkflowInputParameter(InputParameter):
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowInputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -20280,6 +20546,8 @@ class ExpressionTool(Process):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ExpressionTool"
+
     def __init__(
         self,
         inputs: Any,
@@ -20363,12 +20631,6 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
-
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ExpressionTool":
-            raise ValidationException("tried `ExpressionTool` but")
-
         id = None
         if "id" in _doc:
             try:
@@ -20425,6 +20687,21 @@ def fromDoc(
                 id = "_:" + str(_uuid__.uuid4())
         if not __original_id_is_none:
             baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ExpressionTool_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         label = None
         if "label" in _doc:
             try:
@@ -20620,7 +20897,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -20667,7 +20944,7 @@ def fromDoc(
             try:
                 hints = load_field(
                     _doc.get("hints"),
-                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("hints")
@@ -20903,11 +21180,12 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ExpressionTool"
         if self.id is not None:
             u = save_relative_uri(self.id, base_url, True, None, relative_uris)
             r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
         if self.label is not None:
             r["label"] = save(
                 self.label, top=False, base_url=self.id, relative_uris=relative_uris
@@ -20986,6 +21264,8 @@ class WorkflowOutputParameter(OutputParameter):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowOutputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -21783,6 +22063,8 @@ class WorkflowStepInput(Identified, Sink, LoadContents, Labeled):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowStepInput"
+
     def __init__(
         self,
         id: Optional[Any] = None,
@@ -22419,6 +22701,8 @@ class WorkflowStepOutput(Identified):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowStepOutput"
+
     def __init__(
         self,
         id: Optional[Any] = None,
@@ -22653,6 +22937,8 @@ class WorkflowStep(Identified, Labeled, Documented):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#WorkflowStep"
+
     def __init__(
         self,
         in_: Any,
@@ -22988,7 +23274,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -23085,7 +23371,7 @@ def fromDoc(
 
             run = load_field(
                 _doc.get("run"),
-                uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_False_False_None_None,
+                uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader_False_False_None_None,
                 subscope_baseuri,
                 loadingOptions,
                 lc=_doc.get("run")
@@ -23447,6 +23733,8 @@ class Workflow(Process):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#Workflow"
+
     def __init__(
         self,
         inputs: Any,
@@ -23530,12 +23818,6 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
-
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "Workflow":
-            raise ValidationException("tried `Workflow` but")
-
         id = None
         if "id" in _doc:
             try:
@@ -23592,6 +23874,21 @@ def fromDoc(
                 id = "_:" + str(_uuid__.uuid4())
         if not __original_id_is_none:
             baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_Workflow_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         label = None
         if "label" in _doc:
             try:
@@ -23787,7 +24084,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -23834,7 +24131,7 @@ def fromDoc(
             try:
                 hints = load_field(
                     _doc.get("hints"),
-                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("hints")
@@ -24070,11 +24367,12 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "Workflow"
         if self.id is not None:
             u = save_relative_uri(self.id, base_url, True, None, relative_uris)
             r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
         if self.label is not None:
             r["label"] = save(
                 self.label, top=False, base_url=self.id, relative_uris=relative_uris
@@ -24145,6 +24443,8 @@ class SubworkflowFeatureRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#SubworkflowFeatureRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -24182,12 +24482,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "SubworkflowFeatureRequirement":
-            raise ValidationException("tried `SubworkflowFeatureRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_SubworkflowFeatureRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -24227,8 +24536,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "SubworkflowFeatureRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -24248,6 +24558,8 @@ class ScatterFeatureRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#ScatterFeatureRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -24285,12 +24597,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "ScatterFeatureRequirement":
-            raise ValidationException("tried `ScatterFeatureRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_ScatterFeatureRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -24330,8 +24651,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "ScatterFeatureRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -24351,6 +24673,8 @@ class MultipleInputFeatureRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#MultipleInputFeatureRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -24388,12 +24712,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "MultipleInputFeatureRequirement":
-            raise ValidationException("tried `MultipleInputFeatureRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_MultipleInputFeatureRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -24433,8 +24766,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "MultipleInputFeatureRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -24454,6 +24788,8 @@ class StepInputExpressionRequirement(ProcessRequirement):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#StepInputExpressionRequirement"
+
     def __init__(
         self,
         extension_fields: Optional[dict[str, Any]] = None,
@@ -24491,12 +24827,21 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
 
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "StepInputExpressionRequirement":
-            raise ValidationException("tried `StepInputExpressionRequirement` but")
-
+            class_ = load_field(
+                _doc.get("class"),
+                uri_StepInputExpressionRequirement_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         extension_fields: dict[str, Any] = {}
         for k in _doc.keys():
             if k not in cls.attrs:
@@ -24536,8 +24881,9 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "StepInputExpressionRequirement"
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
 
         # top refers to the directory level
         if top:
@@ -24556,6 +24902,8 @@ class OperationInputParameter(InputParameter):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#OperationInputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -25249,6 +25597,8 @@ class OperationOutputParameter(OutputParameter):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#OperationOutputParameter"
+
     def __init__(
         self,
         type_: Any,
@@ -25763,6 +26113,8 @@ class Operation(Process):
 
     """
 
+    class_uri = "https://w3id.org/cwl/cwl#Operation"
+
     def __init__(
         self,
         inputs: Any,
@@ -25842,12 +26194,6 @@ def fromDoc(
             _doc.lc.data = doc.lc.data
             _doc.lc.filename = doc.lc.filename
         _errors__ = []
-
-        if "class" not in _doc:
-            raise ValidationException("Missing 'class' field")
-        if _doc.get("class") != "Operation":
-            raise ValidationException("tried `Operation` but")
-
         id = None
         if "id" in _doc:
             try:
@@ -25904,6 +26250,21 @@ def fromDoc(
                 id = "_:" + str(_uuid__.uuid4())
         if not __original_id_is_none:
             baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_Operation_classLoader_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
         label = None
         if "label" in _doc:
             try:
@@ -26099,7 +26460,7 @@ def fromDoc(
             try:
                 requirements = load_field(
                     _doc.get("requirements"),
-                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("requirements")
@@ -26146,7 +26507,7 @@ def fromDoc(
             try:
                 hints = load_field(
                     _doc.get("hints"),
-                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type,
                     baseuri,
                     loadingOptions,
                     lc=_doc.get("hints")
@@ -26333,11 +26694,12 @@ def save(
         else:
             for ef in self.extension_fields:
                 r[ef] = self.extension_fields[ef]
-
-        r["class"] = "Operation"
         if self.id is not None:
             u = save_relative_uri(self.id, base_url, True, None, relative_uris)
             r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
         if self.label is not None:
             r["label"] = save(
                 self.label, top=False, base_url=self.id, relative_uris=relative_uris
@@ -26396,27 +26758,2350 @@ def save(
     )
 
 
-_vocab = {
-    "Any": "https://w3id.org/cwl/salad#Any",
-    "ArraySchema": "https://w3id.org/cwl/salad#ArraySchema",
-    "CWLArraySchema": "https://w3id.org/cwl/cwl#CWLArraySchema",
-    "CWLInputFile": "https://w3id.org/cwl/cwl#CWLInputFile",
-    "CWLObjectType": "https://w3id.org/cwl/cwl#CWLObjectType",
-    "CWLRecordField": "https://w3id.org/cwl/cwl#CWLRecordField",
-    "CWLRecordSchema": "https://w3id.org/cwl/cwl#CWLRecordSchema",
-    "CWLType": "https://w3id.org/cwl/cwl#CWLType",
-    "CWLVersion": "https://w3id.org/cwl/cwl#CWLVersion",
-    "CommandInputArraySchema": "https://w3id.org/cwl/cwl#CommandInputArraySchema",
-    "CommandInputEnumSchema": "https://w3id.org/cwl/cwl#CommandInputEnumSchema",
-    "CommandInputParameter": "https://w3id.org/cwl/cwl#CommandInputParameter",
-    "CommandInputRecordField": "https://w3id.org/cwl/cwl#CommandInputRecordField",
-    "CommandInputRecordSchema": "https://w3id.org/cwl/cwl#CommandInputRecordSchema",
-    "CommandInputSchema": "https://w3id.org/cwl/cwl#CommandInputSchema",
-    "CommandLineBindable": "https://w3id.org/cwl/cwl#CommandLineBindable",
-    "CommandLineBinding": "https://w3id.org/cwl/cwl#CommandLineBinding",
-    "CommandLineTool": "https://w3id.org/cwl/cwl#CommandLineTool",
-    "CommandOutputArraySchema": "https://w3id.org/cwl/cwl#CommandOutputArraySchema",
-    "CommandOutputBinding": "https://w3id.org/cwl/cwl#CommandOutputBinding",
+class Secrets(ProcessRequirement):
+    class_uri = "http://commonwl.org/cwltool#Secrets"
+
+    def __init__(
+        self,
+        secrets: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "Secrets"
+        self.secrets = secrets
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, Secrets):
+            return bool(self.class_ == other.class_ and self.secrets == other.secrets)
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.secrets))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "Secrets":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("secrets") is None:
+                raise ValidationException("missing required field `secrets`", None, [])
+
+            secrets = load_field(
+                _doc.get("secrets"),
+                uri_array_of_strtype_False_False_0_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("secrets")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `secrets`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("secrets")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `secrets` field is not valid because:",
+                            SourceLine(_doc, "secrets", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `secrets` field is not valid because:",
+                            SourceLine(_doc, "secrets", str),
+                            [e],
+                            detailed_message=f"the `secrets` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `secrets`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            secrets=secrets,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.secrets is not None:
+            u = save_relative_uri(self.secrets, base_url, False, 0, relative_uris)
+            r["secrets"] = u
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "secrets"])
+
+
+class ProcessGenerator(Process):
+    class_uri = "http://commonwl.org/cwltool#ProcessGenerator"
+
+    def __init__(
+        self,
+        inputs: Any,
+        outputs: Any,
+        run: Any,
+        id: Optional[Any] = None,
+        label: Optional[Any] = None,
+        doc: Optional[Any] = None,
+        requirements: Optional[Any] = None,
+        hints: Optional[Any] = None,
+        cwlVersion: Optional[Any] = None,
+        intent: Optional[Any] = None,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.id = id
+        self.label = label
+        self.doc = doc
+        self.inputs = inputs
+        self.outputs = outputs
+        self.requirements = requirements
+        self.hints = hints
+        self.cwlVersion = cwlVersion
+        self.intent = intent
+        self.class_ = "ProcessGenerator"
+        self.run = run
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, ProcessGenerator):
+            return bool(
+                self.id == other.id
+                and self.label == other.label
+                and self.doc == other.doc
+                and self.inputs == other.inputs
+                and self.outputs == other.outputs
+                and self.requirements == other.requirements
+                and self.hints == other.hints
+                and self.cwlVersion == other.cwlVersion
+                and self.intent == other.intent
+                and self.class_ == other.class_
+                and self.run == other.run
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash(
+            (
+                self.id,
+                self.label,
+                self.doc,
+                self.inputs,
+                self.outputs,
+                self.requirements,
+                self.hints,
+                self.cwlVersion,
+                self.intent,
+                self.class_,
+                self.run,
+            )
+        )
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "ProcessGenerator":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        id = None
+        if "id" in _doc:
+            try:
+                id = load_field(
+                    _doc.get("id"),
+                    uri_union_of_None_type_or_strtype_True_False_None_None,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("id")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `id`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("id")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `id` field is not valid because:",
+                                SourceLine(_doc, "id", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `id` field is not valid because:",
+                                SourceLine(_doc, "id", str),
+                                [e],
+                                detailed_message=f"the `id` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+
+        __original_id_is_none = id is None
+        if id is None:
+            if docRoot is not None:
+                id = docRoot
+            else:
+                id = "_:" + str(_uuid__.uuid4())
+        if not __original_id_is_none:
+            baseuri = cast(str, id)
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        label = None
+        if "label" in _doc:
+            try:
+                label = load_field(
+                    _doc.get("label"),
+                    union_of_None_type_or_strtype,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("label")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `label`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("label")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `label` field is not valid because:",
+                                SourceLine(_doc, "label", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `label` field is not valid because:",
+                                SourceLine(_doc, "label", str),
+                                [e],
+                                detailed_message=f"the `label` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        doc = None
+        if "doc" in _doc:
+            try:
+                doc = load_field(
+                    _doc.get("doc"),
+                    union_of_None_type_or_strtype_or_array_of_strtype,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("doc")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `doc`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("doc")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `doc` field is not valid because:",
+                                SourceLine(_doc, "doc", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `doc` field is not valid because:",
+                                SourceLine(_doc, "doc", str),
+                                [e],
+                                detailed_message=f"the `doc` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        try:
+            if _doc.get("inputs") is None:
+                raise ValidationException("missing required field `inputs`", None, [])
+
+            inputs = load_field(
+                _doc.get("inputs"),
+                idmap_inputs_array_of_union_of_CommandInputParameterLoader_or_WorkflowInputParameterLoader_or_OperationInputParameterLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("inputs")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `inputs`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("inputs")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `inputs` field is not valid because:",
+                            SourceLine(_doc, "inputs", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `inputs` field is not valid because:",
+                            SourceLine(_doc, "inputs", str),
+                            [e],
+                            detailed_message=f"the `inputs` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        try:
+            if _doc.get("outputs") is None:
+                raise ValidationException("missing required field `outputs`", None, [])
+
+            outputs = load_field(
+                _doc.get("outputs"),
+                idmap_outputs_array_of_union_of_CommandOutputParameterLoader_or_ExpressionToolOutputParameterLoader_or_WorkflowOutputParameterLoader_or_OperationOutputParameterLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("outputs")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `outputs`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("outputs")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `outputs` field is not valid because:",
+                            SourceLine(_doc, "outputs", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `outputs` field is not valid because:",
+                            SourceLine(_doc, "outputs", str),
+                            [e],
+                            detailed_message=f"the `outputs` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        requirements = None
+        if "requirements" in _doc:
+            try:
+                requirements = load_field(
+                    _doc.get("requirements"),
+                    idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("requirements")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `requirements`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("requirements")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `requirements` field is not valid because:",
+                                SourceLine(_doc, "requirements", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `requirements` field is not valid because:",
+                                SourceLine(_doc, "requirements", str),
+                                [e],
+                                detailed_message=f"the `requirements` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        hints = None
+        if "hints" in _doc:
+            try:
+                hints = load_field(
+                    _doc.get("hints"),
+                    idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("hints")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `hints`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("hints")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `hints` field is not valid because:",
+                                SourceLine(_doc, "hints", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `hints` field is not valid because:",
+                                SourceLine(_doc, "hints", str),
+                                [e],
+                                detailed_message=f"the `hints` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        cwlVersion = None
+        if "cwlVersion" in _doc:
+            try:
+                cwlVersion = load_field(
+                    _doc.get("cwlVersion"),
+                    uri_union_of_None_type_or_CWLVersionLoader_False_True_None_None,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("cwlVersion")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `cwlVersion`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("cwlVersion")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `cwlVersion` field is not valid because:",
+                                SourceLine(_doc, "cwlVersion", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `cwlVersion` field is not valid because:",
+                                SourceLine(_doc, "cwlVersion", str),
+                                [e],
+                                detailed_message=f"the `cwlVersion` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        intent = None
+        if "intent" in _doc:
+            try:
+                intent = load_field(
+                    _doc.get("intent"),
+                    uri_union_of_None_type_or_array_of_strtype_True_False_None_None,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("intent")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `intent`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("intent")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `intent` field is not valid because:",
+                                SourceLine(_doc, "intent", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `intent` field is not valid because:",
+                                SourceLine(_doc, "intent", str),
+                                [e],
+                                detailed_message=f"the `intent` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+
+        subscope_baseuri = expand_url('run', baseuri, loadingOptions, True)
+        try:
+            if _doc.get("run") is None:
+                raise ValidationException("missing required field `run`", None, [])
+
+            run = load_field(
+                _doc.get("run"),
+                uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader_False_False_None_None,
+                subscope_baseuri,
+                loadingOptions,
+                lc=_doc.get("run")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `run`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("run")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `run` field is not valid because:",
+                            SourceLine(_doc, "run", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `run` field is not valid because:",
+                            SourceLine(_doc, "run", str),
+                            [e],
+                            detailed_message=f"the `run` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `id`, `label`, `doc`, `inputs`, `outputs`, `requirements`, `hints`, `cwlVersion`, `intent`, `class`, `run`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            id=id,
+            label=label,
+            doc=doc,
+            inputs=inputs,
+            outputs=outputs,
+            requirements=requirements,
+            hints=hints,
+            cwlVersion=cwlVersion,
+            intent=intent,
+            run=run,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        loadingOptions.idx[cast(str, id)] = (_constructed, loadingOptions)
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.id is not None:
+            u = save_relative_uri(self.id, base_url, True, None, relative_uris)
+            r["id"] = u
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, self.id, False, None, relative_uris)
+            r["class"] = u
+        if self.label is not None:
+            r["label"] = save(
+                self.label, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.doc is not None:
+            r["doc"] = save(
+                self.doc, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.inputs is not None:
+            r["inputs"] = save(
+                self.inputs, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.outputs is not None:
+            r["outputs"] = save(
+                self.outputs, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.requirements is not None:
+            r["requirements"] = save(
+                self.requirements,
+                top=False,
+                base_url=self.id,
+                relative_uris=relative_uris,
+            )
+        if self.hints is not None:
+            r["hints"] = save(
+                self.hints, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.cwlVersion is not None:
+            u = save_relative_uri(self.cwlVersion, self.id, False, None, relative_uris)
+            r["cwlVersion"] = u
+        if self.intent is not None:
+            u = save_relative_uri(self.intent, self.id, True, None, relative_uris)
+            r["intent"] = u
+        if self.run is not None:
+            u = save_relative_uri(self.run, self.id, False, None, relative_uris)
+            r["run"] = u
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(
+        [
+            "id",
+            "label",
+            "doc",
+            "inputs",
+            "outputs",
+            "requirements",
+            "hints",
+            "cwlVersion",
+            "intent",
+            "class",
+            "run",
+        ]
+    )
+
+
+class MPIRequirement(ProcessRequirement):
+    """
+    Indicates that a process requires an MPI runtime.
+
+    """
+
+    class_uri = "http://commonwl.org/cwltool#MPIRequirement"
+
+    def __init__(
+        self,
+        processes: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "MPIRequirement"
+        self.processes = processes
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, MPIRequirement):
+            return bool(
+                self.class_ == other.class_ and self.processes == other.processes
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.processes))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "MPIRequirement":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("processes") is None:
+                raise ValidationException("missing required field `processes`", None, [])
+
+            processes = load_field(
+                _doc.get("processes"),
+                union_of_inttype_or_ExpressionLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("processes")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `processes`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("processes")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `processes` field is not valid because:",
+                            SourceLine(_doc, "processes", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `processes` field is not valid because:",
+                            SourceLine(_doc, "processes", str),
+                            [e],
+                            detailed_message=f"the `processes` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `processes`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            processes=processes,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.processes is not None:
+            r["processes"] = save(
+                self.processes,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "processes"])
+
+
+class CUDARequirement(ProcessRequirement):
+    """
+    Require support for NVIDA CUDA (GPU hardware acceleration).
+
+    """
+
+    class_uri = "http://commonwl.org/cwltool#CUDARequirement"
+
+    def __init__(
+        self,
+        cudaComputeCapability: Any,
+        cudaVersionMin: Any,
+        cudaDeviceCountMax: Optional[Any] = None,
+        cudaDeviceCountMin: Optional[Any] = None,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "CUDARequirement"
+        self.cudaComputeCapability = cudaComputeCapability
+        self.cudaDeviceCountMax = cudaDeviceCountMax
+        self.cudaDeviceCountMin = cudaDeviceCountMin
+        self.cudaVersionMin = cudaVersionMin
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, CUDARequirement):
+            return bool(
+                self.class_ == other.class_
+                and self.cudaComputeCapability == other.cudaComputeCapability
+                and self.cudaDeviceCountMax == other.cudaDeviceCountMax
+                and self.cudaDeviceCountMin == other.cudaDeviceCountMin
+                and self.cudaVersionMin == other.cudaVersionMin
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash(
+            (
+                self.class_,
+                self.cudaComputeCapability,
+                self.cudaDeviceCountMax,
+                self.cudaDeviceCountMin,
+                self.cudaVersionMin,
+            )
+        )
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "CUDARequirement":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("cudaComputeCapability") is None:
+                raise ValidationException("missing required field `cudaComputeCapability`", None, [])
+
+            cudaComputeCapability = load_field(
+                _doc.get("cudaComputeCapability"),
+                union_of_strtype_or_array_of_strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("cudaComputeCapability")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `cudaComputeCapability`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("cudaComputeCapability")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaComputeCapability` field is not valid because:",
+                            SourceLine(_doc, "cudaComputeCapability", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaComputeCapability` field is not valid because:",
+                            SourceLine(_doc, "cudaComputeCapability", str),
+                            [e],
+                            detailed_message=f"the `cudaComputeCapability` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        cudaDeviceCountMax = None
+        if "cudaDeviceCountMax" in _doc:
+            try:
+                cudaDeviceCountMax = load_field(
+                    _doc.get("cudaDeviceCountMax"),
+                    union_of_None_type_or_inttype_or_ExpressionLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("cudaDeviceCountMax")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `cudaDeviceCountMax`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("cudaDeviceCountMax")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMax` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMax", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMax` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMax", str),
+                                [e],
+                                detailed_message=f"the `cudaDeviceCountMax` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        cudaDeviceCountMin = None
+        if "cudaDeviceCountMin" in _doc:
+            try:
+                cudaDeviceCountMin = load_field(
+                    _doc.get("cudaDeviceCountMin"),
+                    union_of_None_type_or_inttype_or_ExpressionLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("cudaDeviceCountMin")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `cudaDeviceCountMin`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("cudaDeviceCountMin")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMin` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMin", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `cudaDeviceCountMin` field is not valid because:",
+                                SourceLine(_doc, "cudaDeviceCountMin", str),
+                                [e],
+                                detailed_message=f"the `cudaDeviceCountMin` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        try:
+            if _doc.get("cudaVersionMin") is None:
+                raise ValidationException("missing required field `cudaVersionMin`", None, [])
+
+            cudaVersionMin = load_field(
+                _doc.get("cudaVersionMin"),
+                strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("cudaVersionMin")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `cudaVersionMin`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("cudaVersionMin")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaVersionMin` field is not valid because:",
+                            SourceLine(_doc, "cudaVersionMin", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `cudaVersionMin` field is not valid because:",
+                            SourceLine(_doc, "cudaVersionMin", str),
+                            [e],
+                            detailed_message=f"the `cudaVersionMin` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `cudaComputeCapability`, `cudaDeviceCountMax`, `cudaDeviceCountMin`, `cudaVersionMin`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            cudaComputeCapability=cudaComputeCapability,
+            cudaDeviceCountMax=cudaDeviceCountMax,
+            cudaDeviceCountMin=cudaDeviceCountMin,
+            cudaVersionMin=cudaVersionMin,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.cudaComputeCapability is not None:
+            r["cudaComputeCapability"] = save(
+                self.cudaComputeCapability,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+        if self.cudaDeviceCountMax is not None:
+            r["cudaDeviceCountMax"] = save(
+                self.cudaDeviceCountMax,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+        if self.cudaDeviceCountMin is not None:
+            r["cudaDeviceCountMin"] = save(
+                self.cudaDeviceCountMin,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+        if self.cudaVersionMin is not None:
+            r["cudaVersionMin"] = save(
+                self.cudaVersionMin,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(
+        [
+            "class",
+            "cudaComputeCapability",
+            "cudaDeviceCountMax",
+            "cudaDeviceCountMin",
+            "cudaVersionMin",
+        ]
+    )
+
+
+class LoopInput(Saveable):
+    class_uri = "http://commonwl.org/cwltool#LoopInput"
+
+    def __init__(
+        self,
+        default: Optional[Any] = None,
+        id: Optional[Any] = None,
+        linkMerge: Optional[Any] = None,
+        loopSource: Optional[Any] = None,
+        pickValue: Optional[Any] = None,
+        valueFrom: Optional[Any] = None,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.default = default
+        self.id = id
+        self.linkMerge = linkMerge
+        self.loopSource = loopSource
+        self.pickValue = pickValue
+        self.valueFrom = valueFrom
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, LoopInput):
+            return bool(
+                self.default == other.default
+                and self.id == other.id
+                and self.linkMerge == other.linkMerge
+                and self.loopSource == other.loopSource
+                and self.pickValue == other.pickValue
+                and self.valueFrom == other.valueFrom
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash(
+            (
+                self.default,
+                self.id,
+                self.linkMerge,
+                self.loopSource,
+                self.pickValue,
+                self.valueFrom,
+            )
+        )
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "LoopInput":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        id = None
+        if "id" in _doc:
+            try:
+                id = load_field(
+                    _doc.get("id"),
+                    uri_union_of_None_type_or_strtype_True_False_None_None,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("id")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `id`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("id")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `id` field is not valid because:",
+                                SourceLine(_doc, "id", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `id` field is not valid because:",
+                                SourceLine(_doc, "id", str),
+                                [e],
+                                detailed_message=f"the `id` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+
+        __original_id_is_none = id is None
+        if id is None:
+            if docRoot is not None:
+                id = docRoot
+            else:
+                id = "_:" + str(_uuid__.uuid4())
+        if not __original_id_is_none:
+            baseuri = cast(str, id)
+        default = None
+        if "default" in _doc:
+            try:
+                default = load_field(
+                    _doc.get("default"),
+                    union_of_None_type_or_Any_type,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("default")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `default`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("default")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `default` field is not valid because:",
+                                SourceLine(_doc, "default", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `default` field is not valid because:",
+                                SourceLine(_doc, "default", str),
+                                [e],
+                                detailed_message=f"the `default` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        linkMerge = None
+        if "linkMerge" in _doc:
+            try:
+                linkMerge = load_field(
+                    _doc.get("linkMerge"),
+                    union_of_None_type_or_LinkMergeMethodLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("linkMerge")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `linkMerge`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("linkMerge")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `linkMerge` field is not valid because:",
+                                SourceLine(_doc, "linkMerge", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `linkMerge` field is not valid because:",
+                                SourceLine(_doc, "linkMerge", str),
+                                [e],
+                                detailed_message=f"the `linkMerge` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        loopSource = None
+        if "loopSource" in _doc:
+            try:
+                loopSource = load_field(
+                    _doc.get("loopSource"),
+                    uri_union_of_None_type_or_strtype_or_array_of_strtype_False_False_1_None,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("loopSource")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `loopSource`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("loopSource")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `loopSource` field is not valid because:",
+                                SourceLine(_doc, "loopSource", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `loopSource` field is not valid because:",
+                                SourceLine(_doc, "loopSource", str),
+                                [e],
+                                detailed_message=f"the `loopSource` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        pickValue = None
+        if "pickValue" in _doc:
+            try:
+                pickValue = load_field(
+                    _doc.get("pickValue"),
+                    union_of_None_type_or_PickValueMethodLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("pickValue")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `pickValue`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("pickValue")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `pickValue` field is not valid because:",
+                                SourceLine(_doc, "pickValue", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `pickValue` field is not valid because:",
+                                SourceLine(_doc, "pickValue", str),
+                                [e],
+                                detailed_message=f"the `pickValue` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        valueFrom = None
+        if "valueFrom" in _doc:
+            try:
+                valueFrom = load_field(
+                    _doc.get("valueFrom"),
+                    union_of_None_type_or_strtype_or_ExpressionLoader,
+                    baseuri,
+                    loadingOptions,
+                    lc=_doc.get("valueFrom")
+                )
+
+            except ValidationException as e:
+                error_message, to_print, verb_tensage = parse_errors(str(e))
+
+                if str(e) == "missing required field `valueFrom`":
+                    _errors__.append(
+                        ValidationException(
+                            str(e),
+                            None
+                        )
+                    )
+                else:
+                    val = _doc.get("valueFrom")
+                    if error_message != str(e):
+                        val_type = convert_typing(extract_type(type(val)))
+                        _errors__.append(
+                            ValidationException(
+                                "the `valueFrom` field is not valid because:",
+                                SourceLine(_doc, "valueFrom", str),
+                                [ValidationException(f"Value is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}",
+                                                     detailed_message=f"Value `{val}` is a {val_type}, "
+                                                     f"but valid {to_print} for this field "
+                                                     f"{verb_tensage} {error_message}")],
+                            )
+                        )
+                    else:
+                        _errors__.append(
+                            ValidationException(
+                                "the `valueFrom` field is not valid because:",
+                                SourceLine(_doc, "valueFrom", str),
+                                [e],
+                                detailed_message=f"the `valueFrom` field with value `{val}` "
+                                "is not valid because:",
+                            )
+                        )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `default`, `id`, `linkMerge`, `loopSource`, `pickValue`, `valueFrom`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            default=default,
+            id=id,
+            linkMerge=linkMerge,
+            loopSource=loopSource,
+            pickValue=pickValue,
+            valueFrom=valueFrom,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        loadingOptions.idx[cast(str, id)] = (_constructed, loadingOptions)
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.id is not None:
+            u = save_relative_uri(self.id, base_url, True, None, relative_uris)
+            r["id"] = u
+        if self.default is not None:
+            r["default"] = save(
+                self.default, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.linkMerge is not None:
+            r["linkMerge"] = save(
+                self.linkMerge, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.loopSource is not None:
+            u = save_relative_uri(self.loopSource, self.id, False, 1, relative_uris)
+            r["loopSource"] = u
+        if self.pickValue is not None:
+            r["pickValue"] = save(
+                self.pickValue, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+        if self.valueFrom is not None:
+            r["valueFrom"] = save(
+                self.valueFrom, top=False, base_url=self.id, relative_uris=relative_uris
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(
+        ["default", "id", "linkMerge", "loopSource", "pickValue", "valueFrom"]
+    )
+
+
+class Loop(ProcessRequirement):
+    """
+    Prototype to enable workflow-level looping of a step.
+
+    Valid only under `requirements` of a https://www.commonwl.org/v1.2/Workflow.html#WorkflowStep.
+    Unlike other CWL requirements, Loop requirement is not propagated to inner steps.
+
+    `loopWhen` is an expansion of the CWL v1.2 `when` construct which controls
+    conditional execution.
+
+    Using `loopWhen` and `when` for the same step will produce an error.
+
+    `loopWhen` is not compatible with `scatter` at this time and combining the
+    two in the same step will produce an error.
+
+    """
+
+    class_uri = "http://commonwl.org/cwltool#Loop"
+
+    def __init__(
+        self,
+        loop: Any,
+        loopWhen: Any,
+        outputMethod: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "Loop"
+        self.loop = loop
+        self.loopWhen = loopWhen
+        self.outputMethod = outputMethod
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, Loop):
+            return bool(
+                self.class_ == other.class_
+                and self.loop == other.loop
+                and self.loopWhen == other.loopWhen
+                and self.outputMethod == other.outputMethod
+            )
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.loop, self.loopWhen, self.outputMethod))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "Loop":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("loop") is None:
+                raise ValidationException("missing required field `loop`", None, [])
+
+            loop = load_field(
+                _doc.get("loop"),
+                idmap_loop_array_of_LoopInputLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("loop")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `loop`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("loop")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `loop` field is not valid because:",
+                            SourceLine(_doc, "loop", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `loop` field is not valid because:",
+                            SourceLine(_doc, "loop", str),
+                            [e],
+                            detailed_message=f"the `loop` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        try:
+            if _doc.get("loopWhen") is None:
+                raise ValidationException("missing required field `loopWhen`", None, [])
+
+            loopWhen = load_field(
+                _doc.get("loopWhen"),
+                ExpressionLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("loopWhen")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `loopWhen`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("loopWhen")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `loopWhen` field is not valid because:",
+                            SourceLine(_doc, "loopWhen", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `loopWhen` field is not valid because:",
+                            SourceLine(_doc, "loopWhen", str),
+                            [e],
+                            detailed_message=f"the `loopWhen` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        try:
+            if _doc.get("outputMethod") is None:
+                raise ValidationException("missing required field `outputMethod`", None, [])
+
+            outputMethod = load_field(
+                _doc.get("outputMethod"),
+                LoopOutputModesLoader,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("outputMethod")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `outputMethod`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("outputMethod")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `outputMethod` field is not valid because:",
+                            SourceLine(_doc, "outputMethod", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `outputMethod` field is not valid because:",
+                            SourceLine(_doc, "outputMethod", str),
+                            [e],
+                            detailed_message=f"the `outputMethod` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `loop`, `loopWhen`, `outputMethod`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            loop=loop,
+            loopWhen=loopWhen,
+            outputMethod=outputMethod,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.loop is not None:
+            r["loop"] = save(
+                self.loop, top=False, base_url=base_url, relative_uris=relative_uris
+            )
+        if self.loopWhen is not None:
+            r["loopWhen"] = save(
+                self.loopWhen, top=False, base_url=base_url, relative_uris=relative_uris
+            )
+        if self.outputMethod is not None:
+            r["outputMethod"] = save(
+                self.outputMethod,
+                top=False,
+                base_url=base_url,
+                relative_uris=relative_uris,
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "loop", "loopWhen", "outputMethod"])
+
+
+class ShmSize(ProcessRequirement):
+    class_uri = "http://commonwl.org/cwltool#ShmSize"
+
+    def __init__(
+        self,
+        shmSize: Any,
+        extension_fields: Optional[dict[str, Any]] = None,
+        loadingOptions: Optional[LoadingOptions] = None,
+    ) -> None:
+        if extension_fields:
+            self.extension_fields = extension_fields
+        else:
+            self.extension_fields = CommentedMap()
+        if loadingOptions:
+            self.loadingOptions = loadingOptions
+        else:
+            self.loadingOptions = LoadingOptions()
+        self.class_ = "ShmSize"
+        self.shmSize = shmSize
+
+    def __eq__(self, other: Any) -> bool:
+        if isinstance(other, ShmSize):
+            return bool(self.class_ == other.class_ and self.shmSize == other.shmSize)
+        return False
+
+    def __hash__(self) -> int:
+        return hash((self.class_, self.shmSize))
+
+    @classmethod
+    def fromDoc(
+        cls,
+        doc: Any,
+        baseuri: str,
+        loadingOptions: LoadingOptions,
+        docRoot: Optional[str] = None
+    ) -> "ShmSize":
+        _doc = copy.copy(doc)
+
+        if hasattr(doc, "lc"):
+            _doc.lc.data = doc.lc.data
+            _doc.lc.filename = doc.lc.filename
+        _errors__ = []
+        try:
+            if _doc.get("class") is None:
+                raise ValidationException("missing required field `class`", None, [])
+
+            class_ = load_field(
+                _doc.get("class"),
+                uri_strtype_False_True_None_None,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("class")
+            )
+            if class_ != cls.__name__ and class_ != cls.class_uri:
+               raise ValidationException(f"tried `{cls.__name__}` but")
+        except ValidationException as e:
+               raise e
+        try:
+            if _doc.get("shmSize") is None:
+                raise ValidationException("missing required field `shmSize`", None, [])
+
+            shmSize = load_field(
+                _doc.get("shmSize"),
+                strtype,
+                baseuri,
+                loadingOptions,
+                lc=_doc.get("shmSize")
+            )
+
+        except ValidationException as e:
+            error_message, to_print, verb_tensage = parse_errors(str(e))
+
+            if str(e) == "missing required field `shmSize`":
+                _errors__.append(
+                    ValidationException(
+                        str(e),
+                        None
+                    )
+                )
+            else:
+                val = _doc.get("shmSize")
+                if error_message != str(e):
+                    val_type = convert_typing(extract_type(type(val)))
+                    _errors__.append(
+                        ValidationException(
+                            "the `shmSize` field is not valid because:",
+                            SourceLine(_doc, "shmSize", str),
+                            [ValidationException(f"Value is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}",
+                                                 detailed_message=f"Value `{val}` is a {val_type}, "
+                                                 f"but valid {to_print} for this field "
+                                                 f"{verb_tensage} {error_message}")],
+                        )
+                    )
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "the `shmSize` field is not valid because:",
+                            SourceLine(_doc, "shmSize", str),
+                            [e],
+                            detailed_message=f"the `shmSize` field with value `{val}` "
+                            "is not valid because:",
+                        )
+                    )
+        extension_fields: dict[str, Any] = {}
+        for k in _doc.keys():
+            if k not in cls.attrs:
+                if not k:
+                    _errors__.append(
+                        ValidationException("mapping with implicit null key")
+                    )
+                elif ":" in k:
+                    ex = expand_url(
+                        k, "", loadingOptions, scoped_id=False, vocab_term=False
+                    )
+                    extension_fields[ex] = _doc[k]
+                else:
+                    _errors__.append(
+                        ValidationException(
+                            "invalid field `{}`, expected one of: `class`, `shmSize`".format(
+                                k
+                            ),
+                            SourceLine(_doc, k, str),
+                        )
+                    )
+
+        if _errors__:
+            raise ValidationException("", None, _errors__, "*")
+        _constructed = cls(
+            shmSize=shmSize,
+            extension_fields=extension_fields,
+            loadingOptions=loadingOptions,
+        )
+        return _constructed
+
+    def save(
+        self, top: bool = False, base_url: str = "", relative_uris: bool = True
+    ) -> dict[str, Any]:
+        r: dict[str, Any] = {}
+
+        if relative_uris:
+            for ef in self.extension_fields:
+                r[prefix_url(ef, self.loadingOptions.vocab)] = self.extension_fields[ef]
+        else:
+            for ef in self.extension_fields:
+                r[ef] = self.extension_fields[ef]
+        if self.class_ is not None:
+            u = save_relative_uri(self.class_, base_url, False, None, relative_uris)
+            r["class"] = u
+        if self.shmSize is not None:
+            r["shmSize"] = save(
+                self.shmSize, top=False, base_url=base_url, relative_uris=relative_uris
+            )
+
+        # top refers to the directory level
+        if top:
+            if self.loadingOptions.namespaces:
+                r["$namespaces"] = self.loadingOptions.namespaces
+            if self.loadingOptions.schemas:
+                r["$schemas"] = self.loadingOptions.schemas
+        return r
+
+    attrs = frozenset(["class", "shmSize"])
+
+
+_vocab = {
+    "Any": "https://w3id.org/cwl/salad#Any",
+    "ArraySchema": "https://w3id.org/cwl/salad#ArraySchema",
+    "CUDARequirement": "http://commonwl.org/cwltool#CUDARequirement",
+    "CWLArraySchema": "https://w3id.org/cwl/cwl#CWLArraySchema",
+    "CWLInputFile": "https://w3id.org/cwl/cwl#CWLInputFile",
+    "CWLObjectType": "https://w3id.org/cwl/cwl#CWLObjectType",
+    "CWLRecordField": "https://w3id.org/cwl/cwl#CWLRecordField",
+    "CWLRecordSchema": "https://w3id.org/cwl/cwl#CWLRecordSchema",
+    "CWLType": "https://w3id.org/cwl/cwl#CWLType",
+    "CWLVersion": "https://w3id.org/cwl/cwl#CWLVersion",
+    "CommandInputArraySchema": "https://w3id.org/cwl/cwl#CommandInputArraySchema",
+    "CommandInputEnumSchema": "https://w3id.org/cwl/cwl#CommandInputEnumSchema",
+    "CommandInputParameter": "https://w3id.org/cwl/cwl#CommandInputParameter",
+    "CommandInputRecordField": "https://w3id.org/cwl/cwl#CommandInputRecordField",
+    "CommandInputRecordSchema": "https://w3id.org/cwl/cwl#CommandInputRecordSchema",
+    "CommandInputSchema": "https://w3id.org/cwl/cwl#CommandInputSchema",
+    "CommandLineBindable": "https://w3id.org/cwl/cwl#CommandLineBindable",
+    "CommandLineBinding": "https://w3id.org/cwl/cwl#CommandLineBinding",
+    "CommandLineTool": "https://w3id.org/cwl/cwl#CommandLineTool",
+    "CommandOutputArraySchema": "https://w3id.org/cwl/cwl#CommandOutputArraySchema",
+    "CommandOutputBinding": "https://w3id.org/cwl/cwl#CommandOutputBinding",
     "CommandOutputEnumSchema": "https://w3id.org/cwl/cwl#CommandOutputEnumSchema",
     "CommandOutputParameter": "https://w3id.org/cwl/cwl#CommandOutputParameter",
     "CommandOutputRecordField": "https://w3id.org/cwl/cwl#CommandOutputRecordField",
@@ -26452,6 +29137,9 @@ def save(
     "LoadContents": "https://w3id.org/cwl/cwl#LoadContents",
     "LoadListingEnum": "https://w3id.org/cwl/cwl#LoadListingEnum",
     "LoadListingRequirement": "https://w3id.org/cwl/cwl#LoadListingRequirement",
+    "Loop": "http://commonwl.org/cwltool#Loop",
+    "LoopInput": "http://commonwl.org/cwltool#LoopInput",
+    "MPIRequirement": "http://commonwl.org/cwltool#MPIRequirement",
     "MapSchema": "https://w3id.org/cwl/salad#MapSchema",
     "MultipleInputFeatureRequirement": "https://w3id.org/cwl/cwl#MultipleInputFeatureRequirement",
     "NetworkAccess": "https://w3id.org/cwl/cwl#NetworkAccess",
@@ -26469,6 +29157,7 @@ def save(
     "PickValueMethod": "https://w3id.org/cwl/cwl#PickValueMethod",
     "PrimitiveType": "https://w3id.org/cwl/salad#PrimitiveType",
     "Process": "https://w3id.org/cwl/cwl#Process",
+    "ProcessGenerator": "http://commonwl.org/cwltool#ProcessGenerator",
     "ProcessRequirement": "https://w3id.org/cwl/cwl#ProcessRequirement",
     "RecordField": "https://w3id.org/cwl/salad#RecordField",
     "RecordSchema": "https://w3id.org/cwl/salad#RecordSchema",
@@ -26477,7 +29166,9 @@ def save(
     "ScatterMethod": "https://w3id.org/cwl/cwl#ScatterMethod",
     "SchemaDefRequirement": "https://w3id.org/cwl/cwl#SchemaDefRequirement",
     "SecondaryFileSchema": "https://w3id.org/cwl/cwl#SecondaryFileSchema",
+    "Secrets": "http://commonwl.org/cwltool#Secrets",
     "ShellCommandRequirement": "https://w3id.org/cwl/cwl#ShellCommandRequirement",
+    "ShmSize": "http://commonwl.org/cwltool#ShmSize",
     "Sink": "https://w3id.org/cwl/cwl#Sink",
     "SoftwarePackage": "https://w3id.org/cwl/cwl#SoftwarePackage",
     "SoftwareRequirement": "https://w3id.org/cwl/cwl#SoftwareRequirement",
@@ -26492,6 +29183,7 @@ def save(
     "WorkflowStep": "https://w3id.org/cwl/cwl#WorkflowStep",
     "WorkflowStepInput": "https://w3id.org/cwl/cwl#WorkflowStepInput",
     "WorkflowStepOutput": "https://w3id.org/cwl/cwl#WorkflowStepOutput",
+    "all": "http://commonwl.org/cwltool#Loop/outputMethod/LoopOutputModes/all",
     "all_non_null": "https://w3id.org/cwl/cwl#PickValueMethod/all_non_null",
     "array": "https://w3id.org/cwl/salad#array",
     "boolean": "http://www.w3.org/2001/XMLSchema#boolean",
@@ -26513,6 +29205,7 @@ def save(
     "flat_crossproduct": "https://w3id.org/cwl/cwl#ScatterMethod/flat_crossproduct",
     "float": "http://www.w3.org/2001/XMLSchema#float",
     "int": "http://www.w3.org/2001/XMLSchema#int",
+    "last": "http://commonwl.org/cwltool#Loop/outputMethod/LoopOutputModes/last",
     "long": "http://www.w3.org/2001/XMLSchema#long",
     "map": "https://w3id.org/cwl/salad#map",
     "merge_flattened": "https://w3id.org/cwl/cwl#LinkMergeMethod/merge_flattened",
@@ -26542,6 +29235,7 @@ def save(
 _rvocab = {
     "https://w3id.org/cwl/salad#Any": "Any",
     "https://w3id.org/cwl/salad#ArraySchema": "ArraySchema",
+    "http://commonwl.org/cwltool#CUDARequirement": "CUDARequirement",
     "https://w3id.org/cwl/cwl#CWLArraySchema": "CWLArraySchema",
     "https://w3id.org/cwl/cwl#CWLInputFile": "CWLInputFile",
     "https://w3id.org/cwl/cwl#CWLObjectType": "CWLObjectType",
@@ -26595,6 +29289,9 @@ def save(
     "https://w3id.org/cwl/cwl#LoadContents": "LoadContents",
     "https://w3id.org/cwl/cwl#LoadListingEnum": "LoadListingEnum",
     "https://w3id.org/cwl/cwl#LoadListingRequirement": "LoadListingRequirement",
+    "http://commonwl.org/cwltool#Loop": "Loop",
+    "http://commonwl.org/cwltool#LoopInput": "LoopInput",
+    "http://commonwl.org/cwltool#MPIRequirement": "MPIRequirement",
     "https://w3id.org/cwl/salad#MapSchema": "MapSchema",
     "https://w3id.org/cwl/cwl#MultipleInputFeatureRequirement": "MultipleInputFeatureRequirement",
     "https://w3id.org/cwl/cwl#NetworkAccess": "NetworkAccess",
@@ -26612,6 +29309,7 @@ def save(
     "https://w3id.org/cwl/cwl#PickValueMethod": "PickValueMethod",
     "https://w3id.org/cwl/salad#PrimitiveType": "PrimitiveType",
     "https://w3id.org/cwl/cwl#Process": "Process",
+    "http://commonwl.org/cwltool#ProcessGenerator": "ProcessGenerator",
     "https://w3id.org/cwl/cwl#ProcessRequirement": "ProcessRequirement",
     "https://w3id.org/cwl/salad#RecordField": "RecordField",
     "https://w3id.org/cwl/salad#RecordSchema": "RecordSchema",
@@ -26620,7 +29318,9 @@ def save(
     "https://w3id.org/cwl/cwl#ScatterMethod": "ScatterMethod",
     "https://w3id.org/cwl/cwl#SchemaDefRequirement": "SchemaDefRequirement",
     "https://w3id.org/cwl/cwl#SecondaryFileSchema": "SecondaryFileSchema",
+    "http://commonwl.org/cwltool#Secrets": "Secrets",
     "https://w3id.org/cwl/cwl#ShellCommandRequirement": "ShellCommandRequirement",
+    "http://commonwl.org/cwltool#ShmSize": "ShmSize",
     "https://w3id.org/cwl/cwl#Sink": "Sink",
     "https://w3id.org/cwl/cwl#SoftwarePackage": "SoftwarePackage",
     "https://w3id.org/cwl/cwl#SoftwareRequirement": "SoftwareRequirement",
@@ -26635,6 +29335,7 @@ def save(
     "https://w3id.org/cwl/cwl#WorkflowStep": "WorkflowStep",
     "https://w3id.org/cwl/cwl#WorkflowStepInput": "WorkflowStepInput",
     "https://w3id.org/cwl/cwl#WorkflowStepOutput": "WorkflowStepOutput",
+    "http://commonwl.org/cwltool#Loop/outputMethod/LoopOutputModes/all": "all",
     "https://w3id.org/cwl/cwl#PickValueMethod/all_non_null": "all_non_null",
     "https://w3id.org/cwl/salad#array": "array",
     "http://www.w3.org/2001/XMLSchema#boolean": "boolean",
@@ -26656,6 +29357,7 @@ def save(
     "https://w3id.org/cwl/cwl#ScatterMethod/flat_crossproduct": "flat_crossproduct",
     "http://www.w3.org/2001/XMLSchema#float": "float",
     "http://www.w3.org/2001/XMLSchema#int": "int",
+    "http://commonwl.org/cwltool#Loop/outputMethod/LoopOutputModes/last": "last",
     "http://www.w3.org/2001/XMLSchema#long": "long",
     "https://w3id.org/cwl/salad#map": "map",
     "https://w3id.org/cwl/cwl#LinkMergeMethod/merge_flattened": "merge_flattened",
@@ -26787,7 +29489,12 @@ def save(
 StepInputExpressionRequirementLoader = _RecordLoader(
     StepInputExpressionRequirement, None, None
 )
-union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _UnionLoader(
+SecretsLoader = _RecordLoader(Secrets, None, None)
+MPIRequirementLoader = _RecordLoader(MPIRequirement, None, None)
+CUDARequirementLoader = _RecordLoader(CUDARequirement, None, None)
+LoopLoader = _RecordLoader(Loop, None, None)
+ShmSizeLoader = _RecordLoader(ShmSize, None, None)
+union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader = _UnionLoader(
     (
         InlineJavascriptRequirementLoader,
         SchemaDefRequirementLoader,
@@ -26806,25 +29513,30 @@ def save(
         ScatterFeatureRequirementLoader,
         MultipleInputFeatureRequirementLoader,
         StepInputExpressionRequirementLoader,
+        SecretsLoader,
+        MPIRequirementLoader,
+        CUDARequirementLoader,
+        LoopLoader,
+        ShmSizeLoader,
     )
 )
-array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _ArrayLoader(
-    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader
+array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader = _ArrayLoader(
+    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader
 )
-union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_CWLObjectTypeLoader = _UnionLoader(
+union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_CWLObjectTypeLoader = _UnionLoader(
     (
         None_type,
-        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader,
         CWLObjectTypeLoader,
     )
 )
-map_of_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_CWLObjectTypeLoader = _MapLoader(
-    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_CWLObjectTypeLoader,
+map_of_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_CWLObjectTypeLoader = _MapLoader(
+    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_CWLObjectTypeLoader,
     "CWLInputFile",
     "@list",
     True,
 )
-CWLInputFileLoader = map_of_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_CWLObjectTypeLoader
+CWLInputFileLoader = map_of_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_CWLObjectTypeLoader
 CWLVersionLoader = _EnumLoader(
     (
         "draft-2",
@@ -27056,6 +29768,8 @@ def save(
 OperationInputParameterLoader = _RecordLoader(OperationInputParameter, None, None)
 OperationOutputParameterLoader = _RecordLoader(OperationOutputParameter, None, None)
 OperationLoader = _RecordLoader(Operation, None, None)
+ProcessGeneratorLoader = _RecordLoader(ProcessGenerator, None, None)
+LoopInputLoader = _RecordLoader(LoopInput, None, None)
 array_of_strtype = _ArrayLoader(strtype)
 union_of_None_type_or_strtype_or_array_of_strtype = _UnionLoader(
     (
@@ -27394,18 +30108,18 @@ def save(
     "id",
     "type",
 )
-union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _UnionLoader(
+union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader = _UnionLoader(
     (
         None_type,
-        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader,
     )
 )
-idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader = _IdMapLoader(
-    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader,
+idmap_requirements_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader = _IdMapLoader(
+    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader,
     "class",
     "None",
 )
-union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _UnionLoader(
+union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type = _UnionLoader(
     (
         InlineJavascriptRequirementLoader,
         SchemaDefRequirementLoader,
@@ -27424,20 +30138,25 @@ def save(
         ScatterFeatureRequirementLoader,
         MultipleInputFeatureRequirementLoader,
         StepInputExpressionRequirementLoader,
+        SecretsLoader,
+        MPIRequirementLoader,
+        CUDARequirementLoader,
+        LoopLoader,
+        ShmSizeLoader,
         Any_type,
     )
 )
-array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _ArrayLoader(
-    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type
+array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type = _ArrayLoader(
+    union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type
 )
-union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _UnionLoader(
+union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type = _UnionLoader(
     (
         None_type,
-        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+        array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type,
     )
 )
-idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type = _IdMapLoader(
-    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_Any_type,
+idmap_hints_union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type = _IdMapLoader(
+    union_of_None_type_or_array_of_union_of_InlineJavascriptRequirementLoader_or_SchemaDefRequirementLoader_or_LoadListingRequirementLoader_or_DockerRequirementLoader_or_SoftwareRequirementLoader_or_InitialWorkDirRequirementLoader_or_EnvVarRequirementLoader_or_ShellCommandRequirementLoader_or_ResourceRequirementLoader_or_WorkReuseLoader_or_NetworkAccessLoader_or_InplaceUpdateRequirementLoader_or_ToolTimeLimitLoader_or_SubworkflowFeatureRequirementLoader_or_ScatterFeatureRequirementLoader_or_MultipleInputFeatureRequirementLoader_or_StepInputExpressionRequirementLoader_or_SecretsLoader_or_MPIRequirementLoader_or_CUDARequirementLoader_or_LoopLoader_or_ShmSizeLoader_or_Any_type,
     "class",
     "None",
 )
@@ -27868,17 +30587,18 @@ def save(
 idmap_hints_union_of_None_type_or_array_of_Any_type = _IdMapLoader(
     union_of_None_type_or_array_of_Any_type, "class", "None"
 )
-union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader = _UnionLoader(
+union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader = _UnionLoader(
     (
         strtype,
         CommandLineToolLoader,
         ExpressionToolLoader,
         WorkflowLoader,
         OperationLoader,
+        ProcessGeneratorLoader,
     )
 )
-uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_False_False_None_None = _URILoader(
-    union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader,
+uri_union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader_False_False_None_None = _URILoader(
+    union_of_strtype_or_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader,
     False,
     False,
     None,
@@ -27945,24 +30665,53 @@ def save(
 idmap_outputs_array_of_OperationOutputParameterLoader = _IdMapLoader(
     array_of_OperationOutputParameterLoader, "id", "type"
 )
-union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader = _UnionLoader(
+uri_strtype_False_True_None_None = _URILoader(strtype, False, True, None, None)
+uri_array_of_strtype_False_False_0_None = _URILoader(
+    array_of_strtype, False, False, 0, None
+)
+union_of_strtype_or_array_of_strtype = _UnionLoader(
+    (
+        strtype,
+        array_of_strtype,
+    )
+)
+union_of_None_type_or_Any_type = _UnionLoader(
+    (
+        None_type,
+        Any_type,
+    )
+)
+array_of_LoopInputLoader = _ArrayLoader(LoopInputLoader)
+idmap_loop_array_of_LoopInputLoader = _IdMapLoader(
+    array_of_LoopInputLoader, "id", "loopSource"
+)
+LoopOutputModesLoader = _EnumLoader(
+    (
+        "last",
+        "all",
+    ),
+    "LoopOutputModes",
+)
+union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader = _UnionLoader(
     (
         CommandLineToolLoader,
         ExpressionToolLoader,
         WorkflowLoader,
         OperationLoader,
+        ProcessGeneratorLoader,
     )
 )
-array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader = _ArrayLoader(
-    union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader
+array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader = _ArrayLoader(
+    union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader
 )
-union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader = _UnionLoader(
+union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader = _UnionLoader(
     (
         CommandLineToolLoader,
         ExpressionToolLoader,
         WorkflowLoader,
         OperationLoader,
-        array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader,
+        ProcessGeneratorLoader,
+        array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader,
     )
 )
 
@@ -27990,7 +30739,7 @@ def load_document(
     if loadingOptions is None:
         loadingOptions = LoadingOptions()
     result, metadata = _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader,
         doc,
         baseuri,
         loadingOptions,
@@ -28009,7 +30758,7 @@ def load_document_with_metadata(
     if loadingOptions is None:
         loadingOptions = LoadingOptions(fileuri=baseuri)
     return _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader,
         doc,
         baseuri,
         loadingOptions,
@@ -28030,7 +30779,7 @@ def load_document_by_string(
         loadingOptions = LoadingOptions(fileuri=uri)
 
     result, metadata = _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader,
         result,
         uri,
         loadingOptions,
@@ -28053,7 +30802,7 @@ def load_document_by_yaml(
         loadingOptions = LoadingOptions(fileuri=uri)
 
     result, metadata = _document_load(
-        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader,
+        union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader_or_array_of_union_of_CommandLineToolLoader_or_ExpressionToolLoader_or_WorkflowLoader_or_OperationLoader_or_ProcessGeneratorLoader,
         yaml,
         uri,
         loadingOptions,
diff --git a/cwl_utils/parser/cwl_v1_2_utils.py b/cwl_utils/parser/cwl_v1_2_utils.py
index f2f1f61e..c15c23e7 100644
--- a/cwl_utils/parser/cwl_v1_2_utils.py
+++ b/cwl_utils/parser/cwl_v1_2_utils.py
@@ -5,10 +5,9 @@
 from collections import namedtuple
 from collections.abc import MutableMapping, MutableSequence
 from io import StringIO
-from typing import IO, Any, Optional, Union, cast
+from typing import Any, IO, Optional, Union, cast
 from urllib.parse import urldefrag
 
-from ruamel import yaml
 from schema_salad.exceptions import ValidationException
 from schema_salad.sourceline import SourceLine, add_lc_filename
 from schema_salad.utils import aslist, json_dumps, yaml_no_ts
@@ -17,6 +16,7 @@
 import cwl_utils.parser.cwl_v1_2 as cwl
 import cwl_utils.parser.utils
 from cwl_utils.errors import WorkflowException
+from cwl_utils.utils import yaml_dumps
 
 CONTENT_LIMIT: int = 64 * 1024
 
@@ -86,6 +86,16 @@ def _compare_type(type1: Any, type2: Any) -> bool:
         return bool(type1 == type2)
 
 
+def _is_all_output_method_loop_step(
+    param_to_step: dict[str, cwl.WorkflowStep], parm_id: str
+) -> bool:
+    if (source_step := param_to_step.get(parm_id)) is not None:
+        for requirement in source_step.requirements or []:
+            if isinstance(requirement, cwl.Loop) and requirement.outputMethod == "all":
+                return True
+    return False
+
+
 def _is_conditional_step(
     param_to_step: dict[str, cwl.WorkflowStep], parm_id: str
 ) -> bool:
@@ -230,6 +240,11 @@ def check_all_types(
                                 message="Source is from conditional step, but pickValue is not used",
                             )
                         )
+                    if _is_all_output_method_loop_step(param_to_step, parm_id):
+                        src_typ = type_dict[src_dict[parm_id].id]
+                        type_dict[src_dict[parm_id].id] = cwl.ArraySchema(
+                            items=src_typ, type_="array"
+                        )
             else:
                 parm_id = cast(str, sourceField)
                 if parm_id not in src_dict:
@@ -248,7 +263,7 @@ def check_all_types(
                         )
                     )
                 if _is_conditional_step(param_to_step, parm_id):
-                    src_typ = aslist(type_dict[srcs_of_sink[0].id])
+                    src_typ = aslist(type_dict[src_dict[parm_id].id])
                     snk_typ = type_dict[cast(str, sink.id)]
                     if "null" not in src_typ:
                         src_typ = ["null"] + cast(list[Any], src_typ)
@@ -264,7 +279,12 @@ def check_all_types(
                                 message="Source is from conditional step and may produce `null`",
                             )
                         )
-                    type_dict[srcs_of_sink[0].id] = src_typ
+                    type_dict[src_dict[parm_id].id] = src_typ
+                if _is_all_output_method_loop_step(param_to_step, parm_id):
+                    src_typ = type_dict[src_dict[parm_id].id]
+                    type_dict[src_dict[parm_id].id] = cwl.ArraySchema(
+                        items=src_typ, type_="array"
+                    )
             for src in srcs_of_sink:
                 check_result = check_types(
                     type_dict[cast(str, src.id)],
@@ -496,7 +516,7 @@ def type_for_step_output(
     raise ValidationException(
         "param {} not found in {}.".format(
             sourcename,
-            yaml.main.round_trip_dump(cwl.save(step)),
+            yaml_dumps(cwl.save(step)),
         )
     )
 
@@ -638,11 +658,7 @@ def param_for_source_id(
     raise WorkflowException(
         "param {} not found in {}\n{}.".format(
             sourcename,
-            yaml.main.round_trip_dump(cwl.save(process)),
-            (
-                f" or\n {yaml.main.round_trip_dump(cwl.save(parent))}"
-                if parent is not None
-                else ""
-            ),
+            yaml_dumps(cwl.save(process)),
+            (f" or\n {yaml_dumps(cwl.save(parent))}" if parent is not None else ""),
         )
     )
diff --git a/pyproject.toml b/pyproject.toml
index 1c4ba78a..4519fb4e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -67,6 +67,7 @@ packages = [
     "cwl_utils.tests",
     "cwl_utils.testdata",
     "cwl_utils.testdata.checker_wf",
+    "cwl_utils.testdata.extensions",
     "cwl_utils.testdata.types",
     "cwl_utils.testdata.workflows",
 ]
@@ -77,6 +78,7 @@ include-package-data = true
 "cwl_utils.tests" = "tests"
 "cwl_utils.testdata" = "testdata"
 "cwl_utils.testdata.checker_wf" = "testdata/checker_wf"
+"cwl_utils.testdata.extensions" = "testdata/extensions"
 "cwl_utils.testdata.types" = "testdata/types"
 "cwl_utils.testdata.workflows" = "testdata/workflows"
 
diff --git a/requirements.txt b/requirements.txt
index 5e887f69..d24b7145 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,5 +2,5 @@ cwl-upgrader >= 1.2.3
 packaging
 rdflib
 requests
-schema-salad >= 8.8, < 9
+schema-salad >= 8.8.20241206093842, < 9
 ruamel.yaml >= 0.17.6, < 0.19
diff --git a/testdata/extensions/all-output-loop_v1_2.cwl b/testdata/extensions/all-output-loop_v1_2.cwl
new file mode 100644
index 00000000..096be519
--- /dev/null
+++ b/testdata/extensions/all-output-loop_v1_2.cwl
@@ -0,0 +1,32 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.2
+class: Workflow
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  InlineJavascriptRequirement: {}
+inputs:
+  i1: int
+outputs:
+  o1:
+    type: int[]
+    outputSource: subworkflow/o1
+steps:
+  subworkflow:
+    run:
+      class: ExpressionTool
+      inputs:
+        i1: int
+      outputs:
+        o1: int
+      expression: >
+        ${return {'o1': inputs.i1 + 1};}
+    in:
+      i1: i1
+    out: [o1]
+    requirements:
+      cwltool:Loop:
+        loopWhen: $(inputs.i1 < 10)
+        loop:
+          i1: o1
+        outputMethod: all
diff --git a/testdata/extensions/cuda-requirement_v1_0.cwl b/testdata/extensions/cuda-requirement_v1_0.cwl
new file mode 100644
index 00000000..21985e6c
--- /dev/null
+++ b/testdata/extensions/cuda-requirement_v1_0.cwl
@@ -0,0 +1,16 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.0
+class: CommandLineTool
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  cwltool:CUDARequirement:
+    cudaVersionMin: "1.0"
+    cudaComputeCapability: "1.0"
+    cudaDeviceCountMin: $(inputs.gpus)
+inputs:
+  gpus:
+    type: int
+    default: 1
+outputs: []
+baseCommand: "nvidia-smi"
\ No newline at end of file
diff --git a/testdata/extensions/cuda-requirement_v1_1.cwl b/testdata/extensions/cuda-requirement_v1_1.cwl
new file mode 100644
index 00000000..9c24f0fe
--- /dev/null
+++ b/testdata/extensions/cuda-requirement_v1_1.cwl
@@ -0,0 +1,16 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.1
+class: CommandLineTool
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  cwltool:CUDARequirement:
+    cudaVersionMin: "1.0"
+    cudaComputeCapability: "1.0"
+    cudaDeviceCountMin: $(inputs.gpus)
+inputs:
+  gpus:
+    type: int
+    default: 1
+outputs: []
+baseCommand: "nvidia-smi"
\ No newline at end of file
diff --git a/testdata/extensions/cuda-requirement_v1_2.cwl b/testdata/extensions/cuda-requirement_v1_2.cwl
new file mode 100644
index 00000000..4f1ecbd8
--- /dev/null
+++ b/testdata/extensions/cuda-requirement_v1_2.cwl
@@ -0,0 +1,16 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.2
+class: CommandLineTool
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  cwltool:CUDARequirement:
+    cudaVersionMin: "1.0"
+    cudaComputeCapability: "1.0"
+    cudaDeviceCountMin: $(inputs.gpus)
+inputs:
+  gpus:
+    type: int
+    default: 1
+outputs: []
+baseCommand: "nvidia-smi"
\ No newline at end of file
diff --git a/testdata/extensions/inplace-update-requirement_v1_0.cwl b/testdata/extensions/inplace-update-requirement_v1_0.cwl
new file mode 100644
index 00000000..14f72054
--- /dev/null
+++ b/testdata/extensions/inplace-update-requirement_v1_0.cwl
@@ -0,0 +1,21 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.0
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  cwltool:InplaceUpdateRequirement:
+    inplaceUpdate: true
+inputs:
+  r: File
+  script:
+    type: File
+    default:
+      class: File
+      location: updateval.py
+outputs:
+  out:
+    type: File
+    outputBinding:
+      glob: $(inputs.r.basename)
+arguments: [python, $(inputs.script), $(inputs.r.basename)]
\ No newline at end of file
diff --git a/testdata/extensions/load-listing-requirement_v1_0.cwl b/testdata/extensions/load-listing-requirement_v1_0.cwl
new file mode 100644
index 00000000..36d67fb4
--- /dev/null
+++ b/testdata/extensions/load-listing-requirement_v1_0.cwl
@@ -0,0 +1,13 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.0
+$namespaces:
+  cwltool: http://commonwl.org/cwltool#
+requirements:
+  cwltool:LoadListingRequirement:
+    loadListing: shallow_listing
+inputs:
+  d: Directory
+outputs: []
+arguments:
+  [echo, "$(inputs.d.listing[0].listing[0])"]
diff --git a/testdata/extensions/mpi-requirement_v1_0.cwl b/testdata/extensions/mpi-requirement_v1_0.cwl
new file mode 100644
index 00000000..72dc680b
--- /dev/null
+++ b/testdata/extensions/mpi-requirement_v1_0.cwl
@@ -0,0 +1,14 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.0
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+
+baseCommand: env
+requirements:
+  cwltool:MPIRequirement:
+    processes: 1
+inputs: {}
+outputs:
+  environment:
+    type: stdout
\ No newline at end of file
diff --git a/testdata/extensions/mpi-requirement_v1_1.cwl b/testdata/extensions/mpi-requirement_v1_1.cwl
new file mode 100644
index 00000000..a4ad0fe1
--- /dev/null
+++ b/testdata/extensions/mpi-requirement_v1_1.cwl
@@ -0,0 +1,13 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.1
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+baseCommand: env
+requirements:
+  cwltool:MPIRequirement:
+    processes: 1
+inputs: {}
+outputs:
+  environment:
+    type: stdout
\ No newline at end of file
diff --git a/testdata/extensions/mpi-requirement_v1_2.cwl b/testdata/extensions/mpi-requirement_v1_2.cwl
new file mode 100644
index 00000000..5790f414
--- /dev/null
+++ b/testdata/extensions/mpi-requirement_v1_2.cwl
@@ -0,0 +1,13 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.2
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+baseCommand: env
+requirements:
+  cwltool:MPIRequirement:
+    processes: 1
+inputs: {}
+outputs:
+  environment:
+    type: stdout
\ No newline at end of file
diff --git a/testdata/extensions/network-access_v1_0.cwl b/testdata/extensions/network-access_v1_0.cwl
new file mode 100644
index 00000000..4152a116
--- /dev/null
+++ b/testdata/extensions/network-access_v1_0.cwl
@@ -0,0 +1,16 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.0
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  cwltool:NetworkAccess:
+    networkAccess: true
+inputs: []
+outputs: []
+baseCommand: python
+arguments:
+  - "-c"
+  - valueFrom: |
+      import urllib.request
+      assert(urllib.request.urlopen("http://commonwl.org").code == 200)
\ No newline at end of file
diff --git a/testdata/extensions/process-generator_v1_0.cwl b/testdata/extensions/process-generator_v1_0.cwl
new file mode 100644
index 00000000..01df6367
--- /dev/null
+++ b/testdata/extensions/process-generator_v1_0.cwl
@@ -0,0 +1,32 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.0
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+class: cwltool:ProcessGenerator
+inputs:
+  script: string
+  dir: Directory
+outputs: {}
+run:
+  class: CommandLineTool
+  inputs:
+    script: string
+    dir: Directory
+  outputs:
+    runProcess:
+      type: File
+      outputBinding:
+        glob: main.cwl
+  requirements:
+    InlineJavascriptRequirement: {}
+    LoadListingRequirement:
+      loadListing: shallow_listing
+    InitialWorkDirRequirement:
+      listing: |
+        ${
+         var v = inputs.dir.listing;
+         v.push({entryname: "inp.py", entry: inputs.script});
+         return v;
+        }
+  arguments: [python3, inp.py]
+  stdout: main.cwl
\ No newline at end of file
diff --git a/testdata/extensions/process-generator_v1_1.cwl b/testdata/extensions/process-generator_v1_1.cwl
new file mode 100644
index 00000000..b4ccc99c
--- /dev/null
+++ b/testdata/extensions/process-generator_v1_1.cwl
@@ -0,0 +1,32 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.1
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+class: cwltool:ProcessGenerator
+inputs:
+  script: string
+  dir: Directory
+outputs: {}
+run:
+  class: CommandLineTool
+  inputs:
+    script: string
+    dir: Directory
+  outputs:
+    runProcess:
+      type: File
+      outputBinding:
+        glob: main.cwl
+  requirements:
+    InlineJavascriptRequirement: {}
+    LoadListingRequirement:
+      loadListing: shallow_listing
+    InitialWorkDirRequirement:
+      listing: |
+        ${
+         var v = inputs.dir.listing;
+         v.push({entryname: "inp.py", entry: inputs.script});
+         return v;
+        }
+  arguments: [python3, inp.py]
+  stdout: main.cwl
\ No newline at end of file
diff --git a/testdata/extensions/process-generator_v1_2.cwl b/testdata/extensions/process-generator_v1_2.cwl
new file mode 100644
index 00000000..62960a2f
--- /dev/null
+++ b/testdata/extensions/process-generator_v1_2.cwl
@@ -0,0 +1,32 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.2
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+class: cwltool:ProcessGenerator
+inputs:
+  script: string
+  dir: Directory
+outputs: {}
+run:
+  class: CommandLineTool
+  inputs:
+    script: string
+    dir: Directory
+  outputs:
+    runProcess:
+      type: File
+      outputBinding:
+        glob: main.cwl
+  requirements:
+    InlineJavascriptRequirement: {}
+    LoadListingRequirement:
+      loadListing: shallow_listing
+    InitialWorkDirRequirement:
+      listing: |
+        ${
+         var v = inputs.dir.listing;
+         v.push({entryname: "inp.py", entry: inputs.script});
+         return v;
+        }
+  arguments: [python3, inp.py]
+  stdout: main.cwl
\ No newline at end of file
diff --git a/testdata/extensions/secrets_v1_0.cwl b/testdata/extensions/secrets_v1_0.cwl
new file mode 100644
index 00000000..63446512
--- /dev/null
+++ b/testdata/extensions/secrets_v1_0.cwl
@@ -0,0 +1,13 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.0
+class: CommandLineTool
+$namespaces:
+  cwltool: http://commonwl.org/cwltool#
+requirements:
+  cwltool:Secrets:
+    secrets: [pw]
+inputs:
+  pw: string
+outputs:
+  out: stdout
+arguments: [cat, example.conf]
diff --git a/testdata/extensions/secrets_v1_1.cwl b/testdata/extensions/secrets_v1_1.cwl
new file mode 100644
index 00000000..09d476f6
--- /dev/null
+++ b/testdata/extensions/secrets_v1_1.cwl
@@ -0,0 +1,13 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.1
+class: CommandLineTool
+$namespaces:
+  cwltool: http://commonwl.org/cwltool#
+requirements:
+  cwltool:Secrets:
+    secrets: [pw]
+inputs:
+  pw: string
+outputs:
+  out: stdout
+arguments: [cat, example.conf]
diff --git a/testdata/extensions/secrets_v1_2.cwl b/testdata/extensions/secrets_v1_2.cwl
new file mode 100644
index 00000000..02d7dff6
--- /dev/null
+++ b/testdata/extensions/secrets_v1_2.cwl
@@ -0,0 +1,13 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.2
+class: CommandLineTool
+$namespaces:
+  cwltool: http://commonwl.org/cwltool#
+requirements:
+  cwltool:Secrets:
+    secrets: [pw]
+inputs:
+  pw: string
+outputs:
+  out: stdout
+arguments: [cat, example.conf]
diff --git a/testdata/extensions/shm-size_v1_0.cwl b/testdata/extensions/shm-size_v1_0.cwl
new file mode 100644
index 00000000..01f90a44
--- /dev/null
+++ b/testdata/extensions/shm-size_v1_0.cwl
@@ -0,0 +1,15 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.0
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  cwltool:ShmSize:
+    shmSize: 128m
+inputs: []
+outputs:
+  output:
+    type: stdout
+baseCommand: echo
+stdout: shm-size.txt
+arguments: [ $(runtime) ]
diff --git a/testdata/extensions/shm-size_v1_1.cwl b/testdata/extensions/shm-size_v1_1.cwl
new file mode 100644
index 00000000..3bff20df
--- /dev/null
+++ b/testdata/extensions/shm-size_v1_1.cwl
@@ -0,0 +1,15 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.1
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  cwltool:ShmSize:
+    shmSize: 128m
+inputs: []
+outputs:
+  output:
+    type: stdout
+baseCommand: echo
+stdout: shm-size.txt
+arguments: [ $(runtime) ]
diff --git a/testdata/extensions/shm-size_v1_2.cwl b/testdata/extensions/shm-size_v1_2.cwl
new file mode 100644
index 00000000..b6491432
--- /dev/null
+++ b/testdata/extensions/shm-size_v1_2.cwl
@@ -0,0 +1,15 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.2
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  cwltool:ShmSize:
+    shmSize: 128m
+inputs: []
+outputs:
+  output:
+    type: stdout
+baseCommand: echo
+stdout: shm-size.txt
+arguments: [ $(runtime) ]
diff --git a/testdata/extensions/single-var-loop_v1_2.cwl b/testdata/extensions/single-var-loop_v1_2.cwl
new file mode 100644
index 00000000..c5f76563
--- /dev/null
+++ b/testdata/extensions/single-var-loop_v1_2.cwl
@@ -0,0 +1,32 @@
+#!/usr/bin/env cwl-runner
+cwlVersion: v1.2
+class: Workflow
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  InlineJavascriptRequirement: {}
+inputs:
+  i1: int
+outputs:
+  o1:
+    type: int
+    outputSource: subworkflow/o1
+steps:
+  subworkflow:
+    run:
+      class: ExpressionTool
+      inputs:
+        i1: int
+      outputs:
+        o1: int
+      expression: >
+        ${return {'o1': inputs.i1 + 1};}
+    in:
+      i1: i1
+    out: [o1]
+    requirements:
+      cwltool:Loop:
+        loopWhen: $(inputs.i1 < 10)
+        loop:
+          i1: o1
+        outputMethod: last
diff --git a/testdata/extensions/time-limit_v1_0.cwl b/testdata/extensions/time-limit_v1_0.cwl
new file mode 100644
index 00000000..7106a934
--- /dev/null
+++ b/testdata/extensions/time-limit_v1_0.cwl
@@ -0,0 +1,15 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.0
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+inputs:
+  sleep_time:
+    type: int
+    default: 3
+    inputBinding: {}
+outputs: []
+requirements:
+  cwltool:TimeLimit:
+    timelimit: 20
+baseCommand: sleep
\ No newline at end of file
diff --git a/testdata/extensions/work-reuse_v1_0.cwl b/testdata/extensions/work-reuse_v1_0.cwl
new file mode 100644
index 00000000..7278cb2b
--- /dev/null
+++ b/testdata/extensions/work-reuse_v1_0.cwl
@@ -0,0 +1,18 @@
+#!/usr/bin/env cwl-runner
+class: CommandLineTool
+cwlVersion: v1.0
+$namespaces:
+  cwltool: "http://commonwl.org/cwltool#"
+requirements:
+  cwltool:WorkReuse:
+    enableReuse: false
+inputs: []
+outputs:
+  page: stdout
+stdout: time.txt
+baseCommand: python
+arguments:
+  - "-c"
+  - valueFrom: |
+      import time
+      print(time.time())


Test patch:
diff --git a/tests/test_extensions.py b/tests/test_extensions.py
new file mode 100644
index 00000000..ab4a0f43
--- /dev/null
+++ b/tests/test_extensions.py
@@ -0,0 +1,204 @@
+from pathlib import Path
+
+from cwl_utils.parser import cwl_v1_0, cwl_v1_1, cwl_v1_2, load_document_by_uri
+
+from .util import get_data
+
+
+def test_cuda_requirement_v1_0() -> None:
+    """Test that CUDARequirement objects are correctly loaded for CWL v1.0."""
+    uri = (
+        Path(get_data("testdata/extensions/cuda-requirement_v1_0.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_0.CUDARequirement)
+
+
+def test_cuda_requirement_v1_1() -> None:
+    """Test that CUDARequirement objects are correctly loaded for CWL v1.1."""
+    uri = (
+        Path(get_data("testdata/extensions/cuda-requirement_v1_1.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_1.CUDARequirement)
+
+
+def test_cuda_requirement_v1_2() -> None:
+    """Test that CUDARequirement objects are correctly loaded for CWL v1.2."""
+    uri = (
+        Path(get_data("testdata/extensions/cuda-requirement_v1_2.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_2.CUDARequirement)
+
+
+def test_load_listing_requirement_v1_0() -> None:
+    """Test that LoadListingRequirement objects are correctly loaded for CWL v1.0."""
+    uri = (
+        Path(get_data("testdata/extensions/load-listing-requirement_v1_0.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_0.LoadListingRequirement)
+
+
+def test_loop_v1_2() -> None:
+    """Test that Loop and LoopInput objects are correctly loaded for CWL v1.2."""
+    uri = (
+        Path(get_data("testdata/extensions/single-var-loop_v1_2.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    cwl_obj = load_document_by_uri(uri)
+    cwl_step = next(iter(cwl_obj.steps))
+    loop_req = next(iter(cwl_step.requirements))
+    assert isinstance(loop_req, cwl_v1_2.Loop)
+    assert isinstance(next(iter(loop_req.loop)), cwl_v1_2.LoopInput)
+
+
+def test_inplace_update_requirement_v1_0() -> None:
+    """Test that InplaceUpdateRequirement objects are correctly loaded for CWL v1.0."""
+    uri = (
+        Path(get_data("testdata/extensions/inplace-update-requirement_v1_0.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(
+        next(iter(cwl_obj.requirements)), cwl_v1_0.InplaceUpdateRequirement
+    )
+
+
+def test_mpi_requirement_v1_0() -> None:
+    """Test that MPIRequirement objects are correctly loaded for CWL v1.0."""
+    uri = (
+        Path(get_data("testdata/extensions/mpi-requirement_v1_0.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_0.MPIRequirement)
+
+
+def test_mpi_requirement_v1_1() -> None:
+    """Test that MPIRequirement objects are correctly loaded for CWL v1.1."""
+    uri = (
+        Path(get_data("testdata/extensions/mpi-requirement_v1_1.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_1.MPIRequirement)
+
+
+def test_mpi_requirement_v1_2() -> None:
+    """Test that MPIRequirement objects are correctly loaded for CWL v1.2."""
+    uri = (
+        Path(get_data("testdata/extensions/mpi-requirement_v1_2.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_2.MPIRequirement)
+
+
+def test_network_access_v1_0() -> None:
+    """Test that NetworkAccess objects are correctly loaded for CWL v1.0."""
+    uri = (
+        Path(get_data("testdata/extensions/network-access_v1_0.cwl")).resolve().as_uri()
+    )
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_0.NetworkAccess)
+
+
+def test_process_generator_v1_0() -> None:
+    """Test that ProcessGenerator objects are correctly loaded for CWL v1.0."""
+    uri = (
+        Path(get_data("testdata/extensions/process-generator_v1_0.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    assert isinstance(load_document_by_uri(uri), cwl_v1_0.ProcessGenerator)
+
+
+def test_process_generator_v1_1() -> None:
+    """Test that ProcessGenerator objects are correctly loaded for CWL v1.1."""
+    uri = (
+        Path(get_data("testdata/extensions/process-generator_v1_1.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    assert isinstance(load_document_by_uri(uri), cwl_v1_1.ProcessGenerator)
+
+
+def test_process_generator_v1_2() -> None:
+    """Test that ProcessGenerator objects are correctly loaded for CWL v1.2."""
+    uri = (
+        Path(get_data("testdata/extensions/process-generator_v1_2.cwl"))
+        .resolve()
+        .as_uri()
+    )
+    assert isinstance(load_document_by_uri(uri), cwl_v1_2.ProcessGenerator)
+
+
+def test_secrets_v1_0() -> None:
+    """Test that Secrets objects are correctly loaded for CWL v1.0."""
+    uri = Path(get_data("testdata/extensions/secrets_v1_0.cwl")).resolve().as_uri()
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_0.Secrets)
+
+
+def test_secrets_v1_1() -> None:
+    """Test that Secrets objects are correctly loaded for CWL v1.1."""
+    uri = Path(get_data("testdata/extensions/secrets_v1_1.cwl")).resolve().as_uri()
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_1.Secrets)
+
+
+def test_secrets_v1_2() -> None:
+    """Test that Secrets objects are correctly loaded for CWL v1.2."""
+    uri = Path(get_data("testdata/extensions/secrets_v1_2.cwl")).resolve().as_uri()
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_2.Secrets)
+
+
+def test_shm_size_v1_0() -> None:
+    """Test that ShmSize objects are correctly loaded for CWL v1.0."""
+    uri = Path(get_data("testdata/extensions/shm-size_v1_0.cwl")).resolve().as_uri()
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_0.ShmSize)
+
+
+def test_shm_size_v1_1() -> None:
+    """Test that ShmSize objects are correctly loaded for CWL v1.1."""
+    uri = Path(get_data("testdata/extensions/shm-size_v1_1.cwl")).resolve().as_uri()
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_1.ShmSize)
+
+
+def test_shm_size_v1_2() -> None:
+    """Test that ShmSize objects are correctly loaded for CWL v1.2."""
+    uri = Path(get_data("testdata/extensions/shm-size_v1_2.cwl")).resolve().as_uri()
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_2.ShmSize)
+
+
+def test_time_limit_v1_0() -> None:
+    """Test that TimeLimit objects are correctly loaded for CWL v1.0."""
+    uri = Path(get_data("testdata/extensions/time-limit_v1_0.cwl")).resolve().as_uri()
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_0.TimeLimit)
+
+
+def test_work_reuse_v1_0() -> None:
+    """Test that WorkReuse objects are correctly loaded for CWL v1.0."""
+    uri = Path(get_data("testdata/extensions/work-reuse_v1_0.cwl")).resolve().as_uri()
+    cwl_obj = load_document_by_uri(uri)
+    assert isinstance(next(iter(cwl_obj.requirements)), cwl_v1_0.WorkReuse)
diff --git a/tests/test_parser_utils.py b/tests/test_parser_utils.py
index 25eef68f..8c16b004 100644
--- a/tests/test_parser_utils.py
+++ b/tests/test_parser_utils.py
@@ -36,16 +36,12 @@ def test_static_checker_fail(cwlVersion: str) -> None:
 
         uri = Path(get_data("testdata/checker_wf/broken-wf2.cwl")).resolve().as_uri()
         cwl_obj = load_document_by_uri(uri)
-        with pytest.raises(
-            ValidationException, match="param .* not found in class: CommandLineTool"
-        ):
+        with pytest.raises(ValidationException, match="param .* not found in id: .*"):
             cwl_utils.parser.utils.static_checker(cwl_obj)
 
         uri = Path(get_data("testdata/checker_wf/broken-wf3.cwl")).resolve().as_uri()
         cwl_obj = load_document_by_uri(uri)
-        with pytest.raises(
-            ValidationException, match="param .* not found in class: Workflow"
-        ):
+        with pytest.raises(ValidationException, match="param .* not found in id: .*"):
             cwl_utils.parser.utils.static_checker(cwl_obj)
 
     uri = (
@@ -107,6 +103,8 @@ def test_static_checker_success(cwlVersion: str) -> None:
                 "testdata/cond-wf-004.1.cwl",
                 "testdata/cond-wf-005.1.cwl",
                 "testdata/cond-single-source-wf-005.1.cwl",
+                "testdata/extensions/all-output-loop_v1_2.cwl",
+                "testdata/extensions/single-var-loop_v1_2.cwl",
             ]
         )
     for test_file in test_files: