@Override
    public void childMoved(@NotNull PsiTreeChangeEvent e) {
      PsiFile file = e.getFile();
      if (file != null) { // local change
        scheduleMarkFileAsDirtyAndUpdateTree(file);
        return;
      }
      PsiElement child = e.getChild();
      if (child instanceof PsiFile psiFile) { // file was moved
        if (canContainTodoItems(psiFile)) { // moved file contains TODOs
          scheduleMarkFileAsDirtyAndUpdateTree(psiFile);
        }
        return;
      }
      if (child instanceof PsiDirectory psiDirectory) { // directory was moved. mark all its files as dirty.
        ArrayList<VirtualFile> files = new ArrayList<>();
        for (Iterator<? extends PsiFile> i = getAllFiles(); i.hasNext(); ) {
          PsiFile psiFile = i.next();
          if (psiFile == null ||  // skip invalid PSI files
              !psiFile.isValid() ||
              !PsiTreeUtil.isAncestor(psiDirectory, psiFile, true)) {
            continue;
          }
          VirtualFile virtualFile = psiFile.getVirtualFile();
          if (virtualFile != null) {
            files.add(virtualFile);
          }
        }

        myCoroutineHelper.scheduleMarkFilesAsDirtyAndUpdateTree(files);
      }
    }
@Override
    public void childMoved(@NotNull PsiTreeChangeEvent e)