private static <TRef, TResult> @Nullable TResult resolve(@NotNull TRef ref, @NotNull Map<TRef, TResult> cache, boolean preventRecursion, @NotNull Computable<? extends TResult> resolver) {
    TResult cachedResult = cache.get(ref);
    if (cachedResult != null) {
      if (IdempotenceChecker.areRandomChecksEnabled()) {
        IdempotenceChecker.applyForRandomCheck(cachedResult, ref, loggingResolver(ref, resolver));
      }
      return cachedResult;
    }

    RecursionGuard.StackStamp stamp = RecursionManager.markStack();
    Computable<TResult> loggingResolver = loggingResolver(ref, resolver);
    TResult result = preventRecursion
                     ? RecursionManager.doPreventingRecursion(Pair.create(ref, cache), true, loggingResolver)
                     : loggingResolver.get();
    if (result instanceof ResolveResult) {
      ensureValidPsi((ResolveResult)result);
    }
    else if (result instanceof ResolveResult[]) {
      ensureValidResults((ResolveResult[])result);
    }
    else if (result instanceof PsiElement) {
      PsiUtilCore.ensureValid((PsiElement)result);
    }
    if (stamp.mayCacheNow()) {
      cache(ref, cache, result, loggingResolver);
    }
    return result;
  }
private static <TRef, TResult> @Nullable TResult resolve(@NotNull TRef ref, @NotNull Map<TRef, TResult> cache, boolean preventRecursion, @NotNull Computable<? extends TResult> resolver)