def _merge_prims(prims, *, debug=False, stagenames=None, stages=None):
    """Helper method to greedily combine Frames (of Primitives) or Primitives based on the rules defined in the Primitive's class.

    Used by a CommandQueue during compilation and optimization of
    Primitives.

    Args:
        prims: A list or FrameSequence of Primitives or Frames (respectively) to try to merge together.
        debug: A boolean for if debug information should be generated.
        stages: A list to be edited by this method to store snapshots of the compilation state. Used if debug is True.
        stagenames: A list of strings describing each debug snapshot of the compiilation process. Used if debug is True.

    Returns:
        A list or FrameSequence (the same type as prims) of the compined Primitives or Frames.
    """
    if isinstance(prims, FrameSequence):
        merged_prims = FrameSequence(prims._chain)
    else:
        merged_prims = []
    working_prim = prims[0]
    i = 1
    logging_tmp = []

    while i < len(prims):
        tmp = prims[i]
        res = working_prim.merge(tmp)
        if res is not None:
            working_prim = res
            if debug:#pragma: no cover
                logging_tmp.append(
                    [p.snapshot() for p in
                     merged_prims+[working_prim]])
        else:
            merged_prims.append(working_prim)
            working_prim = tmp
        i += 1
    merged_prims.append(working_prim)
    if debug:#pragma: no cover
        stages.append(logging_tmp)
        stagenames.append("Merge intermediate states")

    return merged_prims