@NotNull
  private Promise<VALUE> getOrCreateAsyncResult(HOST host, boolean checkFreshness, boolean load) {
    Promise<VALUE> promise = fieldUpdater.getVolatile(host);
    if (promise == null) {
      promise = new AsyncPromise<>();
      promise.onError((ignored) -> {});
      if (!fieldUpdater.compareAndSet(host, null, promise)) {
        return fieldUpdater.getVolatile(host);
      }
    }
    else {
      Promise.State state = promise.getState();
      if (state == Promise.State.PENDING) {
        // if current promise is not processed, so, we don't need to check cache state
        return promise;
      }
      else if (state == Promise.State.SUCCEEDED) {
        try {
          if (!checkFreshness || isUpToDate(host, promise.blockingGet(0))) {
            return promise;
          }
        }
        catch (ExecutionException | TimeoutException e) {
          throw new RuntimeException(e);
        }

        if (!fieldUpdater.compareAndSet(host, promise, promise = new AsyncPromise<>())) {
          Promise<VALUE> valueFromAnotherThread = fieldUpdater.getVolatile(host);
          while (valueFromAnotherThread == null) {
            if (fieldUpdater.compareAndSet(host, null, promise)) {
              return getPromise(host, load, promise);
            }
            else {
              valueFromAnotherThread = fieldUpdater.getVolatile(host);
            }
          }
          return valueFromAnotherThread;
        }
      }
    }

    return getPromise(host, load, promise);
  }
@NotNull
  private Promise<VALUE> getOrCreateAsyncResult(HOST host, boolean checkFreshness, boolean load)