private async Task <ICollection <MergedWord> > FindMergeWords( string parentWord, string injectWord, ResultSet returnOnFirstResult, SynonymsOfInjectWord checkSynonymsOfInjectWord, SynonymsOfParentWord checkSynonymsOfParentWord ) { parentWord = parentWord.ToLower(); injectWord = injectWord.ToLower(); var mappedPairs = new List <MergedWord>(); // Create a list of synonyms for the injected word var injectWords = new List <string>(); injectWords.Add(injectWord); if (checkSynonymsOfInjectWord.Equals(SynonymsOfInjectWord.INCLUDE)) { injectWords.AddRange(await GetFilteredSynonymsOfWord(injectWord)); } // Create a list of synonyms for the parent word var parentWords = new List <string>(); parentWords.Add(parentWord); if (checkSynonymsOfParentWord.Equals(SynonymsOfParentWord.INCLUDE)) { parentWords.AddRange(await GetFilteredSynonymsOfWord(parentWord)); } // Go through each inject word option (synonyms) and each of their related words (sounds like, spells like) foreach (var selectedinjectWord in injectWords) { var pivotOptions = await GetFilteredSimilarWordsFromWord(selectedinjectWord); // Process each similar word option and the word replacements for these words. foreach (var similarWordOption in pivotOptions) { foreach (string parentWordOption in parentWords) { foreach (string wordAttempt in FindCommonCharacterReplacements(similarWordOption.Word) .Where(w => parentWordOption.Contains(w))) { var replaceStartIndex = parentWordOption.IndexOf(wordAttempt, StringComparison.Ordinal); var replaceEndIndex = replaceStartIndex + wordAttempt.Length; var word = parentWordOption.Substring(0, replaceStartIndex) + selectedinjectWord + parentWordOption.Substring(replaceEndIndex); MergedWord match = new MergedWord { Word = word, Score = similarWordOption.Score, InjectedWord = selectedinjectWord, ParentWord = parentWordOption }; if (!mappedPairs.Any(x => x.Word == match.Word)) { mappedPairs.Add(match); if (returnOnFirstResult.Equals(ResultSet.FIRST_RESULT_ONLY)) { return(mappedPairs); } } } } } } return(mappedPairs); }