<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def reachable_nodes(self, p_id, p_recursive=True, p_reverse=False):
 """ Returns the set of all neighbors that the given node can reach. If recursive, it will also return the neighbor's neighbors, etc. If reverse, the arrows are reversed and then the reachable neighbors are located. """

        stack = [p_id]
        visited = set()
        result = set()

        while len(stack):
            current = stack.pop()

            if current in visited or current not in self._edges:
                continue

            visited.add(current)

            if p_reverse:
                parents = [node for node, neighbors in self._edges.items()
                           if current in neighbors]

                stack = stack + parents
                result = result.union(parents)
            else:
                stack = stack + list(self._edges[current])
                result = result.union(self._edges[current])

            if not p_recursive:
                break

        return result