@Override
      public <T, E extends Throwable> @Nullable T computePreventingRecursion(@NotNull Key key,
                                                                             boolean memoize,
                                                                             @NotNull ThrowableComputable<T, E> computation) throws E{
        MyKey realKey = new MyKey(id, key, true);
        final CalculationStack stack = ourStack.get();

        if (stack.checkReentrancy(realKey)) {
          if (ourAssertOnPrevention.get()) {
            throw new StackOverflowPreventedException("Endless recursion prevention occurred on " + key);
          }
          else if (LOG.isDebugEnabled()) {
            LOG.debug(new StackOverflowPreventedException("Endless recursion prevention occurred on " + key));
          }
          return null;
        }

        if (memoize) {
          MemoizedValue memoized = stack.intermediateCache.get(realKey);
          if (memoized != null) {
            for (MyKey noCacheUntil : memoized.dependencies) {
              stack.prohibitResultCaching(noCacheUntil);
            }
            //noinspection unchecked
            return (T)memoized.value;
          }
        }

        realKey = new MyKey(id, key, false);

        final int sizeBefore = stack.progressMap.size();
        StackFrame frame = stack.beforeComputation(realKey);
        final int sizeAfter = stack.progressMap.size();

        try {
          T result = computation.compute();

          if (memoize && frame.preventionsInside != null) {
            stack.memoize(realKey, result, frame.preventionsInside);
          }

          return result;
        }
        finally {
          try {
            stack.afterComputation(realKey, sizeBefore, sizeAfter);
          }
          catch (Throwable e) {
            //noinspection ThrowFromFinallyBlock
            throw new RuntimeException("Throwable in afterComputation", e);
          }

          stack.checkDepth("4");
        }
      }
@Override
      public <T, E extends Throwable> @Nullable T computePreventingRecursion(@NotNull Key key,
                                                                             boolean memoize,
                                                                             @NotNull ThrowableComputable<T, E> computation)