canUseInReferencedScopes(binding, next) {
    const tracker = this;

    if (tracker.hasBindingOrReference(binding.scope, binding, next)) {
      return false;
    }

    // Safari raises a syntax error for a `let` or `const` declaration in a
    // `for` loop initialization that shadows a parent function's parameter.
    // https://github.com/babel/minify/issues/559
    // https://bugs.webkit.org/show_bug.cgi?id=171041
    // https://trac.webkit.org/changeset/217200/webkit/trunk/Source
    const maybeDecl = binding.path.parentPath;
    const isBlockScoped =
      maybeDecl.isVariableDeclaration({ kind: "let" }) ||
      maybeDecl.isVariableDeclaration({ kind: "const" });
    if (isBlockScoped) {
      const maybeFor = maybeDecl.parentPath;
      const isForLoopBinding =
        maybeFor.isForStatement({ init: maybeDecl.node }) ||
        maybeFor.isForXStatement({ left: maybeDecl.node });
      if (isForLoopBinding) {
        const fnParent = getFunctionParent(maybeFor);
        if (fnParent.isFunction({ body: maybeFor.parent })) {
          const parentFunctionBinding = this.bindings
            .get(fnParent.scope)
            .get(next);
          if (parentFunctionBinding) {
            const parentFunctionHasParamBinding =
              parentFunctionBinding.kind === "param";
            if (parentFunctionHasParamBinding) {
              return false;
            }
          }
        }
      }
    }

    for (let i = 0; i < binding.constantViolations.length; i++) {
      const violation = binding.constantViolations[i];
      if (tracker.hasBindingOrReference(violation.scope, binding, next)) {
        return false;
      }
    }

    for (let i = 0; i < binding.referencePaths.length; i++) {
      const ref = binding.referencePaths[i];
      if (!ref.isIdentifier()) {
        let canUse = true;
        ref.traverse({
          ReferencedIdentifier(path) {
            if (path.node.name !== next) return;
            if (tracker.hasBindingOrReference(path.scope, binding, next)) {
              canUse = false;
            }
          }
        });
        if (!canUse) {
          return canUse;
        }
      } else if (!isLabelIdentifier(ref)) {
        if (tracker.hasBindingOrReference(ref.scope, binding, next)) {
          return false;
        }
      }
    }

    return true;
  }
For a Binding visit all places where the Binding is used and detect
if the newName {next} can be used in all these places

1. binding's own scope
2. constant violations' scopes
3. referencePaths' scopes

@param {Binding} binding
@param {String} next