@Override
  public <K> Collection<K> getAllKeys(final StubIndexKey<K, ?> indexKey, @NotNull Project project) {
    FileBasedIndex.getInstance()
        .ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, GlobalSearchScope.allScope(project));

    final MyIndex<K> index = (MyIndex<K>) myIndices.get(indexKey);
    try {
      return index.getAllKeys();
    } catch (StorageException e) {
      forceRebuild(e);
    } catch (RuntimeException e) {
      final Throwable cause = e.getCause();
      if (cause instanceof IOException || cause instanceof StorageException) {
        forceRebuild(e);
      }
      throw e;
    }
    return Collections.emptyList();
  }
 @NotNull
 public static List<PyFile> find(
     @NotNull String name, @NotNull Project project, boolean includeNonProjectItems) {
   final List<PyFile> results = new ArrayList<PyFile>();
   final GlobalSearchScope scope =
       includeNonProjectItems
           ? PyProjectScopeBuilder.excludeSdkTestsScope(project)
           : GlobalSearchScope.projectScope(project);
   final Collection<VirtualFile> files =
       FileBasedIndex.getInstance().getContainingFiles(NAME, name, scope);
   for (VirtualFile virtualFile : files) {
     final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
     if (psiFile instanceof PyFile) {
       if (!PyUserSkeletonsUtil.isUnderUserSkeletonsDirectory(psiFile)) {
         results.add((PyFile) psiFile);
       }
     }
   }
   return results;
 }
  public static <Key, Psi extends PsiElement> Collection<Psi> safeGet(
      @NotNull StubIndexKey<Key, Psi> indexKey,
      @NotNull Key key,
      final Project project,
      final GlobalSearchScope scope,
      Class<Psi> requiredClass) {
    Collection<Psi> collection = getInstance().get(indexKey, key, project, scope);
    for (Iterator<Psi> iterator = collection.iterator(); iterator.hasNext(); ) {
      Psi psi = iterator.next();
      if (!requiredClass.isInstance(psi)) {
        iterator.remove();

        VirtualFile faultyContainer = PsiUtilCore.getVirtualFile(psi);
        LOG.error("Invalid stub element type in index: " + faultyContainer + ". found: " + psi);
        if (faultyContainer != null && faultyContainer.isValid()) {
          FileBasedIndex.getInstance().requestReindex(faultyContainer);
        }
      }
    }

    return collection;
  }
 private static void forceRebuild(Throwable e) {
   LOG.info(e);
   requestRebuild();
   FileBasedIndex.getInstance().scheduleRebuild(StubUpdatingIndex.INDEX_ID, e);
 }
  @Override
  public <Key, Psi extends PsiElement> Collection<Psi> get(
      @NotNull final StubIndexKey<Key, Psi> indexKey,
      @NotNull final Key key,
      final Project project,
      final GlobalSearchScope scope) {
    FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, scope);

    final PersistentFS fs = (PersistentFS) ManagingFS.getInstance();
    final PsiManager psiManager = PsiManager.getInstance(project);

    final List<Psi> result = new ArrayList<Psi>();
    final MyIndex<Key> index = (MyIndex<Key>) myIndices.get(indexKey);

    try {
      try {
        // disable up-to-date check to avoid locks on attempt to acquire index write lock while
        // holding at the same time the readLock for this index
        FileBasedIndex.disableUpToDateCheckForCurrentThread();
        index.getReadLock().lock();
        final ValueContainer<TIntArrayList> container = index.getData(key);

        container.forEach(
            new ValueContainer.ContainerAction<TIntArrayList>() {
              @Override
              public void perform(final int id, final TIntArrayList value) {
                final VirtualFile file = IndexInfrastructure.findFileByIdIfCached(fs, id);
                if (file != null && (scope == null || scope.contains(file))) {
                  StubTree stubTree = null;

                  final PsiFile _psifile = psiManager.findFile(file);
                  PsiFileWithStubSupport psiFile = null;

                  if (_psifile != null && !(_psifile instanceof PsiPlainTextFile)) {
                    if (_psifile instanceof PsiFileWithStubSupport) {
                      psiFile = (PsiFileWithStubSupport) _psifile;
                      stubTree = psiFile.getStubTree();
                      if (stubTree == null && psiFile instanceof PsiFileImpl) {
                        stubTree = ((PsiFileImpl) psiFile).calcStubTree();
                      }
                    }
                  }

                  if (stubTree != null || psiFile != null) {
                    if (stubTree == null) {
                      stubTree = StubTreeLoader.getInstance().readFromVFile(project, file);
                      if (stubTree != null) {
                        final List<StubElement<?>> plained = stubTree.getPlainList();
                        for (int i = 0; i < value.size(); i++) {
                          final StubElement<?> stub = plained.get(value.get(i));
                          final ASTNode tree = psiFile.findTreeForStub(stubTree, stub);

                          if (tree != null) {
                            if (tree.getElementType() == stubType(stub)) {
                              result.add((Psi) tree.getPsi());
                            } else {
                              String persistedStubTree =
                                  ((PsiFileStubImpl) stubTree.getRoot()).printTree();

                              String stubTreeJustBuilt =
                                  ((PsiFileStubImpl)
                                          ((IStubFileElementType)
                                                  ((PsiFileImpl) psiFile).getContentElementType())
                                              .getBuilder()
                                              .buildStubTree(psiFile))
                                      .printTree();

                              StringBuilder builder = new StringBuilder();
                              builder.append("Oops\n");

                              builder.append("Recorded stub:-----------------------------------\n");
                              builder.append(persistedStubTree);
                              builder.append(
                                  "\nAST built stub: ------------------------------------\n");
                              builder.append(stubTreeJustBuilt);
                              builder.append("\n");
                              LOG.info(builder.toString());

                              // requestReindex() may want to acquire write lock (for indices not
                              // requiring content loading)
                              // thus, because here we are under read lock, need to use invoke later
                              ApplicationManager.getApplication()
                                  .invokeLater(
                                      new Runnable() {
                                        @Override
                                        public void run() {
                                          FileBasedIndex.getInstance().requestReindex(file);
                                        }
                                      },
                                      ModalityState.NON_MODAL);
                            }
                          }
                        }
                      }
                    } else {
                      final List<StubElement<?>> plained = stubTree.getPlainList();
                      for (int i = 0; i < value.size(); i++) {
                        result.add((Psi) plained.get(value.get(i)).getPsi());
                      }
                    }
                  }
                }
              }
            });
      } finally {
        index.getReadLock().unlock();
        FileBasedIndex.enableUpToDateCheckForCurrentThread();
      }
    } catch (StorageException e) {
      forceRebuild(e);
    } catch (RuntimeException e) {
      final Throwable cause = FileBasedIndex.getCauseToRebuildIndex(e);
      if (cause != null) {
        forceRebuild(cause);
      } else {
        throw e;
      }
    }

    return result;
  }
 @NotNull
 public static Collection<String> getAllKeys(@NotNull Project project) {
   return FileBasedIndex.getInstance().getAllKeys(NAME, project);
 }