@Contract("_, _, !null -> !null")
  private @Nullable Supplier<Data> getOrCalculateAndCache(@Nullable Project project,
                                                          @NotNull VirtualFile file,
                                                          @Nullable GistCalculator<Data> calculator) {
    ApplicationManager.getApplication().assertReadAccessAllowed();
    ProgressManager.checkCanceled();

    if (!(file instanceof VirtualFileWithId)) {
      if (calculator != null) {
        Data value = calculator.calcData(project, file);
        return () -> value;
      }
      else {
        return null;
      }
    }

    int expectedGistStamp = GistManagerImpl.getGistStamp(file);
    try {
      GistStorage.GistData<Data> gistData = gist.getProjectData(project, file, expectedGistStamp);
      if (gistData.hasData()) {
        return () -> gistData.data();
      }
    }
    catch (IOException e) {
      LOG.error(e);
    }

    if (calculator != null) {
      Data value = calculator.calcData(project, file);
      cacheResult(expectedGistStamp, value, project, file);
      return () -> value;
    }
    else {
      return null;
    }
  }
@Contract("_, _, !null -> !null")
  private @Nullable Supplier<Data> getOrCalculateAndCache(@Nullable Project project,
                                                          @NotNull VirtualFile file,
                                                          @Nullable GistCalculator<Data> calculator)