We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
--pack should preserve @namespace
---

## Expected Behavior
cwltool should resolve file formats specified as links (e.g., after `--pack`-ing a workflow)

## Steps to reproduce
```
cd /path/to/common-workflow-language/v1.0/v1.0
cwltool --pack formattest2.cwl > formattest2-packed.cwl
cwltool formattest2-packed.cwl formattest2-job.json
```

Expected output:
```
{
    "output": {
        "format": "http://edamontology.org/format_2330", 
        "checksum": "sha1$97fe1b50b4582cebc7d853796ebd62e3e163aa3f", 
        "basename": "output.txt", 
        "location": "file:///Users/anton/Programming/CWL/cwltool/cwltool/schemas/v1.0/output.txt", 
        "path": "/Users/anton/Programming/CWL/cwltool/cwltool/schemas/v1.0/output.txt", 
        "class": "File", 
        "size": 1111
    }
}
```

Produced output:
```
{
    "output": {
        "format": "edam:format_2330", 
        "checksum": "sha1$97fe1b50b4582cebc7d853796ebd62e3e163aa3f", 
        "basename": "output.txt", 
        "location": "file:///Users/anton/Programming/CWL/cwltool/cwltool/schemas/v1.0/output.txt", 
        "path": "/Users/anton/Programming/CWL/cwltool/cwltool/schemas/v1.0/output.txt", 
        "class": "File", 
        "size": 1111
    }
}
```

## Your Environment
* cwltool version: 
1.0.20171107133715


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cwltool/pack.py`
Content:
```
1 from __future__ import absolute_import
2 import copy
3 import re
4 from typing import Any, Callable, Dict, List, Set, Text, Union, cast
5 
6 from schema_salad.ref_resolver import Loader, SubLoader
7 from six.moves import urllib
8 from ruamel.yaml.comments import CommentedSeq, CommentedMap
9 
10 from .process import shortname, uniquename
11 import six
12 
13 
14 def flatten_deps(d, files):  # type: (Any, Set[Text]) -> None
15     if isinstance(d, list):
16         for s in d:
17             flatten_deps(s, files)
18     elif isinstance(d, dict):
19         if d["class"] == "File":
20             files.add(d["location"])
21         if "secondaryFiles" in d:
22             flatten_deps(d["secondaryFiles"], files)
23         if "listing" in d:
24             flatten_deps(d["listing"], files)
25 
26 
27 def find_run(d, loadref, runs):  # type: (Any, Callable[[Text, Text], Union[Dict, List, Text]], Set[Text]) -> None
28     if isinstance(d, list):
29         for s in d:
30             find_run(s, loadref, runs)
31     elif isinstance(d, dict):
32         if "run" in d and isinstance(d["run"], six.string_types):
33             if d["run"] not in runs:
34                 runs.add(d["run"])
35                 find_run(loadref(None, d["run"]), loadref, runs)
36         for s in d.values():
37             find_run(s, loadref, runs)
38 
39 
40 def find_ids(d, ids):  # type: (Any, Set[Text]) -> None
41     if isinstance(d, list):
42         for s in d:
43             find_ids(s, ids)
44     elif isinstance(d, dict):
45         for i in ("id", "name"):
46             if i in d and isinstance(d[i], six.string_types):
47                 ids.add(d[i])
48         for s in d.values():
49             find_ids(s, ids)
50 
51 
52 def replace_refs(d, rewrite, stem, newstem):
53     # type: (Any, Dict[Text, Text], Text, Text) -> None
54     if isinstance(d, list):
55         for s, v in enumerate(d):
56             if isinstance(v, six.string_types):
57                 if v in rewrite:
58                     d[s] = rewrite[v]
59                 elif v.startswith(stem):
60                     d[s] = newstem + v[len(stem):]
61             else:
62                 replace_refs(v, rewrite, stem, newstem)
63     elif isinstance(d, dict):
64         for s, v in d.items():
65             if isinstance(v, six.string_types):
66                 if v in rewrite:
67                     d[s] = rewrite[v]
68                 elif v.startswith(stem):
69                     id_ = v[len(stem):]
70                     # prevent appending newstems if tool is already packed
71                     if id_.startswith(newstem.strip("#")):
72                         d[s] = "#" + id_
73                     else:
74                         d[s] = newstem + id_
75             replace_refs(v, rewrite, stem, newstem)
76 
77 def import_embed(d, seen):
78     # type: (Any, Set[Text]) -> None
79     if isinstance(d, list):
80         for v in d:
81             import_embed(v, seen)
82     elif isinstance(d, dict):
83         for n in ("id", "name"):
84             if n in d:
85                 if d[n] in seen:
86                     this = d[n]
87                     d.clear()
88                     d["$import"] = this
89                 else:
90                     this = d[n]
91                     seen.add(this)
92                     break
93 
94         for k in sorted(d.keys()):
95             import_embed(d[k], seen)
96 
97 
98 def pack(document_loader, processobj, uri, metadata):
99     # type: (Loader, Union[Dict[Text, Any], List[Dict[Text, Any]]], Text, Dict[Text, Text]) -> Dict[Text, Any]
100 
101     document_loader = SubLoader(document_loader)
102     document_loader.idx = {}
103     if isinstance(processobj, dict):
104         document_loader.idx[processobj["id"]] = CommentedMap(six.iteritems(processobj))
105     elif isinstance(processobj, list):
106         path, frag = urllib.parse.urldefrag(uri)
107         for po in processobj:
108             if not frag:
109                 if po["id"].endswith("#main"):
110                     uri = po["id"]
111             document_loader.idx[po["id"]] = CommentedMap(six.iteritems(po))
112 
113     def loadref(b, u):
114         # type: (Text, Text) -> Union[Dict, List, Text]
115         return document_loader.resolve_ref(u, base_url=b)[0]
116 
117     runs = {uri}
118     find_run(processobj, loadref, runs)
119 
120     ids = set()  # type: Set[Text]
121     for f in runs:
122         find_ids(document_loader.resolve_ref(f)[0], ids)
123 
124     names = set()  # type: Set[Text]
125     rewrite = {}  # type: Dict[Text, Text]
126 
127     mainpath, _ = urllib.parse.urldefrag(uri)
128 
129     def rewrite_id(r, mainuri):
130         # type: (Text, Text) -> None
131         if r == mainuri:
132             rewrite[r] = "#main"
133         elif r.startswith(mainuri) and r[len(mainuri)] in ("#", "/"):
134             path, frag = urllib.parse.urldefrag(r)
135             rewrite[r] = "#"+frag
136         else:
137             path, frag = urllib.parse.urldefrag(r)
138             if path == mainpath:
139                 rewrite[r] = "#" + uniquename(frag, names)
140             else:
141                 if path not in rewrite:
142                     rewrite[path] = "#" + uniquename(shortname(path), names)
143 
144     sortedids = sorted(ids)
145 
146     for r in sortedids:
147         if r in document_loader.idx:
148             rewrite_id(r, uri)
149 
150     packed = {"$graph": [], "cwlVersion": metadata["cwlVersion"]
151               }  # type: Dict[Text, Any]
152 
153     schemas = set()  # type: Set[Text]
154     for r in sorted(runs):
155         dcr, metadata = document_loader.resolve_ref(r)
156         if isinstance(dcr, CommentedSeq):
157             dcr = dcr[0]
158             dcr = cast(CommentedMap, dcr)
159         if not isinstance(dcr, dict):
160             continue
161         for doc in (dcr, metadata):
162             if "$schemas" in doc:
163                 for s in doc["$schemas"]:
164                     schemas.add(s)
165         if dcr.get("class") not in ("Workflow", "CommandLineTool", "ExpressionTool"):
166             continue
167         dc = cast(Dict[Text, Any], copy.deepcopy(dcr))
168         v = rewrite[r]
169         dc["id"] = v
170         for n in ("name", "cwlVersion", "$namespaces", "$schemas"):
171             if n in dc:
172                 del dc[n]
173         packed["$graph"].append(dc)
174 
175     if schemas:
176         packed["$schemas"] = list(schemas)
177 
178     for r in rewrite:
179         v = rewrite[r]
180         replace_refs(packed, rewrite, r + "/" if "#" in r else r + "#", v + "/")
181 
182     import_embed(packed, set())
183 
184     if len(packed["$graph"]) == 1:
185         # duplicate 'cwlVersion' inside $graph when there is a single item
186         # because we're printing contents inside '$graph' rather than whole dict
187         packed["$graph"][0]["cwlVersion"] = packed["cwlVersion"]
188 
189     return packed
190
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/cwltool/pack.py b/cwltool/pack.py
--- a/cwltool/pack.py
+++ b/cwltool/pack.py
@@ -149,6 +149,7 @@
 
     packed = {"$graph": [], "cwlVersion": metadata["cwlVersion"]
               }  # type: Dict[Text, Any]
+    namespaces = metadata.get('$namespaces', None)
 
     schemas = set()  # type: Set[Text]
     for r in sorted(runs):
@@ -185,5 +186,7 @@
         # duplicate 'cwlVersion' inside $graph when there is a single item
         # because we're printing contents inside '$graph' rather than whole dict
         packed["$graph"][0]["cwlVersion"] = packed["cwlVersion"]
+    if namespaces:
+        packed["$graph"][0]["$namespaces"] = dict(cast(Dict, namespaces))
 
     return packed

{"golden_diff": "diff --git a/cwltool/pack.py b/cwltool/pack.py\n--- a/cwltool/pack.py\n+++ b/cwltool/pack.py\n@@ -149,6 +149,7 @@\n \n     packed = {\"$graph\": [], \"cwlVersion\": metadata[\"cwlVersion\"]\n               }  # type: Dict[Text, Any]\n+    namespaces = metadata.get('$namespaces', None)\n \n     schemas = set()  # type: Set[Text]\n     for r in sorted(runs):\n@@ -185,5 +186,7 @@\n         # duplicate 'cwlVersion' inside $graph when there is a single item\n         # because we're printing contents inside '$graph' rather than whole dict\n         packed[\"$graph\"][0][\"cwlVersion\"] = packed[\"cwlVersion\"]\n+    if namespaces:\n+        packed[\"$graph\"][0][\"$namespaces\"] = dict(cast(Dict, namespaces))\n \n     return packed\n", "issue": "--pack should preserve @namespace\n---\r\n\r\n## Expected Behavior\r\ncwltool should resolve file formats specified as links (e.g., after `--pack`-ing a workflow)\r\n\r\n## Steps to reproduce\r\n```\r\ncd /path/to/common-workflow-language/v1.0/v1.0\r\ncwltool --pack formattest2.cwl > formattest2-packed.cwl\r\ncwltool formattest2-packed.cwl formattest2-job.json\r\n```\r\n\r\nExpected output:\r\n```\r\n{\r\n    \"output\": {\r\n        \"format\": \"http://edamontology.org/format_2330\", \r\n        \"checksum\": \"sha1$97fe1b50b4582cebc7d853796ebd62e3e163aa3f\", \r\n        \"basename\": \"output.txt\", \r\n        \"location\": \"file:///Users/anton/Programming/CWL/cwltool/cwltool/schemas/v1.0/output.txt\", \r\n        \"path\": \"/Users/anton/Programming/CWL/cwltool/cwltool/schemas/v1.0/output.txt\", \r\n        \"class\": \"File\", \r\n        \"size\": 1111\r\n    }\r\n}\r\n```\r\n\r\nProduced output:\r\n```\r\n{\r\n    \"output\": {\r\n        \"format\": \"edam:format_2330\", \r\n        \"checksum\": \"sha1$97fe1b50b4582cebc7d853796ebd62e3e163aa3f\", \r\n        \"basename\": \"output.txt\", \r\n        \"location\": \"file:///Users/anton/Programming/CWL/cwltool/cwltool/schemas/v1.0/output.txt\", \r\n        \"path\": \"/Users/anton/Programming/CWL/cwltool/cwltool/schemas/v1.0/output.txt\", \r\n        \"class\": \"File\", \r\n        \"size\": 1111\r\n    }\r\n}\r\n```\r\n\r\n## Your Environment\r\n* cwltool version: \r\n1.0.20171107133715\r\n\n", "before_files": [{"content": "from __future__ import absolute_import\nimport copy\nimport re\nfrom typing import Any, Callable, Dict, List, Set, Text, Union, cast\n\nfrom schema_salad.ref_resolver import Loader, SubLoader\nfrom six.moves import urllib\nfrom ruamel.yaml.comments import CommentedSeq, CommentedMap\n\nfrom .process import shortname, uniquename\nimport six\n\n\ndef flatten_deps(d, files):  # type: (Any, Set[Text]) -> None\n    if isinstance(d, list):\n        for s in d:\n            flatten_deps(s, files)\n    elif isinstance(d, dict):\n        if d[\"class\"] == \"File\":\n            files.add(d[\"location\"])\n        if \"secondaryFiles\" in d:\n            flatten_deps(d[\"secondaryFiles\"], files)\n        if \"listing\" in d:\n            flatten_deps(d[\"listing\"], files)\n\n\ndef find_run(d, loadref, runs):  # type: (Any, Callable[[Text, Text], Union[Dict, List, Text]], Set[Text]) -> None\n    if isinstance(d, list):\n        for s in d:\n            find_run(s, loadref, runs)\n    elif isinstance(d, dict):\n        if \"run\" in d and isinstance(d[\"run\"], six.string_types):\n            if d[\"run\"] not in runs:\n                runs.add(d[\"run\"])\n                find_run(loadref(None, d[\"run\"]), loadref, runs)\n        for s in d.values():\n            find_run(s, loadref, runs)\n\n\ndef find_ids(d, ids):  # type: (Any, Set[Text]) -> None\n    if isinstance(d, list):\n        for s in d:\n            find_ids(s, ids)\n    elif isinstance(d, dict):\n        for i in (\"id\", \"name\"):\n            if i in d and isinstance(d[i], six.string_types):\n                ids.add(d[i])\n        for s in d.values():\n            find_ids(s, ids)\n\n\ndef replace_refs(d, rewrite, stem, newstem):\n    # type: (Any, Dict[Text, Text], Text, Text) -> None\n    if isinstance(d, list):\n        for s, v in enumerate(d):\n            if isinstance(v, six.string_types):\n                if v in rewrite:\n                    d[s] = rewrite[v]\n                elif v.startswith(stem):\n                    d[s] = newstem + v[len(stem):]\n            else:\n                replace_refs(v, rewrite, stem, newstem)\n    elif isinstance(d, dict):\n        for s, v in d.items():\n            if isinstance(v, six.string_types):\n                if v in rewrite:\n                    d[s] = rewrite[v]\n                elif v.startswith(stem):\n                    id_ = v[len(stem):]\n                    # prevent appending newstems if tool is already packed\n                    if id_.startswith(newstem.strip(\"#\")):\n                        d[s] = \"#\" + id_\n                    else:\n                        d[s] = newstem + id_\n            replace_refs(v, rewrite, stem, newstem)\n\ndef import_embed(d, seen):\n    # type: (Any, Set[Text]) -> None\n    if isinstance(d, list):\n        for v in d:\n            import_embed(v, seen)\n    elif isinstance(d, dict):\n        for n in (\"id\", \"name\"):\n            if n in d:\n                if d[n] in seen:\n                    this = d[n]\n                    d.clear()\n                    d[\"$import\"] = this\n                else:\n                    this = d[n]\n                    seen.add(this)\n                    break\n\n        for k in sorted(d.keys()):\n            import_embed(d[k], seen)\n\n\ndef pack(document_loader, processobj, uri, metadata):\n    # type: (Loader, Union[Dict[Text, Any], List[Dict[Text, Any]]], Text, Dict[Text, Text]) -> Dict[Text, Any]\n\n    document_loader = SubLoader(document_loader)\n    document_loader.idx = {}\n    if isinstance(processobj, dict):\n        document_loader.idx[processobj[\"id\"]] = CommentedMap(six.iteritems(processobj))\n    elif isinstance(processobj, list):\n        path, frag = urllib.parse.urldefrag(uri)\n        for po in processobj:\n            if not frag:\n                if po[\"id\"].endswith(\"#main\"):\n                    uri = po[\"id\"]\n            document_loader.idx[po[\"id\"]] = CommentedMap(six.iteritems(po))\n\n    def loadref(b, u):\n        # type: (Text, Text) -> Union[Dict, List, Text]\n        return document_loader.resolve_ref(u, base_url=b)[0]\n\n    runs = {uri}\n    find_run(processobj, loadref, runs)\n\n    ids = set()  # type: Set[Text]\n    for f in runs:\n        find_ids(document_loader.resolve_ref(f)[0], ids)\n\n    names = set()  # type: Set[Text]\n    rewrite = {}  # type: Dict[Text, Text]\n\n    mainpath, _ = urllib.parse.urldefrag(uri)\n\n    def rewrite_id(r, mainuri):\n        # type: (Text, Text) -> None\n        if r == mainuri:\n            rewrite[r] = \"#main\"\n        elif r.startswith(mainuri) and r[len(mainuri)] in (\"#\", \"/\"):\n            path, frag = urllib.parse.urldefrag(r)\n            rewrite[r] = \"#\"+frag\n        else:\n            path, frag = urllib.parse.urldefrag(r)\n            if path == mainpath:\n                rewrite[r] = \"#\" + uniquename(frag, names)\n            else:\n                if path not in rewrite:\n                    rewrite[path] = \"#\" + uniquename(shortname(path), names)\n\n    sortedids = sorted(ids)\n\n    for r in sortedids:\n        if r in document_loader.idx:\n            rewrite_id(r, uri)\n\n    packed = {\"$graph\": [], \"cwlVersion\": metadata[\"cwlVersion\"]\n              }  # type: Dict[Text, Any]\n\n    schemas = set()  # type: Set[Text]\n    for r in sorted(runs):\n        dcr, metadata = document_loader.resolve_ref(r)\n        if isinstance(dcr, CommentedSeq):\n            dcr = dcr[0]\n            dcr = cast(CommentedMap, dcr)\n        if not isinstance(dcr, dict):\n            continue\n        for doc in (dcr, metadata):\n            if \"$schemas\" in doc:\n                for s in doc[\"$schemas\"]:\n                    schemas.add(s)\n        if dcr.get(\"class\") not in (\"Workflow\", \"CommandLineTool\", \"ExpressionTool\"):\n            continue\n        dc = cast(Dict[Text, Any], copy.deepcopy(dcr))\n        v = rewrite[r]\n        dc[\"id\"] = v\n        for n in (\"name\", \"cwlVersion\", \"$namespaces\", \"$schemas\"):\n            if n in dc:\n                del dc[n]\n        packed[\"$graph\"].append(dc)\n\n    if schemas:\n        packed[\"$schemas\"] = list(schemas)\n\n    for r in rewrite:\n        v = rewrite[r]\n        replace_refs(packed, rewrite, r + \"/\" if \"#\" in r else r + \"#\", v + \"/\")\n\n    import_embed(packed, set())\n\n    if len(packed[\"$graph\"]) == 1:\n        # duplicate 'cwlVersion' inside $graph when there is a single item\n        # because we're printing contents inside '$graph' rather than whole dict\n        packed[\"$graph\"][0][\"cwlVersion\"] = packed[\"cwlVersion\"]\n\n    return packed\n", "path": "cwltool/pack.py"}], "after_files": [{"content": "from __future__ import absolute_import\nimport copy\nimport re\nfrom typing import Any, Callable, Dict, List, Set, Text, Union, cast\n\nfrom schema_salad.ref_resolver import Loader, SubLoader\nfrom six.moves import urllib\nfrom ruamel.yaml.comments import CommentedSeq, CommentedMap\n\nfrom .process import shortname, uniquename\nimport six\n\n\ndef flatten_deps(d, files):  # type: (Any, Set[Text]) -> None\n    if isinstance(d, list):\n        for s in d:\n            flatten_deps(s, files)\n    elif isinstance(d, dict):\n        if d[\"class\"] == \"File\":\n            files.add(d[\"location\"])\n        if \"secondaryFiles\" in d:\n            flatten_deps(d[\"secondaryFiles\"], files)\n        if \"listing\" in d:\n            flatten_deps(d[\"listing\"], files)\n\n\ndef find_run(d, loadref, runs):  # type: (Any, Callable[[Text, Text], Union[Dict, List, Text]], Set[Text]) -> None\n    if isinstance(d, list):\n        for s in d:\n            find_run(s, loadref, runs)\n    elif isinstance(d, dict):\n        if \"run\" in d and isinstance(d[\"run\"], six.string_types):\n            if d[\"run\"] not in runs:\n                runs.add(d[\"run\"])\n                find_run(loadref(None, d[\"run\"]), loadref, runs)\n        for s in d.values():\n            find_run(s, loadref, runs)\n\n\ndef find_ids(d, ids):  # type: (Any, Set[Text]) -> None\n    if isinstance(d, list):\n        for s in d:\n            find_ids(s, ids)\n    elif isinstance(d, dict):\n        for i in (\"id\", \"name\"):\n            if i in d and isinstance(d[i], six.string_types):\n                ids.add(d[i])\n        for s in d.values():\n            find_ids(s, ids)\n\n\ndef replace_refs(d, rewrite, stem, newstem):\n    # type: (Any, Dict[Text, Text], Text, Text) -> None\n    if isinstance(d, list):\n        for s, v in enumerate(d):\n            if isinstance(v, six.string_types):\n                if v in rewrite:\n                    d[s] = rewrite[v]\n                elif v.startswith(stem):\n                    d[s] = newstem + v[len(stem):]\n            else:\n                replace_refs(v, rewrite, stem, newstem)\n    elif isinstance(d, dict):\n        for s, v in d.items():\n            if isinstance(v, six.string_types):\n                if v in rewrite:\n                    d[s] = rewrite[v]\n                elif v.startswith(stem):\n                    id_ = v[len(stem):]\n                    # prevent appending newstems if tool is already packed\n                    if id_.startswith(newstem.strip(\"#\")):\n                        d[s] = \"#\" + id_\n                    else:\n                        d[s] = newstem + id_\n            replace_refs(v, rewrite, stem, newstem)\n\ndef import_embed(d, seen):\n    # type: (Any, Set[Text]) -> None\n    if isinstance(d, list):\n        for v in d:\n            import_embed(v, seen)\n    elif isinstance(d, dict):\n        for n in (\"id\", \"name\"):\n            if n in d:\n                if d[n] in seen:\n                    this = d[n]\n                    d.clear()\n                    d[\"$import\"] = this\n                else:\n                    this = d[n]\n                    seen.add(this)\n                    break\n\n        for k in sorted(d.keys()):\n            import_embed(d[k], seen)\n\n\ndef pack(document_loader, processobj, uri, metadata):\n    # type: (Loader, Union[Dict[Text, Any], List[Dict[Text, Any]]], Text, Dict[Text, Text]) -> Dict[Text, Any]\n\n    document_loader = SubLoader(document_loader)\n    document_loader.idx = {}\n    if isinstance(processobj, dict):\n        document_loader.idx[processobj[\"id\"]] = CommentedMap(six.iteritems(processobj))\n    elif isinstance(processobj, list):\n        path, frag = urllib.parse.urldefrag(uri)\n        for po in processobj:\n            if not frag:\n                if po[\"id\"].endswith(\"#main\"):\n                    uri = po[\"id\"]\n            document_loader.idx[po[\"id\"]] = CommentedMap(six.iteritems(po))\n\n    def loadref(b, u):\n        # type: (Text, Text) -> Union[Dict, List, Text]\n        return document_loader.resolve_ref(u, base_url=b)[0]\n\n    runs = {uri}\n    find_run(processobj, loadref, runs)\n\n    ids = set()  # type: Set[Text]\n    for f in runs:\n        find_ids(document_loader.resolve_ref(f)[0], ids)\n\n    names = set()  # type: Set[Text]\n    rewrite = {}  # type: Dict[Text, Text]\n\n    mainpath, _ = urllib.parse.urldefrag(uri)\n\n    def rewrite_id(r, mainuri):\n        # type: (Text, Text) -> None\n        if r == mainuri:\n            rewrite[r] = \"#main\"\n        elif r.startswith(mainuri) and r[len(mainuri)] in (\"#\", \"/\"):\n            path, frag = urllib.parse.urldefrag(r)\n            rewrite[r] = \"#\"+frag\n        else:\n            path, frag = urllib.parse.urldefrag(r)\n            if path == mainpath:\n                rewrite[r] = \"#\" + uniquename(frag, names)\n            else:\n                if path not in rewrite:\n                    rewrite[path] = \"#\" + uniquename(shortname(path), names)\n\n    sortedids = sorted(ids)\n\n    for r in sortedids:\n        if r in document_loader.idx:\n            rewrite_id(r, uri)\n\n    packed = {\"$graph\": [], \"cwlVersion\": metadata[\"cwlVersion\"]\n              }  # type: Dict[Text, Any]\n    namespaces = metadata.get('$namespaces', None)\n\n    schemas = set()  # type: Set[Text]\n    for r in sorted(runs):\n        dcr, metadata = document_loader.resolve_ref(r)\n        if isinstance(dcr, CommentedSeq):\n            dcr = dcr[0]\n            dcr = cast(CommentedMap, dcr)\n        if not isinstance(dcr, dict):\n            continue\n        for doc in (dcr, metadata):\n            if \"$schemas\" in doc:\n                for s in doc[\"$schemas\"]:\n                    schemas.add(s)\n        if dcr.get(\"class\") not in (\"Workflow\", \"CommandLineTool\", \"ExpressionTool\"):\n            continue\n        dc = cast(Dict[Text, Any], copy.deepcopy(dcr))\n        v = rewrite[r]\n        dc[\"id\"] = v\n        for n in (\"name\", \"cwlVersion\", \"$namespaces\", \"$schemas\"):\n            if n in dc:\n                del dc[n]\n        packed[\"$graph\"].append(dc)\n\n    if schemas:\n        packed[\"$schemas\"] = list(schemas)\n\n    for r in rewrite:\n        v = rewrite[r]\n        replace_refs(packed, rewrite, r + \"/\" if \"#\" in r else r + \"#\", v + \"/\")\n\n    import_embed(packed, set())\n\n    if len(packed[\"$graph\"]) == 1:\n        # duplicate 'cwlVersion' inside $graph when there is a single item\n        # because we're printing contents inside '$graph' rather than whole dict\n        packed[\"$graph\"][0][\"cwlVersion\"] = packed[\"cwlVersion\"]\n    if namespaces:\n        packed[\"$graph\"][0][\"$namespaces\"] = dict(cast(Dict, namespaces))\n\n    return packed\n", "path": "cwltool/pack.py"}]}