@Override
  public @NotNull StubTree getStubTree() {
    ApplicationManager.getApplication().assertReadAccessAllowed();

    StubTree stubTree = dereference(myStub);
    if (stubTree != null) return stubTree;

    // build newStub out of lock to avoid deadlock
    StubTreeLoader stubTreeLoader = StubTreeLoader.getInstance();
    Project project = getProject();
    VirtualFile virtualFile = getVirtualFile();
    boolean isDefault = project.isDefault(); // happens on decompile
    StubTree newStubTree =
      (StubTree)(isDefault ? stubTreeLoader.build(null, virtualFile, this) : stubTreeLoader.readOrBuild(project, virtualFile, this));
    if (newStubTree == null) {
      if (LOG.isDebugEnabled()) LOG.debug("No stub for class file " + virtualFile.getPresentableUrl());
      newStubTree = new StubTree(new PsiJavaFileStubImpl(CORRUPTED_CLASS_PACKAGE, true));
    }
    else if (!(newStubTree.getRoot() instanceof PsiClassHolderFileStub)) {
      if (LOG.isDebugEnabled()) LOG.debug("Invalid stub for class file " + virtualFile.getPresentableUrl() + ": " + newStubTree.getRoot());
      newStubTree = new StubTree(new PsiJavaFileStubImpl(CORRUPTED_CLASS_PACKAGE, true));
    }

    synchronized (myStubLock) {
      stubTree = dereference(myStub);
      if (stubTree != null) return stubTree;

      stubTree = newStubTree;

      @SuppressWarnings("unchecked") PsiFileStubImpl<PsiFile> fileStub = (PsiFileStubImpl<PsiFile>)stubTree.getRoot();
      fileStub.setPsi(this);

      myStub = new SoftReference<>(stubTree);
    }

    return stubTree;
  }
@Override
  public @NotNull StubTree getStubTree()