Populates (from the given trace graph) the forward and backward
        traces reachable from the given traces (including input trace frames).
        Make sure to respect trace kind in successors

def _populate_trace(self, graph: TraceGraph, trace_frame_ids: List[int]) -> None:
        """ Populates (from the given trace graph) the forward and backward
        traces reachable from the given traces (including input trace frames).
        Make sure to respect trace kind in successors
        """
        while len(trace_frame_ids) > 0:
            trace_frame_id = trace_frame_ids.pop()
            if trace_frame_id in self._visited_trace_frame_ids:
                continue

            trace_frame = graph._trace_frames[trace_frame_id]
            self._add_trace_frame(graph, trace_frame)
            self._visited_trace_frame_ids.add(trace_frame_id)

            key = (trace_frame.callee_id.local_id, trace_frame.callee_port)
            trace_frame_ids.extend(
                [
                    trace_frame_id
                    for trace_frame_id in graph._trace_frames_map[key]
                    if trace_frame_id not in self._visited_trace_frame_ids
                    and graph._trace_frames[trace_frame_id].kind == trace_frame.kind
                ]
            )