Annotate this graph, returning an AnnotatedGraph object
        with the same structure.

def annotated(self):
        """
        Annotate this graph, returning an AnnotatedGraph object
        with the same structure.

        """
        # Build up dictionary of edge annotations.
        edge_annotations = {}
        for edge in self.edges:
            if edge not in edge_annotations:
                # We annotate all edges from a given object at once.
                referrer = self._tail[edge]
                known_refs = annotated_references(referrer)
                for out_edge in self._out_edges[referrer]:
                    referent = self._head[out_edge]
                    if known_refs[referent]:
                        annotation = known_refs[referent].pop()
                    else:
                        annotation = None
                    edge_annotations[out_edge] = annotation

        annotated_vertices = [
            AnnotatedVertex(
                id=id(vertex),
                annotation=object_annotation(vertex),
            )
            for vertex in self.vertices
        ]

        annotated_edges = [
            AnnotatedEdge(
                id=edge,
                annotation=edge_annotations[edge],
                head=id(self._head[edge]),
                tail=id(self._tail[edge]),
            )
            for edge in self.edges
        ]

        return AnnotatedGraph(
            vertices=annotated_vertices,
            edges=annotated_edges,
        )