@Override
  @Nullable
  public ObjectStubTree readFromVFile(Project project, final VirtualFile vFile) {
    if (DumbService.getInstance(project).isDumb()) {
      return null;
    }

    final int id = Math.abs(FileBasedIndex.getFileId(vFile));
    if (id <= 0) {
      return null;
    }

    boolean wasIndexedAlready = FileBasedIndexImpl.isFileIndexed(vFile, StubUpdatingIndex.INDEX_ID);

    final List<SerializedStubTree> datas =
        FileBasedIndex.getInstance()
            .getValues(StubUpdatingIndex.INDEX_ID, id, GlobalSearchScope.fileScope(project, vFile));
    final int size = datas.size();

    if (size == 1) {
      Stub stub;
      try {
        stub = datas.get(0).getStub(false);
      } catch (SerializerNotFoundException e) {
        return processError(
            vFile, "No stub serializer: " + vFile.getPresentableUrl() + ": " + e.getMessage(), e);
      }
      ObjectStubTree tree =
          stub instanceof PsiFileStub
              ? new StubTree((PsiFileStub) stub)
              : new ObjectStubTree((ObjectStubBase) stub, true);
      tree.setDebugInfo(
          "created from index: "
              + StubUpdatingIndex.getIndexingStampInfo(vFile)
              + ", wasIndexedAlready="
              + wasIndexedAlready
              + ", queried at "
              + vFile.getTimeStamp());
      return tree;
    } else if (size != 0) {
      return processError(
          vFile,
          "Twin stubs: "
              + vFile.getPresentableUrl()
              + " has "
              + size
              + " stub versions. Should only have one. id="
              + id,
          null);
    }

    return null;
  }
  @Override
  @Nullable
  public ObjectStubTree readFromVFile(Project project, final VirtualFile vFile) {
    if (DumbService.getInstance(project).isDumb()) {
      return null;
    }

    final int id = Math.abs(FileBasedIndex.getFileId(vFile));
    if (id <= 0) {
      return null;
    }

    boolean wasIndexedAlready =
        ((FileBasedIndexImpl) FileBasedIndex.getInstance()).isFileUpToDate(vFile);

    Document document = FileDocumentManager.getInstance().getCachedDocument(vFile);
    boolean saved =
        document == null || !FileDocumentManager.getInstance().isDocumentUnsaved(document);

    final List<SerializedStubTree> datas =
        FileBasedIndex.getInstance()
            .getValues(StubUpdatingIndex.INDEX_ID, id, GlobalSearchScope.fileScope(project, vFile));
    final int size = datas.size();

    if (size == 1) {
      SerializedStubTree stubTree = datas.get(0);

      if (!stubTree.contentLengthMatches(
          vFile.getLength(), getCurrentTextContentLength(project, vFile, document))) {
        return processError(
            vFile,
            "Outdated stub in index: "
                + StubUpdatingIndex.getIndexingStampInfo(vFile)
                + ", doc="
                + document
                + ", docSaved="
                + saved
                + ", wasIndexedAlready="
                + wasIndexedAlready
                + ", queried at "
                + vFile.getTimeStamp(),
            null);
      }

      Stub stub;
      try {
        stub = stubTree.getStub(false);
      } catch (SerializerNotFoundException e) {
        return processError(
            vFile, "No stub serializer: " + vFile.getPresentableUrl() + ": " + e.getMessage(), e);
      }
      ObjectStubTree tree =
          stub instanceof PsiFileStub
              ? new StubTree((PsiFileStub) stub)
              : new ObjectStubTree((ObjectStubBase) stub, true);
      tree.setDebugInfo("created from index");
      return tree;
    } else if (size != 0) {
      return processError(
          vFile,
          "Twin stubs: "
              + vFile.getPresentableUrl()
              + " has "
              + size
              + " stub versions. Should only have one. id="
              + id,
          null);
    }

    return null;
  }
 @Override
 public String getIndexingStampDebugInfo(VirtualFile file) {
   return StubUpdatingIndex.getIndexingStampInfo(file);
 }
 @Override
 public boolean canHaveStub(VirtualFile file) {
   return StubUpdatingIndex.canHaveStub(file);
 }