private TokenChanges FindBestPath(ParsedSequence seq, int end, Dictionary<ParsedSequenceKey, SequenceTokenChanges> memiozation) { if (_parseResult.TerminateParsing) throw new OperationCanceledException(); SequenceTokenChanges result; var key = new ParsedSequenceKey(seq, end); if (memiozation.TryGetValue(key, out result)) return result.TotalTokenChanges; if (seq.StartPos == end) { var tokenChanges = new TokenChanges(seq.ParsingSequence.MandatoryTokenCount, 0); memiozation.Add(key, new SequenceTokenChanges(new SubrulesTokenChanges(), tokenChanges)); return tokenChanges; } var results = new SubrulesTokenChanges(); var validSubrules = seq.GetValidSubrules(end).ToList(); if (validSubrules.Count == 0) { var tokenChanges = new TokenChanges(); memiozation.Add(key, new SequenceTokenChanges(results, tokenChanges)); return tokenChanges; } memiozation.Add(key, new SequenceTokenChanges(results, TokenChanges.Fail)); foreach (var subrule in validSubrules) { TokenChanges localMin = TokenChanges.Fail; if (_deletedToken.ContainsKey(new ParsedSequenceAndSubrule(seq, subrule))) localMin = new TokenChanges(0, 1); else localMin = LocalMinForSubSequence(seq, memiozation, subrule, localMin); results[subrule] = localMin; } TokenChanges comulativeMin; if (results.Count == 0) { } var bestResults = RemoveWorstPaths(seq, end, results, out comulativeMin); var result2 = new SequenceTokenChanges(bestResults, comulativeMin); memiozation[key] = result2; return result2.TotalTokenChanges; }