nodes: 0, module; 1, function_definition; 2, function_name:_merge_points; 3, parameters; 4, block; 5, identifier:self; 6, identifier:function_address; 7, expression_statement; 8, comment:# we are entering a new function. now it's time to figure out how to optimally traverse the control flow; 9, comment:# graph by generating the sorted merge points; 10, try_statement; 11, if_statement; 12, return_statement; 13, comment:"""
          Return the ordered merge points for a specific function.
  
          :param int function_address: Address of the querying function.
          :return: A list of sorted merge points (addresses).
          :rtype: list
          """; 14, block; 15, except_clause; 16, comparison_operator:function_address not in self._function_merge_points; 17, block; 18, subscript; 19, expression_statement; 20, identifier:KeyError; 21, comment:# the function does not exist; 22, block; 23, identifier:function_address; 24, attribute; 25, expression_statement; 26, expression_statement; 27, attribute; 28, identifier:function_address; 29, assignment; 30, return_statement; 31, identifier:self; 32, identifier:_function_merge_points; 33, assignment; 34, assignment; 35, identifier:self; 36, identifier:_function_merge_points; 37, identifier:new_function; 38, subscript; 39, list; 40, identifier:ordered_merge_points; 41, call; 42, subscript; 43, identifier:ordered_merge_points; 44, attribute; 45, identifier:function_address; 46, attribute; 47, argument_list; 48, attribute; 49, identifier:function_address; 50, attribute; 51, identifier:functions; 52, identifier:CFGUtils; 53, identifier:find_merge_points; 54, identifier:function_address; 55, attribute; 56, attribute; 57, identifier:self; 58, identifier:_function_merge_points; 59, identifier:self; 60, identifier:kb; 61, identifier:new_function; 62, identifier:endpoints; 63, identifier:new_function; 64, identifier:graph
code: def _merge_points(self, function_address):
          """
          Return the ordered merge points for a specific function.
  
          :param int function_address: Address of the querying function.
          :return: A list of sorted merge points (addresses).
          :rtype: list
          """
  
          # we are entering a new function. now it's time to figure out how to optimally traverse the control flow
          # graph by generating the sorted merge points
          try:
              new_function = self.kb.functions[function_address]
          except KeyError:
              # the function does not exist
              return [ ]
  
          if function_address not in self._function_merge_points:
              ordered_merge_points = CFGUtils.find_merge_points(function_address, new_function.endpoints,
                                                             new_function.graph)
              self._function_merge_points[function_address] = ordered_merge_points
  
          return self._function_merge_points[function_address]