private IEnumerable <RuleMatch> RecurseMatch( // Used only for debugging purposes, to hook on the context ID of the entire sequence int masterContextID, ExplorerContext context, SubString originalText, int totalMatchLength, int iteration, ImmutableList <RuleMatch> childrenMatches) { var matches = context.InvokeRule(_rule); var nonEmptyMatches = matches.Where(m => m.Text.Length != 0); foreach (var match in nonEmptyMatches) { var newTotalMatchLength = totalMatchLength + match.LengthWithInterleaves; var newChildrenMatches = childrenMatches.Add(match); if (IsRepeatCountBelowMaximum(iteration + 1)) { // Recurse to next iteration var newContext = context.MoveForward(match); var downstreamMatches = RecurseMatch( masterContextID, newContext, originalText, newTotalMatchLength, iteration + 1, newChildrenMatches); foreach (var m in downstreamMatches) { yield return(m); } } // We are returning the matches in decreasing order of text length, so the "current" one goes last if (IsRepeatCountInRange(iteration)) { var matchText = originalText.Take(newTotalMatchLength); var completeMatch = new RuleMatch( this, matchText, () => ComputeOutput(matchText, newChildrenMatches)); yield return(completeMatch); } } }