Args:
        workflow: optional collection of steps
        leaf: only include leaves of the workflow

    Returns: If workflow is specified, returns output directories for all target
        steps in the workflow. If no workflow specified, returns all extant
        output directories in drain.PATH.

def _output_dirnames(workflow=None, leaf=False):
    """
    Args:
        workflow: optional collection of steps
        leaf: only include leaves of the workflow

    Returns: If workflow is specified, returns output directories for all target
        steps in the workflow. If no workflow specified, returns all extant
        output directories in drain.PATH.
    """
    if workflow is None:
        dirs = set()
        for cls in os.listdir(drain.PATH):
            for step in os.listdir(os.path.join(drain.PATH, cls)):
                dirs.add(os.path.join(drain.PATH, cls, step))
        return dirs
    else:
        if leaf:
            steps = [step for step in workflow if step.target]
        else:
            steps = util.union(step.get_inputs() for step in workflow if step.target)

        return set(step._output_dirname for step in steps)