char (char @NotNull [] originalData, int index) { int changeIndex = getChangeIndex(index); if (changeIndex >= 0) { // Target char is contained at the stored change text ChangeEntry changeEntry = myChanges.get(changeIndex); if (changeEntry.change.getText().length() > index - changeEntry.clientStartOffset) { return changeEntry.change.getText().charAt(index - changeEntry.clientStartOffset); } else { int originalArrayIndex = index - (changeEntry.clientStartOffset - changeEntry.change.getStart() + changeEntry.change.getDiff()); return originalData[originalArrayIndex]; } } else { changeIndex = -changeIndex - 1; int clientShift = 0; if (changeIndex > 0 && changeIndex <= myChanges.size()) { ChangeEntry changeEntry = myChanges.get(changeIndex - 1); clientShift = changeEntry.clientStartOffset - changeEntry.change.getStart() + changeEntry.change.getDiff(); } return originalData[index - clientShift]; } }