code: private void populateDatastructuresForAnalysisTraversal(ReferenceMap referenceMap) {
      // Merge the prop and name references into a single multimap since only the name matters.
      ArrayListMultimap<String, Node> referencesByName = ArrayListMultimap.create();
      for (Map.Entry<String, ? extends List<Node>> entry : referenceMap.getNameReferences()) {
        referencesByName.putAll(entry.getKey(), entry.getValue());
      }
      for (Map.Entry<String, ? extends List<Node>> entry : referenceMap.getPropReferences()) {
        referencesByName.putAll(PROP_NAME_PREFIX + entry.getKey(), entry.getValue());
      }
      // Empty function names cause a crash during analysis that is better to detect here.
      // Additionally, functions require a name to be invoked in a statically analyzable way; there's
      // no value in tracking the set of anonymous functions.
      checkState(!referencesByName.containsKey(""));
      checkState(!referencesByName.containsKey(PROP_NAME_PREFIX));
  
      // Create and store a summary for all known names.
      for (String name : referencesByName.keySet()) {
        summariesByName.put(name, AmbiguatedFunctionSummary.createInGraph(reverseCallGraph, name));
      }
  
      Multimaps.asMap(referencesByName).forEach(this::populateFunctionDefinitions);
    }
docs: Fill all of the auxiliary data-structures used by this pass based on the results in {@code
  referenceMap}.
  
  <p>This is the first step of analysis. These structures will be used by a traversal that
  analyzes the bodies of located functions for side-effects. That traversal is separate because
  it needs access to scopes and also depends on global knowledge of functions.