anchor.diff:        nestingMap[nestingLevels[i]] = i;
       }
   
  -    for (var chunk in _chunks.take(length)) {
  +    for (var chunk in chunks) {
         chunk.nesting = nestingMap[chunk.nesting];
       }
     }
   
  -  /// Preemptively harden rules in the first [length] chunks if there will
  -  /// certainly be no solution that allows them to remain unsplit.
  +  /// Preemptively hardens rules in the range of chunks from [start] to [end]
  +  /// (half-inclusive) if there will certainly be no solution that allows them
  +  /// to remain unsplit.
     ///
     /// For each rule, we look at the span of chunks it covers. If that range is
     /// longer than the page width, than the rule is preemptively hardened now.
  
positive.code:       }
      }
  
      if (hardenedRules.isEmpty) return;
  
      // Remove implied references to hardened rules. If a rule implies one
      // that's already hardened, we don't need to track the implication anymore.
      for (var chunk in _chunks) {
        chunk.rule.implies.removeAll(hardenedRules);
      }
  
      // TODO(bob): There's some duplication between this and _hardenRules().
      // Clean up.
  
      for (var i = 0; i < _chunks.length; i++) {
        var chunk = _chunks[i];
        if (chunk.rule == null) continue;
  
        if (hardenedRules.contains(chunk.rule)) {
          chunk.harden();
  
          // Now that this chunk is a hard split, we may be able to format up to
          // it as its own line. If so, the chunks will get removed, so reset
          // the loop counter.
          if (_checkForCompleteLine(i + 1)) i = -1;
        }
      }
    }
  }
  
negative.code:     } else if (_chunks.last.canAddText) {
        _chunks.last.appendText(text);
      } else {
        _chunks.add(new Chunk(text));
      }
    }
  
    /// Takes all of the chunks and breaks them into sublists that can be line
    /// split individually.
    ///
    /// This should only be called once, after all of the chunks have been
    /// written.
    void _splitLines() {
      // For each independent set of chunks, see if there are any rules in them
      // that we want to preemptively harden. This is basically to send smaller
      // batches of chunks to LineSplitter in cases where the code is deeply
      // nested or complex.
      var start = 0;
      for (var i = 1; i < _chunks.length; i++) {
        var chunk = _chunks[i];
        if (chunk.isHardSplit && chunk.nesting == -1) {
          _preemptRules(start, i);
          start = i;
        }
      }
  
      // Now that we know what hard splits there will be, break the chunks into
      // independently splittable lines.
      var bufferedNewlines = 0;
      var beginningIndent = _formatter.indent;
  
      for (var i = 0; i < _chunks.length; i++) {
        var chunk = _chunks[i];
  
        if (!chunk.isHardSplit || chunk.nesting != -1) continue;
  
        // Write the newlines required by the previous line.
        for (var i = 0; i < bufferedNewlines; i++) {
          _buffer.write(_formatter.lineEnding);
        }
  
        _completeLine(beginningIndent, i + 1);
        i = -1;
  
        // Get ready for the next line.
        bufferedNewlines = chunk.isDouble ? 2 : 1;
        beginningIndent = chunk.indent;
      }
  
      if (_chunks.isNotEmpty) _completeLine(beginningIndent, _chunks.length);
    }
  
    /// Takes the first [length] of the chunks with leading [indent], removes
    /// them, and runs the [LineSplitter] on them.
    void _completeLine(int indent, int length) {
      // We know unused nesting levels will never be used now, so flatten them.
      _flattenNestingLevels(length);
  
      // Remove the prefix from the list of rules and spans.
      var chunks = _chunks.take(length).toList();
      // TODO(rnystrom): Mutating the list is a big perf hit. Do something better.
      _chunks.removeRange(0, length);
  
      var spans = [];
      _spans.removeWhere((span) {
        if (!span.subtractPrefix(length)) return false;
  
        // We can ditch the spans that only existed to track rule bounds now.
        // They don't affect splitting.
        if (span.cost > 0) spans.add(span);
        return true;
      });
  
      var splitter = new LineSplitter(_formatter.lineEnding,
      _formatter.pageWidth, chunks, spans, indent);
      var selection = splitter.apply(_buffer);
  
      if (selection[0] != null) {
        _selectionStart = selection[0];
      }
  
      if (selection[1] != null) {
        _selectionLength = selection[1] -_selectionStart;
      }
    }
  
  