CharSequence (@NotNull CharSequence text, @NotNull String newSeparator, @Nullable int[] offsetsToKeep, boolean keepCarriageReturn) { StringBuilder buffer = null; int intactLength = 0; boolean newSeparatorIsSlashN = "\n".equals(newSeparator); for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); if (c == '\n') { if (!newSeparatorIsSlashN) { if (buffer == null) { buffer = new StringBuilder(text.length()); buffer.append(text, 0, intactLength); } buffer.append(newSeparator); shiftOffsets(offsetsToKeep, buffer.length(), 1, newSeparator.length()); } else if (buffer == null) { intactLength++; } else { buffer.append('\n'); } } else if (c == '\r') { boolean followedByLineFeed = i < text.length() - 1 && text.charAt(i + 1) == '\n'; if (!followedByLineFeed && keepCarriageReturn) { if (buffer == null) { intactLength++; } else { buffer.append('\r'); } continue; } if (buffer == null) { buffer = new StringBuilder(text.length()); buffer.append(text, 0, intactLength); } buffer.append(newSeparator); if (followedByLineFeed) { //noinspection AssignmentToForLoopParameter i++; shiftOffsets(offsetsToKeep, buffer.length(), 2, newSeparator.length()); } else { shiftOffsets(offsetsToKeep, buffer.length(), 1, newSeparator.length()); } } else if (buffer == null) { intactLength++; } else { buffer.append(c); } } return buffer == null ? text : buffer; }