def _ro_aggregates(self):
        # type: () -> List[Dict[str, Any]]
        """Gather dictionary of files to be added to the manifest."""
        def guess_mediatype(rel_path):
            # type: (str) -> Dict[str, str]
            """Return the mediatypes."""
            media_types = {
                # Adapted from
                # https://w3id.org/bundle/2014-11-05/#media-types

                "txt": TEXT_PLAIN,
                "ttl": 'text/turtle; charset="UTF-8"',
                "rdf": 'application/rdf+xml',
                "json": 'application/json',
                "jsonld": 'application/ld+json',
                "xml": 'application/xml',
                ##
                "cwl": 'text/x+yaml; charset="UTF-8"',
                "provn": 'text/provenance-notation; charset="UTF-8"',
                "nt": 'application/n-triples',
            }
            conforms_to = {
                "provn": 'http://www.w3.org/TR/2013/REC-prov-n-20130430/',
                "cwl": 'https://w3id.org/cwl/',
            }

            prov_conforms_to = {
                "provn": 'http://www.w3.org/TR/2013/REC-prov-n-20130430/',
                "rdf": 'http://www.w3.org/TR/2013/REC-prov-o-20130430/',
                "ttl": 'http://www.w3.org/TR/2013/REC-prov-o-20130430/',
                "nt": 'http://www.w3.org/TR/2013/REC-prov-o-20130430/',
                "jsonld": 'http://www.w3.org/TR/2013/REC-prov-o-20130430/',
                "xml": 'http://www.w3.org/TR/2013/NOTE-prov-xml-20130430/',
                "json": 'http://www.w3.org/Submission/2013/SUBM-prov-json-20130424/',
            }


            extension = rel_path.rsplit(".", 1)[-1].lower()  # type: Optional[str]
            if extension == rel_path:
                # No ".", no extension
                extension = None

            local_aggregate = {}  # type: Dict[str, Any]
            if extension in media_types:
                local_aggregate["mediatype"] = media_types[extension]

            if extension in conforms_to:
                # TODO: Open CWL file to read its declared "cwlVersion", e.g.
                # cwlVersion = "v1.0"
                local_aggregate["conformsTo"] = conforms_to[extension]

            if (rel_path.startswith(_posix_path(PROVENANCE))
                    and extension in prov_conforms_to):
                if ".cwlprov" in rel_path:
                    # Our own!
                    local_aggregate["conformsTo"] = [prov_conforms_to[extension], CWLPROV_VERSION]
                else:
                    # Some other PROV
                    # TODO: Recognize ProvOne etc.
                    local_aggregate["conformsTo"] = prov_conforms_to[extension]
            return local_aggregate

        aggregates = [] # type: List[Dict]
        for path in self.bagged_size.keys():
            aggregate_dict = {}  # type: Dict[str, Any]

            (folder, filename) = posixpath.split(path)

            # NOTE: Here we end up aggregating the abstract
            # data items by their sha1 hash, so that it matches
            # the entity() in the prov files.

            # TODO: Change to nih:sha-256; hashes
            #  https://tools.ietf.org/html/rfc6920#section-7
            aggregate_dict["uri"] = 'urn:hash::sha1:' + filename
            aggregate_dict["bundledAs"] = {
                # The arcp URI is suitable ORE proxy; local to this Research Object.
                # (as long as we don't also aggregate it by relative path!)
                "uri": self.base_uri + path,
                # relate it to the data/ path
                "folder": "/%s/" % folder,
                "filename": filename,
            }
            if path in self._file_provenance:
                # Made by workflow run, merge captured provenance
                aggregate_dict["bundledAs"].update(self._file_provenance[path])
            else:
                # Probably made outside wf run, part of job object?
                pass
            if path in self._content_types:
                aggregate_dict["mediatype"] = self._content_types[path]

            aggregates.append(aggregate_dict)

        for path in self.tagfiles:
            if (not (path.startswith(METADATA) or path.startswith(WORKFLOW) or
                     path.startswith(SNAPSHOT))):
                # probably a bagit file
                continue
            if path == posixpath.join(METADATA, "manifest.json"):
                # Should not really be there yet! But anyway, we won't
                # aggregate it.
                continue

            rel_aggregates = {} # type: Dict[str, Any]
            # These are local paths like metadata/provenance - but
            # we need to relativize them for our current directory for
            # as we are saved in metadata/manifest.json
            uri = posixpath.relpath(path, METADATA)

            rel_aggregates["uri"] = uri
            rel_aggregates.update(guess_mediatype(path))

            if path in self._file_provenance:
                # Propagate file provenance (e.g. timestamp)
                rel_aggregates.update(self._file_provenance[path])
            elif not path.startswith(SNAPSHOT):
                # make new timestamp?
                rel_aggregates.update(self._self_made())
            aggregates.append(rel_aggregates)
        aggregates.extend(self._external_aggregates)
        return aggregates
Gather dictionary of files to be added to the manifest.