abstract sclass StringMatcher { // change matches only if returning true abstract bool match(S pat, S input, SS matches); // seems to be the same in all subclasses S apply(S input, SS matches) { ret ai_standardReplaceVars(input, matches); } bool matchAnyPattern(Collection patterns, S input, SS matches) { for (S pat : unnull(patterns)) if (match(pat, input, matches)) true; false; } bool matchAnyInput(S pat, Collection inputs, SS matches) { for (S input : unnull(inputs)) if (match(pat, input, matches)) true; false; } }