anchor.diff:        builder.endSelectionFromEnd(text.length - end);
       }
     }
  +
  +  /// Returns the number of characters past [offset] in the source where the
  +  /// selection start appears if it appears before `offset + length`.
  +  ///
  +  /// Returns `null` if the selection start has already been processed or is
  +  /// not within that range.
  +  int _getSelectionStartWithin(int offset, int length) {
  +    // If there is no selection, do nothing.
  +    if (_source.selectionStart == null) return null;
  +
  +    // If we've already passed it, don't consider it again.
  +    if (_passedSelectionStart) return null;
  +
  +    var start = _source.selectionStart - offset;
  +
  +    // If it started in whitespace before this text, push it forward to the
  +    // beginning of the non-whitespace text.
  +    if (start < 0) start = 0;
  +
  +    // If we haven't reached it yet, don't consider it.
  +    if (start >= length) return null;
  +
  +    // We found it.
  +    _passedSelectionStart = true;
  +
  +    return start;
  +  }
  +
  +  /// Returns the number of characters past [offset] in the source where the
  +  /// selection endpoint appears if it appears before `offset + length`.
  +  ///
  +  /// Returns `null` if the selection endpoint has already been processed or is
  +  /// not within that range.
  +  int _getSelectionEndWithin(int offset, int length) {
  +    // If there is no selection, do nothing.
  +    if (_source.selectionLength == null) return null;
  +
  +    // If we've already passed it, don't consider it again.
  +    if (_passedSelectionEnd) return null;
  +
  +    var end = _findSelectionEnd() - offset;
  +
  +    // If it started in whitespace before this text, push it forward to the
  +    // beginning of the non-whitespace text.
  +    if (end < 0) end = 0;
  +
  +    // If we haven't reached it yet, don't consider it.
  +    if (end > length) return null;
  +
  +    if (end == length && _findSelectionEnd() == _source.selectionStart) {
  +      return null;
  +    }
  +
  +    // We found it.
  +    _passedSelectionEnd = true;
  +
  +    return end;
  +  }
  +
  +  /// Calculates the character offset in the source text of the end of the
  +  /// selection.
  +  ///
  +  /// Removes any trailing whitespace from the selection.
  +  int _findSelectionEnd() {
  +    if (_selectionEnd != null) return _selectionEnd;
  +
  +    _selectionEnd = _source.selectionStart + _source.selectionLength;
  +
  +    // If the selection bumps to the end of the source, pin it there.
  +    if (_selectionEnd == _source.text.length) return _selectionEnd;
  +
  +    // Trim off any trailing whitespace. We want the selection to "rubberband"
  +    // around the selected non-whitespace tokens since the whitespace will
  +    // be munged by the formatter itself.
  +    while (_selectionEnd > _source.selectionStart) {
  +      // Stop if we hit anything other than space, tab, newline or carriage
  +      // return.
  +      var char = _source.text.codeUnitAt(_selectionEnd - 1);
  +      if (char != 0x20 && char != 0x09 && char != 0x0a && char != 0x0d) {
  +        break;
  +      }
  +
  +      _selectionEnd--;
  +    }
  +
  +    return _selectionEnd;
  +  }
  +
  +  /// Gets the 1-based line number that the beginning of [token] lies on.
  +  int _startLine(Token token) => _lineInfo.getLocation(token.offset).lineNumber;
  +
  +  /// Gets the 1-based line number that the end of [token] lies on.
  +  int _endLine(Token token) => _lineInfo.getLocation(token.end).lineNumber;
  +
  +  /// Gets the 1-based column number that the beginning of [token] lies on.
  +  int _startColumn(Token token) =>
  +      _lineInfo.getLocation(token.offset).columnNumber;
   }
  
positive.code:     builder.unnest();
    }
  
    visitInstanceCreationExpression(InstanceCreationExpression node) {
      builder.startSpan();
      token(node.keyword);
  
negative.code:     if (body is ExpressionFunctionBody) builder.unnest();
    }
  
    /// Visits the body statement of a `for`, `for in`, or `while` loop.
    void _visitLoopBody(Statement body) {
      if (body is EmptyStatement) {
        // No space before the ";".
        visit(body);
      } else if (body is Block) {
        space();
        visit(body);
      } else {
        // Allow splitting in a statement-bodied loop even though it's against
        // the style guide. Since we can't fix the code itself to follow the
        // style guide, we should at least format it as well as we can.
        builder.indent();
        builder.startRule();
  
        builder.split(nest: false, space: true);
        visit(body);
  
        builder.endRule();
        builder.unindent();
      }
    }
  
    /// Visit a list of [nodes] if not null, optionally separated and/or preceded
    /// and followed by the given functions.
    void visitNodes(Iterable<AstNode> nodes, {before(), between(), after()}) {
      if (nodes == null || nodes.isEmpty) return;
  
      if (before != null) before();
  
      visit(nodes.first);
      for (var node in nodes.skip(1)) {
        if (between != null) between();
        visit(node);
      }
  
      if (after != null) after();
    }
  
    /// Visit a comma-separated list of [nodes] if not null.
    void visitCommaSeparatedNodes(Iterable<AstNode> nodes, {between()}) {
      if (nodes == null || nodes.isEmpty) return;
  
      if (between == null) between = space;
  
      var first = true;
      for (var node in nodes) {
        if (!first) between();
        first = false;
  
        visit(node);
  
        // The comma after the node.
        if (node.endToken.next.lexeme == ",") token(node.endToken.next);
      }
    }
  
    /// Visits the collection literal [node] whose body starts with [leftBracket],
    /// ends with [rightBracket] and contains [elements].
    ///
  