static class LCombineTwoFunctions extends LearnerImpl { static boolean debug; Function f, g; public void processInOut(Object in, Object out) { if (f != null) return; List functions = allFunctions(); // simple version without really checking multiple candidates for (Function f : functions) { Object o = tryProcess(f, in); if (o != null) { if (debug) debug("in=" + structure(in) + ", f=" + structure(f) + ", o=" + structure(o)); for (Function g : functions) { Object x = tryProcess(g, o); if (out.equals(x)) { if (debug) debug("bingo! " + structure(g)); this.f = f; this.g = g; return; } } } } } public Object processIn(Object in) { return g.process(f.process(in)); } static Object tryProcess(Function f, Object in) { try { return f.process(in); } catch (Throwable e) { return null; } } }