private TextLine findLine(final int absIdx) {
    TextLine selected = null;
    if (currentLine != null) {
      if (currentLine.contains(absIdx)) {
        selected = currentLine;
      } else if (absIdx > currentLine.index() && currentLine.index() + 1 < lines.size()) {
        selected = scanLines(absIdx, currentLine.index());
      }
    }

    if (selected == null) {
      selected = scanLines(absIdx, 0);
    }

    assert selected == null || selected.contains(absIdx);
    currentLine = selected;
    return selected;
  }
  public CharRef charAt(int absoluteIndex) {
    final TextLine line = findLine(absoluteIndex);
    if (line == null) {
      throw new ArrayIndexOutOfBoundsException(absoluteIndex);
    }

    final int idx = absoluteIndex - line.start();
    return new CharRef(
        line.content().charAt(idx), new SourceLocation(absoluteIndex, line.index(), idx));
  }
 private void pushNewLine() {
   endLine = new TextLine(endLine.end(), endLine.index() + 1);
   lines.add(endLine);
 }