// B is the type of object we handle sclass TransformersOnObjects implements Steppable { // using the oldschool type F1 here because it's a bit easier to handle new AllOnAll allOnAll; new Set bs; AllOnAllOperation op = new(allOnAll, (a, b) -> { if (!callableOn_nonSynthetic(a, "get", b)) ret; O out = callFOpt(a, b); if (out cast Iterable) for (O x : out) addObject((B) x); else addObject((B) out); }); void add(B b) { addObject(b); } void addObject(B b) { if (addIfNotNull(bs, b)) allOnAll.addB(b); } void addTransformer(F1 f) { allOnAll.addA(f); } void addTransformer(F2 f) { addTransformer(func(O a) { addTransformer(func(O b) { callableOn_nonSynthetic(f, "get", a, b) ? f.get(a, b) : null }); null; }); } public bool step() { ret op.step(); } L getObjects() { ret allOnAll.getBs(); } }