@Override
      public Boolean call() {
        boolean[] result = new boolean[1];
        try {
          ProgressManager.getInstance().executeProcessUnderProgress(() -> {
            try {
              while (true) {
                T element = things.take();

                if (element == TOMBSTONE()) {
                  result[0] = true;
                  break;
                }
                try (AccessToken ignored = ThreadContext.installThreadContext(myContext, true)) {
                  ProgressManager.checkCanceled();
                  if (!thingProcessor.process(element, addToQueue)) {
                    break;
                  }
                }
                catch (RuntimeException|Error e) {
                  if (logAllExceptions) {
                    LOG.info("Failed to process " + element + ". Add too failed query.", e);
                  }
                  throw e;
                }
              }
            }
            catch (InterruptedException e) {
              throw new RuntimeException(e);
            }
          }, progress);
          completer.tryComplete();
          return result[0];
        }
        catch (Throwable throwable) {
          completer.completeExceptionally(throwable);
          return false;
        }
        finally {
          if (!result[0]) {
            // in case of exception, we need to cancel all tasks as quick as possible, so if there is a task blocked in ".take()" we could unblock it by offering tombstone
            addToQueue.dropEverythingAndPanic();
            futureResult.set(false);
          }
        }
      }
@Override
      public Boolean call()