static L<GazelleTree> gazelle_getChildren(GazelleTree tree, O... _) {
  if (tree == null) null;
  if (tree.children != null) ret tree.children;
  
  tree.children = new L;
  
  double qualityCutOff = optPar qualityCutOff(_, -0.75);
  LS dialogHistory = cast optPar dialogHistory(_);
  bool debug = boolPar debug(_);
  
  // make rule engine etc.
  if (tree.ctx == null)
    tree.setContext(assertNotNull('evalContext, (GazelleEvalContext) callF(assertNotNull('makeEvalContext, (O) optPar makeEvalContext(_)))));
  GazelleEvalContext ctx = tree.ctx;
  RuleEngine2 engine = ctx.engine;
  
  SS inputMap = gazelle_inputMapFromLineAndHistory(tree.line, 
    concatLists(dialogHistory, tree.history()));
  if (boolPar respondingToHuman(_)) inputMap.put("_respondingToHuman" := "true");
  if (debug) print("inputMap=" + sfu(asTreeMap(inputMap)));

  // Splitters
  
  if (!boolPar skipSplitters(_)) for (RuleEngine2.SimplifyWithRule rule : engine.splitterRules()) pcall {
    Collection<S> out = gazelle_executeSplitterRule(engine, rule, tree.line);

    GazelleTree child = new(joinWithVBar(out));
    child.ctx = ctx;
    child.isSplitNode = true;
    tree.add(child);
    
    for (S line : out)
      child.add(GazelleTree(line));
  }
  
  // Other rules
    
  bool firstConditionOnly = boolPar firstConditionOnly(_);
  O[] params = litobjectarray(debug := optPar debug(_), +tree);
  L<RuleEngine2_MatchedRule> l = sortByMethodDesc qualitySum(
    firstConditionOnly
      ? ai_ruleEngine2_rulesForInput_5(engine, inputMap, params)
      : ai_ruleEngine2_rulesForInput_5_allConditions(engine, inputMap, params));
  //print("Got rules: " + l(l));
  
  for (RuleEngine2_MatchedRule r : l) {
    double quality = r.relativeQuality();
    if (quality < qualityCutOff) {
      if (debug) print("Match under quality (" + quality + "/" + qualityCutOff + "): " + r);
      continue;
    }
    S line = r.outText();
    
    GazelleTree child = new(line);
    child.ctx = ctx;
    child.mr = r;
    if (r.rule != null) child.lineType = r.rule.outType;
    
    gazelle_addPredictionToTreeNode(child);
    tree.add(child);
  }
  gazelle_sortChildren(tree);
  ret tree.children;
}