def get_branch_list(nodes, exit_index):
  """Computes the branch list for the control flow graph.

  Args:
    nodes: A list of control_flow.ControlFlowNodes.
    exit_index: The index of the exit node.
  Returns:
    A Python list representing the branch options available from each node. Each
    entry in the list corresponds to a node in the control flow graph, with the
    final entry corresponding to the exit node (not present in the cfg). Each
    entry is a 2-tuple indicating the next node reached by the True and False
    branch respectively (these may be the same.) The exit node leads to itself
    along both branches.
  """
  indexes_by_id = {
      id(node): index for index, node in enumerate(nodes)
  }
  indexes_by_id[id(None)] = exit_index
  branches = []
  for node in nodes:
    node_branches = node.branches
    if node_branches:
      branches.append([indexes_by_id[id(node_branches[True])],
                       indexes_by_id[id(node_branches[False])]])
    else:
      try:
        next_node = next(iter(node.next))
        next_index = indexes_by_id[id(next_node)]
      except StopIteration:
        next_index = exit_index
      branches.append([next_index, next_index])

  # Finally we add branches from the exit node to itself.
  # Omit this if running on BasicBlocks rather than ControlFlowNodes, because
  # ControlFlowGraphs have an exit BasicBlock, but no exit ControlFlowNodes.
  branches.append([exit_index, exit_index])
  return branches