code: def construct(start_block, vmap, exceptions):
      
      bfs_blocks = bfs(start_block)
  
      graph = Graph()
      gen_ret = GenInvokeRetName()
  
      # Construction of a mapping of basic blocks into Nodes
      block_to_node = {}
  
      exceptions_start_block = []
      for exception in exceptions:
          for _, _, block in exception.exceptions:
              exceptions_start_block.append(block)
  
      for block in bfs_blocks:
          node = make_node(graph, block, block_to_node, vmap, gen_ret)
          graph.add_node(node)
  
      graph.entry = block_to_node[start_block]
      del block_to_node, bfs_blocks
  
      graph.compute_rpo()
      graph.number_ins()
  
      for node in graph.rpo:
          preds = [pred for pred in graph.all_preds(node) if pred.num < node.num]
          if preds and all(pred.in_catch for pred in preds):
              node.in_catch = True
  
      # Create a list of Node which are 'return' node
      # There should be one and only one node of this type
      # If this is not the case, try to continue anyway by setting the exit node
      # to the one which has the greatest RPO number (not necessarily the case)
      lexit_nodes = [node for node in graph if node.type.is_return]
  
      if len(lexit_nodes) > 1:
          # Not sure that this case is possible...
          logger.error('Multiple exit nodes found !')
          graph.exit = graph.rpo[-1]
      elif len(lexit_nodes) < 1:
          # A method can have no return if it has throw statement(s) or if its
          # body is a while(1) whitout break/return.
          logger.debug('No exit node found !')
      else:
          graph.exit = lexit_nodes[0]
  
      return graph
docs: Constructs a CFG
  
      :param androguard.core.analysis.analysis.DVMBasicBlock start_block: The startpoint
      :param vmap: variable mapping
      :param exceptions: list of androguard.core.analysis.analysis.ExceptionAnalysis
  
      :rtype: Graph