public static @NotNull <K, V, I> IntSet collectInputIdsContainingAllKeys(@NotNull InvertedIndex<? super K, V, I> index,
                                                                           @NotNull Collection<? extends K> dataKeys,
                                                                           @Nullable Condition<? super V> valueChecker,
                                                                           @Nullable IntPredicate idChecker)
    throws StorageException {
    IntSet mainIntersection = null;

    for (K dataKey : dataKeys) {
      IOCancellationCallbackHolder.checkCancelled();

      IntSet copy = new IntOpenHashSet();
      ValueContainer<V> container = index.getData(dataKey);

      for (ValueContainer.ValueIterator<V> valueIt = container.getValueIterator(); valueIt.hasNext(); ) {
        final V value = valueIt.next();
        if (valueChecker != null && !valueChecker.value(value)) {
          continue;
        }
        IOCancellationCallbackHolder.checkCancelled();

        ValueContainer.IntIterator iterator = valueIt.getInputIdsIterator();

        final IntPredicate predicate;
        if (mainIntersection == null || iterator.size() < mainIntersection.size() || (predicate = valueIt.getValueAssociationPredicate()) == null) {
          while (iterator.hasNext()) {
            final int id = iterator.next();
            if (mainIntersection == null && (idChecker == null || idChecker.test(id)) ||
                mainIntersection != null && mainIntersection.contains(id)) {
              copy.add(id);
            }
          }
        }
        else {
          for (IntIterator intIterator = mainIntersection.iterator(); intIterator.hasNext(); ) {
            int id = intIterator.nextInt();
            if (predicate.test(id) && (idChecker == null || idChecker.test(id))) {
              copy.add(id);
            }
          }
        }
      }

      mainIntersection = copy;
      if (mainIntersection.isEmpty()) {
        return IntSets.EMPTY_SET;
      }
    }

    return mainIntersection == null ? IntSets.EMPTY_SET : mainIntersection;
  }
public static @NotNull <K, V, I> IntSet collectInputIdsContainingAllKeys(@NotNull InvertedIndex<? super K, V, I> index,
                                                                           @NotNull Collection<? extends K> dataKeys,
                                                                           @Nullable Condition<? super V> valueChecker,
                                                                           @Nullable IntPredicate idChecker)