/**
     * Check whether the new definition will either conflict with or shadow an existing definition
     */
    private List<PhotranTokenRef> findReferencesToShadowedDefinitions() {
      List<PhotranTokenRef> referencesToShadowedDefinitions = new LinkedList<PhotranTokenRef>();

      for (String newName : newNames) {
        Token token =
            definitionToCheck == null
                ? new FakeToken(scopeOfDefinitionToCheck, newName)
                : new FakeToken(definitionToCheck.getTokenRef().findToken(), newName);

        List<PhotranTokenRef> shadowedDefinitions = scopeOfDefinitionToCheck.manuallyResolve(token);
        // TODO: Does not consider rename or only lists (need to tell if this SPECIFIC definition
        // will be imported)
        for (ScopingNode importingScope : scopeOfDefinitionToCheck.findImportingScopes()) {
          pm.subTask(
              Messages.bind(
                  Messages.FortranResourceRefactoring_CheckingForReferencesTo,
                  newName,
                  importingScope.describe()));
          shadowedDefinitions.addAll(importingScope.manuallyResolve(token));
        }

        for (PhotranTokenRef def : shadowedDefinitions) {
          Definition definition = PhotranVPG.getInstance().getDefinitionFor(def);
          if (definition != null)
            referencesToShadowedDefinitions.addAll(definition.findAllReferences(false));
        }
      }

      return referencesToShadowedDefinitions;
    }
  private void permuteSubroutineInInterfaceBlocks() {
    for (Definition declaration : getInterfaceDeclarations()) {
      ASTSubroutineStmtNode subroutineStmt =
          declaration.getTokenRef().findToken().findNearestAncestor(ASTSubroutineStmtNode.class);

      if (subroutineStmt != null
          && subroutineStmt.getSubroutinePars() != null
          && subroutineStmt.getSubroutinePars().size() == newParameterList.size())
        permuteDummyArguments(subroutineStmt);
    }
  }
    /**
     * Cannot call a function X if it is defined in or imported into a scope with a function X
     * already defined
     *
     * <p>The third parameter indicates whether or not we should check that the definition to check
     * is actually imported into the target scope (it may not be if there is a USE statement with a
     * Rename or ONLY list).
     */
    private void findAllPotentiallyConflictingDefinitionsInScope(
        List<Conflict> conflicts,
        ScopingNode importingScope,
        boolean shouldCheckIfDefinitionImportedIntoScope) {
      for (String newName : newNames) {
        List<PhotranTokenRef> definitionsLocalToScope = collectLocalDefinitions(importingScope);

        if (isProgramOrSubprogramOrModuleScope(importingScope)
            && shouldCheckIfDefinitionImportedIntoScope) {
          // Cannot call a variable X inside a function named X
          if (importingScope.isNamed(newName)) {
            if (definitionToCheck == null
                || definitionsLocalToScope.contains(definitionToCheck.getTokenRef())) {
              conflicts.add(new Conflict(newName, importingScope.getNameToken().getTokenRef()));
            }
          }
          // Cannot call a variable X inside a function named Y inside a module named X
          else {
            ScopingNode parent = importingScope.findNearestAncestor(ScopingNode.class);
            if (parent != null && parent.isNamed(newName)) {
              List<PhotranTokenRef> definitionsLocalToParent = collectLocalDefinitions(parent);
              if (definitionToCheck == null
                  || definitionsLocalToParent.contains(definitionToCheck.getTokenRef())) {
                conflicts.add(new Conflict(newName, parent.getNameToken().getTokenRef()));
              }
            }
          }
        }

        // Cannot call a function X if it is defined in or imported into a scope with a function X
        // already defined
        Token newNameToken =
            definitionToCheck == null
                ? new FakeToken(scopeOfDefinitionToCheck, newName)
                : new FakeToken(definitionToCheck.getTokenRef().findToken(), newName);
        for (PhotranTokenRef conflict : importingScope.manuallyResolveInLocalScope(newNameToken)) {
          if (definitionsLocalToScope.contains(conflict)) {
            if (shouldCheckIfDefinitionImportedIntoScope) {
              if (definitionToCheck == null
                  || definitionsLocalToScope.contains(definitionToCheck.getTokenRef())) {
                conflicts.add(new Conflict(newName, conflict));
              }
            } else {
              conflicts.add(new Conflict(newName, conflict));
            }
          }
        }
      }
    }
 public CheckForConflictBindings(
     Definition definitionToCheck,
     Collection<PhotranTokenRef> allReferences,
     Collection<String> newNames) {
   this.definitionToCheck = definitionToCheck;
   this.scopeOfDefinitionToCheck =
       definitionToCheck.getTokenRef().findToken().getEnclosingScope();
   this.allReferences = allReferences;
   this.newNames = newNames;
 }
    private List<Conflict> findAllPotentiallyConflictingDefinitions() {
      List<Conflict> conflicts = new ArrayList<Conflict>();

      if (definitionToCheck != null) {
        // Cannot call a main program (or function, etc.) X if it has an internal subprogram named
        // X,
        // even if that subprogram is never used (in which case it wouldn't be caught below)
        if (definitionToCheck.isMainProgram()
            || definitionToCheck.isSubprogram()
            || definitionToCheck.isModule()) {
          findAllPotentiallyConflictingDefinitionsInScope(
              conflicts,
              definitionToCheck.getTokenRef().findToken().findNearestAncestor(ScopingNode.class),
              false);
        }
        for (String newName : newNames) {
          if (definitionToCheck.isInternalSubprogramDefinition()
              && scopeContainingInternalSubprogram().isNamed(newName)) {
            conflicts.add(
                new Conflict(
                    newName, scopeContainingInternalSubprogram().getNameToken().getTokenRef()));
          }
        }
      }

      for (ScopingNode importingScope :
          scopeItselfAndAllScopesThatImport(scopeOfDefinitionToCheck)) {
        pm.subTask(
            Messages.bind(
                Messages.FortranResourceRefactoring_CheckingForConflictingDefinitionsIn,
                importingScope.describe()));
        findAllPotentiallyConflictingDefinitionsInScope(conflicts, importingScope, true);
      }

      return conflicts;
    }
  private boolean matchingDeclarationsInInterfacesUniquelyBind() {
    for (Definition declaration : getInterfaceDeclarations())
      if (declaration.resolveInterfaceBinding().size() != 1) return false;

    return true;
  }
 private ScopingNode scopeContainingInternalSubprogram() {
   return definitionToCheck.getTokenRef().findToken().getEnclosingScope();
 }
 private List<PhotranTokenRef> collectLocalDefinitions(ScopingNode importingScope) {
   List<PhotranTokenRef> definitionsLocalToScope = new ArrayList<PhotranTokenRef>();
   for (Definition def : importingScope.getAllDefinitions())
     if (def != null && !def.isIntrinsic()) definitionsLocalToScope.add(def.getTokenRef());
   return definitionsLocalToScope;
 }