@Override
    public ChangeApplier prepareChange(@NotNull List<? extends @NotNull VFileEvent> events) {
      List<VirtualFile> toRecompute = new ArrayList<>();
      Map<VirtualFile, Document> strongRefsToDocuments = new HashMap<>();
      List<VFileContentChangeEvent> contentChanges = ContainerUtil.findAll(events, VFileContentChangeEvent.class);
      for (VFileContentChangeEvent event : contentChanges) {
        ProgressManager.checkCanceled();
        VirtualFile virtualFile = event.getFile();

        // when an empty unknown file is written into, re-run file type detection
        if (virtualFile instanceof VirtualFileWithId) {
          long lastRecordedLength = PersistentFS.getInstance().getLastRecordedLength(virtualFile);
          if (lastRecordedLength == 0 &&
              FileTypeRegistry.getInstance().isFileOfType(virtualFile, UnknownFileType.INSTANCE)) { // check file type last to avoid content detection running
            toRecompute.add(virtualFile);
          }
        }

        prepareForRangeMarkerUpdate(strongRefsToDocuments, virtualFile);
      }

      return new ChangeApplier() {
        @Override
        public void beforeVfsChange() {
          for (VFileContentChangeEvent event : contentChanges) {
            // new range markers could've appeared after "prepareChange" in some read action
            prepareForRangeMarkerUpdate(strongRefsToDocuments, event.getFile());
            if (ourConflictsSolverEnabled) {
              myFileDocumentManager.myConflictResolver.beforeContentChange(event);
            }
          }

          for (VirtualFile file : toRecompute) {
            file.putUserData(MUST_RECOMPUTE_FILE_TYPE, Boolean.TRUE);
          }
        }

        @Override
        public void afterVfsChange() {
          for (VFileEvent event : events) {
            if (event instanceof VFileContentChangeEvent && ((VFileContentChangeEvent)event).getFile().isValid()) {
              myFileDocumentManager.contentsChanged((VFileContentChangeEvent)event);
            }
            else if (event instanceof VFileDeleteEvent && ((VFileDeleteEvent)event).getFile().isValid()) {
              myFileDocumentManager.fileDeleted((VFileDeleteEvent)event);
            }
            else if (event instanceof VFilePropertyChangeEvent && ((VFilePropertyChangeEvent)event).getFile().isValid()) {
              myFileDocumentManager.propertyChanged((VFilePropertyChangeEvent)event);
            }
          }
          Reference.reachabilityFence(strongRefsToDocuments);
        }
      };
    }
@Override
    public ChangeApplier prepareChange(@NotNull List<? extends @NotNull VFileEvent> events)