/** @param globalScope a new Global Scope to replace the scope of references with. */
 public void updateReferencesWithGlobalScope(Scope globalScope) {
   for (ReferenceCollection collection : refMap.values()) {
     List<Reference> newRefs = new ArrayList<>(collection.references.size());
     for (Reference ref : collection.references) {
       if (ref.getScope() != globalScope) {
         newRefs.add(ref.cloneWithNewScope(globalScope));
       } else {
         newRefs.add(ref);
       }
     }
     collection.references = newRefs;
   }
 }
  private void removeScriptReferences(InputId inputId) {
    Preconditions.checkNotNull(inputId);

    if (!inputOrder.containsKey(inputId)) {
      return; // Input did not exist when last computed, so skip
    }
    // TODO(bashir): If this is too slow it is not too difficult to make it
    // faster with keeping an index for variables accessed in sourceName.
    for (ReferenceCollection collection : refMap.values()) {
      if (collection == null) {
        continue;
      }
      List<Reference> oldRefs = collection.references;
      SourceRefRange range = findSourceRefRange(oldRefs, inputId);
      List<Reference> newRefs = new ArrayList<>(range.refsBefore());
      newRefs.addAll(range.refsAfter());
      collection.references = newRefs;
    }
  }
  private boolean inlineAliasIfPossible(Name name, Ref alias, GlobalNamespace namespace) {
    // Ensure that the alias is assigned to a local variable at that
    // variable's declaration. If the alias's parent is a NAME,
    // then the NAME must be the child of a VAR node, and we must
    // be in a VAR assignment.
    Node aliasParent = alias.node.getParent();
    if (aliasParent.isName()) {
      // Ensure that the local variable is well defined and never reassigned.
      Scope scope = alias.scope;
      String aliasVarName = aliasParent.getString();
      Var aliasVar = scope.getVar(aliasVarName);

      ReferenceCollectingCallback collector =
          new ReferenceCollectingCallback(
              compiler,
              ReferenceCollectingCallback.DO_NOTHING_BEHAVIOR,
              Predicates.equalTo(aliasVar));
      collector.processScope(scope);

      ReferenceCollection aliasRefs = collector.getReferences(aliasVar);
      Set<AstChange> newNodes = new LinkedHashSet<>();

      if (aliasRefs.isWellDefined() && aliasRefs.firstReferenceIsAssigningDeclaration()) {
        if (!aliasRefs.isAssignedOnceInLifetime()) {
          // Static properties of constructors are always collapsed.
          // So, if a constructor is aliased and its properties are accessed from
          // the alias, we would like to inline the alias here to access the
          // properties correctly.
          // But if the aliased variable is assigned more than once, we can't
          // inline, so we warn.
          if (name.isConstructor()) {
            boolean accessPropsAfterAliasing = false;
            for (Reference ref : aliasRefs.references) {
              if (ref.getNode().getParent().isGetProp()) {
                accessPropsAfterAliasing = true;
                break;
              }
            }
            if (accessPropsAfterAliasing) {
              compiler.report(JSError.make(aliasParent, UNSAFE_CTOR_ALIASING, aliasVarName));
            }
          }
          return false;
        }

        // The alias is well-formed, so do the inlining now.
        int size = aliasRefs.references.size();
        for (int i = 1; i < size; i++) {
          ReferenceCollectingCallback.Reference aliasRef = aliasRefs.references.get(i);

          Node newNode = alias.node.cloneTree();
          aliasRef.getParent().replaceChild(aliasRef.getNode(), newNode);
          newNodes.add(new AstChange(getRefModule(aliasRef), aliasRef.getScope(), newNode));
        }

        // just set the original alias to null.
        aliasParent.replaceChild(alias.node, IR.nullNode());
        compiler.reportCodeChange();

        // Inlining the variable may have introduced new references
        // to descendants of {@code name}. So those need to be collected now.
        namespace.scanNewNodes(newNodes);
        return true;
      }
    }

    return false;
  }