@Override public Iter iter(final QueryContext ctx) throws QueryException { final Iter iter = ctx.iter(root); final Value cv = ctx.value; final long cs = ctx.size; final long cp = ctx.pos; // cache results to support last() function final ItemCache ic = new ItemCache(); for (Item i; (i = iter.next()) != null; ) ic.add(i); // evaluate predicates for (final Expr p : pred) { final long is = ic.size(); ctx.size = is; ctx.pos = 1; int c = 0; for (int s = 0; s < is; ++s) { ctx.value = ic.get(s); if (p.test(ctx, input) != null) ic.set(ic.get(s), c++); ctx.pos++; } ic.size(c); } ctx.value = cv; ctx.size = cs; ctx.pos = cp; return ic; }