static Collection<GInterpretable> gazelle_processWithPurpose(S input1, S purpose, O... _) {
  Set<S> texts = litCISet();
  new L<GInterpretable> interpretables;
  int max = optPar max(_, 20);
  Collector<GInterpretable> collector = limitedCollector(interpretables, max);
  RuleEngine2 engine = ((F0<GazelleEvalContext>) optPar contextMaker(_)).get().engine;

  int nInterpreted = -1;
  
  bigLoop: while (!collector.full() && nInterpreted < l(interpretables)) {
    GInterpretable workingOn = get(interpretables, nInterpreted);
    S input = nInterpreted < 0 ? input1 : workingOn.text;
    S ruleBase = workingOn == null ? "" : workingOn.ruleID + "+";
    ++nInterpreted;
    
    for (RuleEngine2.SimplifyWithRule rule : engine.splitterRules()) pcall {
      for (S out : gazelle_executeSplitterRule(engine, rule, input))
        if (texts.add(out))
          if (collector.add(new GInterpretable(out, ruleBase + rule.globalID))) break bigLoop;
    }
    
    for (GazelleTree t : dm_gazelle_reasonAboutChatInput_v2(null, input, 
      paramsPlus(_, skipSplitters := true, acceptablePurposes := litset(purpose), skipUserName := true, skipUserID := true)))
        if (texts.add(t.line))
          if (collector.add(new GInterpretable(t.line, ruleBase + t.ruleID()))) break bigLoop;
  }
      
  ret interpretables;
}