def param_space(s, step, param_name, param_space):
    """Spins out new copies of the step across the parameter space.

    For example, for a graph like this::

        +-----+    +-----------+    +-----------+
        | foo | -> |    bar    | -> |    baz    |
        |     |    | ( p = 1 ) |    |           |
        +-----+    +-----------+    +-----------+

    this call:

    .. code-block:: python

        g = Graph()
        (...)
        g.param_space( 'bar', 'p', [ 1, 2, 3 ] )

    will be transformed into a graph like this::

                    +-----------+    +-----------+
                +-> |  bar-p-1  | -> |  baz-p-1  |
                |   | ( p = 1 ) |    |           |
                |   +-----------+    +-----------+
        +-----+ |   +-----------+    +-----------+
        | foo | --> |  bar-p-2  | -> |  baz-p-2  |
        |     | |   | ( p = 2 ) |    |           |
        +-----+ |   +-----------+    +-----------+
                |   +-----------+    +-----------+
                +-> |  bar-p-3  | -> |  baz-p-3  |
                    | ( p = 3 ) |    |           |
                    +-----------+    +-----------+

    Args:
      step        : A string for the step name targeted for expansion
      param_name  : A string for the parameter name
      param_space : A list of parameter values to expand to

    Returns:
      A list of (parameterized) steps (i.e., 'bar-p-1', 'bar-p-2', and
      'bar-p-3').
    """
    if type(step) != str:
        step_name = step.get_name()
    else:
        step_name = step
        step = s.get_step(step_name)
    assert step_name in s.all_steps(
        ), 'param_space -- Step "{}" not found in graph'.format(step_name)
    del s._steps[step_name]
    elist_i = s._param_space_helper_remove_incoming_edges(step_name)
    new_steps = []
    for p in param_space:
        p_step = step.clone()
        p_step.set_param(param_name, p)
        p_step.set_name(step_name + '-' + param_name + '-' + str(p))
        s.add_step(p_step)
        for e in elist_i:
            src_step_name, src_f = e.get_src()
            dst_step_name, dst_f = e.get_dst()
            src_step = s.get_step(src_step_name)
            s.connect(src_step.o(src_f), p_step.i(dst_f))
        new_steps.append(p_step)
    new_src_map = {step_name: new_steps}
    dep_steps = s._param_space_helper_get_dependent_steps(step_name)
    dep_steps = s.topological_sort(seed_steps=dep_steps)
    visited = set()
    for dep_step in dep_steps:
        s._param_space_helper(step_name=dep_step, new_src_map=new_src_map,
            visited=visited, param_name=param_name, param_space=param_space)
    return new_steps
