nodes: 0, module; 1, function_definition; 2, function_name:reference_cluster; 3, parameters; 4, block; 5, identifier:envs; 6, identifier:name; 7, expression_statement; 8, expression_statement; 9, expression_statement; 10, while_statement; 11, return_statement; 12, comment:"""
      Return set of all env names referencing or
      referenced by given name.
  
      >>> cluster = sorted(reference_cluster([
      ...     {'name': 'base', 'refs': []},
      ...     {'name': 'test', 'refs': ['base']},
      ...     {'name': 'local', 'refs': ['test']},
      ... ], 'test'))
      >>> cluster == ['base', 'local', 'test']
      True
      """; 13, assignment; 14, assignment; 15, comparison_operator:prev != cluster; 16, comment:# While cluster grows; 17, block; 18, identifier:cluster; 19, identifier:edges; 20, list_comprehension; 21, pattern_list; 22, expression_list; 23, identifier:prev; 24, identifier:cluster; 25, expression_statement; 26, expression_statement; 27, for_statement; 28, expression_statement; 29, call; 30, for_in_clause; 31, for_in_clause; 32, identifier:prev; 33, identifier:cluster; 34, call; 35, call; 36, assignment; 37, assignment; 38, identifier:edge; 39, identifier:edges; 40, block; 41, assignment; 42, identifier:set; 43, argument_list; 44, identifier:env; 45, identifier:envs; 46, identifier:ref; 47, subscript; 48, identifier:set; 49, argument_list; 50, identifier:set; 51, argument_list; 52, identifier:prev; 53, call; 54, identifier:to_visit; 55, list; 56, if_statement; 57, identifier:edges; 58, identifier:to_visit; 59, list; 60, identifier:env; 61, string; 62, list; 63, identifier:set; 64, argument_list; 65, binary_operator:cluster & edge; 66, comment:# Add adjacent nodes:; 67, block; 68, else_clause; 69, subscript; 70, identifier:ref; 71, string_content:refs; 72, identifier:name; 73, identifier:cluster; 74, identifier:cluster; 75, identifier:edge; 76, expression_statement; 77, comment:# Leave only edges that are out; 78, comment:# of cluster for the next round:; 79, block; 80, identifier:env; 81, string; 82, augmented_assignment; 83, expression_statement; 84, string_content:name; 85, identifier:cluster; 86, identifier:edge; 87, call; 88, attribute; 89, argument_list; 90, identifier:to_visit; 91, identifier:append; 92, identifier:edge
code: def reference_cluster(envs, name):
      """
      Return set of all env names referencing or
      referenced by given name.
  
      >>> cluster = sorted(reference_cluster([
      ...     {'name': 'base', 'refs': []},
      ...     {'name': 'test', 'refs': ['base']},
      ...     {'name': 'local', 'refs': ['test']},
      ... ], 'test'))
      >>> cluster == ['base', 'local', 'test']
      True
      """
      edges = [
          set([env['name'], ref])
          for env in envs
          for ref in env['refs']
      ]
      prev, cluster = set(), set([name])
      while prev != cluster:
          # While cluster grows
          prev = set(cluster)
          to_visit = []
          for edge in edges:
              if cluster & edge:
                  # Add adjacent nodes:
                  cluster |= edge
              else:
                  # Leave only edges that are out
                  # of cluster for the next round:
                  to_visit.append(edge)
          edges = to_visit
      return cluster