@Override
 public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement element) {
   PsiFile file = element.getContainingFile();
   if (file == null) {
     return true;
   }
   VirtualFile virtualFile = file.getVirtualFile();
   if (virtualFile == null) {
     return true;
   }
   TaskFile taskFile = StudyUtils.getTaskFile(element.getProject(), virtualFile);
   return taskFile == null || taskFile.isHighlightErrors();
 }
 @Override
 public void documentChanged(DocumentEvent e) {
   if (!myTaskFile.isTrackChanges()) {
     return;
   }
   if (myAnswerPlaceholders.isEmpty()) return;
   if (e instanceof DocumentEventImpl) {
     DocumentEventImpl event = (DocumentEventImpl) e;
     Document document = e.getDocument();
     int offset = e.getOffset();
     int change = event.getNewLength() - event.getOldLength();
     for (AnswerPlaceholderWrapper answerPlaceholderWrapper : myAnswerPlaceholders) {
       int twStart = answerPlaceholderWrapper.getTwStart();
       if (twStart > offset) {
         twStart += change;
       }
       int twEnd = answerPlaceholderWrapper.getTwEnd();
       if (twEnd >= offset) {
         twEnd += change;
       }
       AnswerPlaceholder answerPlaceholder = answerPlaceholderWrapper.getAnswerPlaceholder();
       int line = document.getLineNumber(twStart);
       int start = twStart - document.getLineStartOffset(line);
       int length = twEnd - twStart;
       answerPlaceholder.setLine(line);
       answerPlaceholder.setStart(start);
       if (usePossibleAnswerLength) {
         answerPlaceholder.setPossibleAnswer(
             document.getText(TextRange.create(twStart, twStart + length)));
       } else if (myTrackLength) {
         answerPlaceholder.setLength(length);
       }
     }
   }
 }
 // remembering old end before document change because of problems
 // with fragments containing "\n"
 @Override
 public void beforeDocumentChange(DocumentEvent e) {
   if (!myTaskFile.isTrackChanges()) {
     return;
   }
   myTaskFile.setHighlightErrors(true);
   Document document = e.getDocument();
   myAnswerPlaceholders.clear();
   for (AnswerPlaceholder answerPlaceholder : myTaskFile.getAnswerPlaceholders()) {
     int twStart = answerPlaceholder.getRealStartOffset(document);
     int length =
         usePossibleAnswerLength
             ? answerPlaceholder.getPossibleAnswerLength()
             : answerPlaceholder.getLength();
     int twEnd = twStart + length;
     myAnswerPlaceholders.add(new AnswerPlaceholderWrapper(answerPlaceholder, twStart, twEnd));
   }
 }