private static @NotNull ConvertResult convertLineSeparatorsToSlashN(byte @NotNull [] charsAsBytes, int startOffset, int endOffset) {
    int lineBreak = findLineBreakOrWideChar(charsAsBytes, startOffset, endOffset);
    if (!BitUtil.isSet(lineBreak, CR) && !BitUtil.isSet(lineBreak, WIDE)) {
      // optimization: if there is no CR in the file, no line separator conversion is necessary.
      // we can re-use the passed byte buffer inplace
      ByteArrayCharSequence sequence = new ByteArrayCharSequence(charsAsBytes, startOffset, endOffset);
      return new ConvertResult(sequence, 0, BitUtil.isSet(lineBreak, LF) ? 1 : 0, 0);
    }

    if (BitUtil.isSet(lineBreak, WIDE)) {
      // characters outside AS_ASCII range found, insert UNDEFINED_CHAR
      return convertWideCharacters(charsAsBytes, startOffset, endOffset);
    }
    // convert \r\n to \n, \r to \n
    int dst = 0;
    char prev = ' ';
    int crCount = 0;
    int lfCount = 0;
    int crlfCount = 0;
    byte[] result = ArrayUtil.newByteArray(endOffset - startOffset);

    for (int src = startOffset; src < endOffset; src++) {
      char c = (char)charsAsBytes[src];
      switch (c) {
        case '\r':
          result[dst++] = '\n';
          crCount++;
          break;
        case '\n':
          if (prev == '\r') {
            crCount--;
            crlfCount++;
          }
          else {
            result[dst++] = '\n';
            lfCount++;
          }
          break;
        default:
          result[dst++] = (byte)c;
          break;
      }
      prev = c;
    }

    ByteArrayCharSequence sequence = new ByteArrayCharSequence(result, 0, dst);
    return new ConvertResult(sequence, crCount, lfCount, crlfCount);
  }
private static @NotNull ConvertResult convertLineSeparatorsToSlashN(byte @NotNull [] charsAsBytes, int startOffset, int endOffset)