protected static IASTNode findEnclosingNode(IFortranAST ast, ITextSelection selection) {
    Token firstToken = findFirstTokenAfter(ast, selection.getOffset());
    Token lastToken =
        findLastTokenBefore(
            ast, OffsetLength.getPositionPastEnd(selection.getOffset(), selection.getLength()));
    if (firstToken == null || lastToken == null) return null;

    for (IASTNode parent = lastToken.getParent(); parent != null; parent = parent.getParent())
      if (contains(parent, firstToken)) return parent;

    return null;
  }
  protected static boolean nodeExactlyEnclosesRegion(
      IASTNode node, IFortranAST ast, ITextSelection selection) {
    Token firstInNode = node.findFirstToken();
    Token lastInNode = node.findLastToken();

    Token firstInSel = findFirstTokenAfter(ast, selection.getOffset());
    Token lastInSel =
        findLastTokenBefore(
            ast, OffsetLength.getPositionPastEnd(selection.getOffset(), selection.getLength()));

    return firstInNode != null
        && lastInNode != null
        && firstInSel != null
        && lastInSel != null
        && firstInNode == firstInSel
        && lastInNode == lastInSel;
  }
 protected static Token findEnclosingToken(IFortranAST ast, final ITextSelection selection) {
   Token prevToken = null;
   for (Token token : new IterableWrapper<Token>(ast)) {
     if (OffsetLength.contains(
         token.getFileOffset(), token.getLength(),
         selection.getOffset(), selection.getLength())) {
       String tokenText = token.getText();
       // If we get whitespace, that means we want the previous token (cursor was put AFTER
       // the identifier we want to rename
       if (tokenText.length() == 1 && Character.isWhitespace(tokenText.charAt(0))) {
         return prevToken;
       } else return token;
     }
     prevToken = token;
   }
   return null;
 }