def METHOD_NAME(
    frames, values, blaming_frame_idx, depth: Optional[int], direction, needs_in_app
):
    rv = []
    # subtract depth by one to count blaming frame
    if depth is not None:
        depth -= 1
    added = 0
    prev_was_prefix = values[blaming_frame_idx].is_prefix_frame
    idx = blaming_frame_idx + direction
    while 0 <= idx < len(values):
        component = values[idx]
        frame = frames[idx]
        idx += direction
        if not component.contributes:
            continue
        if needs_in_app and not frame["in_app"]:
            # XXX: At this and any other break/continue we should actually add
            # a non-contributing component to the tree, but that'd involve a
            # deepcopy and people can debug grouping via the system component
            # anyway.
            continue
        if prev_was_prefix:
            rv.append(component)
        else:
            if depth is not None and added == depth:
                break
            rv.append(component)
            added += 1
        prev_was_prefix = component.is_prefix_frame
    return rv