def compute_itersets(self, cgraph):
        """Return a list of all components required to run a full
        iteration of this driver.
        """
        self._full_iter_set = set()

        comps = [getattr(self.parent, n) for n in self.workflow._explicit_names]
        subdrivers = [c for c in comps if has_interface(c, IDriver)]
        subnames = [s.name for s in subdrivers]

        allcomps = [getattr(self.parent, n) for n in cgraph if not n == self.name]
        alldrivers = [c.name for c in allcomps if has_interface(c, IDriver)]

        # make our own copy of the graph to play with
        cgraph = cgraph.subgraph([n for n in cgraph
                                if n not in alldrivers or n in subnames])

        myset = set(self.workflow._explicit_names +
                    self.list_pseudocomps())

        # First, have all of our subdrivers (recursively) determine
        # their iteration sets, because we need those to determine
        # our full set.
        subcomps = set()
        for comp in subdrivers:
            cgcopy = cgraph.subgraph(cgraph.nodes_iter())
            comp.compute_itersets(cgcopy)
            subcomps.update(comp._full_iter_set)

        # create fake edges to/from the driver and each of its
        # components so we can get everything that's relevant
        # by getting all nodes that are strongly connected to the
        # driver in the graph.
        for drv in subdrivers:
            for name in drv._full_iter_set:
                cgraph.add_edge(drv.name, name)
                cgraph.add_edge(name, drv.name)

        # add predecessors to my pseudocomps if they aren't
        # already in the itersets of my subdrivers
        for pcomp in self.list_pseudocomps():
            for pred in cgraph.predecessors(pcomp):
                if pred not in subcomps:
                    myset.add(pred)

        # now create fake edges from us to all of the comps
        # that we know about in our iterset
        for name in myset:
            cgraph.add_edge(self.name, name)
            cgraph.add_edge(name, self.name)

        # collapse our explicit subdrivers
        self._iter_set = self.workflow._explicit_names
        self._collapse_subdrivers(cgraph)

        comps = []
        for comps in strongly_connected_components(cgraph):
            if self.name in comps:
                break

        self._iter_set = set(comps)
        self._iter_set.remove(self.name)

        # the following fixes a test failure when using DOEdriver with
        # an empty workflow.  This adds any comps that own DOEdriver
        # parameters to the DOEdriver's iteration set.
        conns = self.get_expr_depends()
        self._iter_set.update([u for u,v in conns if u != self.name and u not in subcomps])
        self._iter_set.update([v for u,v in conns if v != self.name and v not in subcomps])

        old_iter = self._iter_set.copy()

        # remove any drivers that were not explicitly specified in our worklow
        self._iter_set = set([c for c in self._iter_set if c not in alldrivers
                                or c in subnames])

        diff = old_iter - self._iter_set
        if diff:
            self._logger.warning("Driver '%s' had the following subdrivers removed"
                                 " from its workflow because they were not explicity"
                                 " added: %s" % (self.name, list(diff)))

        self._full_iter_set.update(self._iter_set)
        self._full_iter_set.update(subcomps)
dataset/ETHPy150Open OpenMDAO/OpenMDAO-Framework/openmdao.main/src/openmdao/main/driver.py/Driver.compute_itersets/original