protected virtual void QueueAfterCommit() => Services.Locks.ExecuteOrQueue(Lifetime, ActivityName, () =>
 {
     using var cookie = ReadLockCookie.Create();
     // We need to have documents committed before we can do anything,
     // because after PSI file creation/deletion/etc the graph might contain incorrect information on whether
     // a certain file has a preprocessed root or not.
     // Also, some implementations access the PSI files,
     // which might become invalid after the simple queueing
     Services.Files.ExecuteAfterCommitAllDocuments(() =>
     {
         AfterCommitSync(IndirectDependencies.WhereNotNull().Where(it => it.IsValid()).ToSet());
         IndirectDependencies = new HashSet <IPsiSourceFile>();
     });
 });
 protected virtual void QueueAfterCommit() => Services.Locks.ExecuteOrQueue(Lifetime, ActivityName, () =>
 {
     AfterCommitSync(IndirectDependencies.WhereNotNull().Where(it => it.IsValid()).ToSet());
     IndirectDependencies = new HashSet <IPsiSourceFile>();
 });