class BatchIdHolder extends IdHolder
            implements CIter<IdHolder> {

        private final Iterator<BackendEntry> entries;
        private final Function<Long, Set<Id>> fetcher;
        private long count;
        private PageIds currentBatch;

        public BatchIdHolder(ConditionQuery query,
                             Iterator<BackendEntry> entries,
                             Function<Long, Set<Id>> fetcher) {
            super(query);
            this.entries = entries;
            this.fetcher = fetcher;
            this.count = 0L;
            this.currentBatch = null;
        }

        @Override
        public boolean paging() {
            return false;
        }

        @Override
        public boolean hasNext() {
            if (this.currentBatch != null) {
                return true;
            }
            if (this.exhausted) {
                return false;
            }
            boolean hasNext = this.entries.hasNext();
            if (!hasNext) {
                this.close();
            }
            return hasNext;
        }

        @Override
        public IdHolder next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            return this;
        }

        @Override
        public PageIds fetchNext(String page, long batchSize) {<FILL_FUNCTION_BODY>}

        @Override
        public Set<Id> all() {
            try {
                Set<Id> ids = this.fetcher.apply(this.remaining());
                if (this.currentBatch != null) {
                    ids.addAll(this.getFromCurrentBatch(Query.NO_LIMIT).ids());
                }
                this.count += ids.size();
                return ids;
            } finally {
                this.close();
            }
        }

        public PageIds peekNext(long size) {
            E.checkArgument(this.currentBatch == null,
                            "Can't call peekNext() twice");
            this.currentBatch = this.fetchNext(null, size);
            return this.currentBatch;
        }

        private PageIds getFromCurrentBatch(long batchSize) {
            assert this.currentBatch != null;
            PageIds result = this.currentBatch;
            this.currentBatch = null;
            return result;
        }

        private long remaining() {
            if (this.query.noLimit()) {
                return Query.NO_LIMIT;
            } else {
                return this.query.total() - this.count;
            }
        }

        @Override
        public void close() {
            if (this.exhausted) {
                return;
            }
            this.exhausted = true;

            CloseableIterator.closeIterator(this.entries);
        }

        @Override
        public Object metadata(String meta, Object... args) {
            E.checkState(this.entries instanceof Metadatable,
                         "Invalid iterator for Metadatable: %s",
                         this.entries.getClass());
            return ((Metadatable) this.entries).metadata(meta, args);
        }
    }

            E.checkArgument(page == null,
                            "Not support page parameter by BatchIdHolder");
            E.checkArgument(batchSize >= 0L,
                            "Invalid batch size value: %s", batchSize);

            if (this.currentBatch != null) {
                return this.getFromCurrentBatch(batchSize);
            }

            if (!this.query.noLimit()) {
                long remaining = this.remaining();
                if (remaining < batchSize) {
                    batchSize = remaining;
                }
            }
            assert batchSize >= 0L : batchSize;
            Set<Id> ids = this.fetcher.apply(batchSize);
            int size = ids.size();
            this.count += size;
            if (size < batchSize || size == 0) {
                this.close();
            }

            // If there is no data, the entries is not a Metadatable object
            if (size == 0) {
                return PageIds.EMPTY;
            } else {
                return new PageIds(ids, PageState.EMPTY);
            }
        
<no_super_class>