/// <summary>
        ///     Collectes translations of <paramref name="text" /> for <paramref name="targetLanguage" />
        ///     that share the same translation in <paramref name="inputLanguage" />.
        /// </summary>
        /// <param name="text">The text in <paramref name="inputLanguage" />.</param>
        /// <param name="targetLanguage">The language for which translations should be collected.</param>
        /// <param name="inputLanguage">The language of <paramref name="text" />.</param>
        /// <param name="allTranslations">
        ///     The collection of all translation to pull the needed translations from.
        /// </param>
        /// <returns>
        ///     All possible translations of <paramref name="text" /> into <paramref name="targetLanguage" />
        ///     based on which keys inside the inner Dictionary of <paramref name="allTranslations" /> share
        ///     the same translations in <paramref name="inputLanguage" />.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     Thrown, if <paramref name="targetLanguage" />, <paramref name="inputLanguage" /> or
        ///     <paramref name="allTranslations" /> is null.
        /// </exception>
        /// <exception cref="InputLanguageNotFoundException">
        ///     Thrown, if <paramref name="allTranslations" /> does not contain <paramref name="inputLanguage" />.
        /// </exception>
        public static IEnumerable <string> ExtractKnownTranslations(string text, CultureInfo targetLanguage,
                                                                    CultureInfo inputLanguage, Dictionary <CultureInfo, Dictionary <string, string> > allTranslations)
        {
            //null and argument checks.
            ExceptionLoggingUtils.VerifyMultiple(targetLanguage, nameof(targetLanguage))
            .AlsoVerify(inputLanguage, nameof(inputLanguage))
            .AlsoVerify(allTranslations, nameof(allTranslations))
            .ThrowIfNull(Logger, nameof(ExtractKnownTranslations),
                         "Unable to extract known translation for null parameter.");

            ExceptionLoggingUtils.ThrowIfInputLanguageMissing(Logger, allTranslations.Keys.ToList(), inputLanguage,
                                                              "InputLanguage is not part of languages collection.",
                                                              "Unable to generate translation recommendations for Localizaions without InputLanguage.");

            allTranslations.TryGetValue(inputLanguage, out var sourceDictionary);

            ICollection <string> knownTranslations = new Collection <string>();

            if (string.IsNullOrWhiteSpace(text) || Equals(targetLanguage, inputLanguage))
            {
                //no Exceptions should be thrown here.
                return(knownTranslations);
            }

            //get all entries out of sourceDictionary, where value matches given text
            var fittingDictionaryEntries =
                sourceDictionary.Where(x => text.Equals(x.Value));

            //collect possible translations
            foreach (var entry in fittingDictionaryEntries)
            {
                var value = "";
                allTranslations.TryGetValue(targetLanguage, out var langDict);
                langDict?.TryGetValue(entry.Key, out value);

                //do not recommend the same translation twice
                if (!string.IsNullOrWhiteSpace(value) && !knownTranslations.Contains(value))
                {
                    knownTranslations.Add(value);
                }
            }

            return(knownTranslations);
        }
        /// <summary>
        ///     Returns a placeholder text (e.g. "fr--Total amount") and evaluates, what translation
        ///     should be used as basis for the text (part after "fr--").
        /// </summary>
        /// <param name="targetLanguage">The language for which the placeholder needs to be generated.</param>
        /// <param name="localizedTexts">
        ///     The collection of all known translations.
        /// </param>
        /// <param name="preferPreferredOverInputLangauge">
        ///     Determines which out of <paramref name="inputLanguage" /> and <paramref name="preferredLanguage" />
        ///     should be used by default.
        ///     This value will be ignored, if there are conflicts with the preference (e.g.
        ///     <paramref name="targetLanguage" /> being identical to <paramref name="preferedLanguage" /> or
        ///     <paramref name="inputLanguage" />).
        /// </param>
        /// <param name="inputLanguage">The language in which the application was originally created in.</param>
        /// <param name="preferredLanguage">
        ///     The language to fall back to, if <paramref name="inputLanguage" /> is the <paramref name="targetLanguage" />
        ///     or to aid as basis for further translation (e.g application was originally french, is then translated
        ///     to english and from english to multiple others).
        /// </param>
        /// <returns>
        ///     The full placeholder string consisting of language code, "--" and the translation of
        ///     <paramref name="inputLanguage" /> or <paramref name="preferredLanguage" />.
        /// </returns>
        /// <exception cref="InputLanguageNotFoundException">
        ///     Thrown, if <paramref name="localizedTexts" /> does not contain <paramref name="inputLanguage" />.
        /// </exception>
        public static string GetRecommendedText(CultureInfo targetLanguage,
                                                ICollection <TextLocalization> localizedTexts, bool preferPreferredOverInputLangauge,
                                                CultureInfo inputLanguage, CultureInfo preferredLanguage)
        {
            ExceptionLoggingUtils.ThrowIfInputLanguageMissing(Logger,
                                                              localizedTexts.Select(loc => loc.Language), inputLanguage,
                                                              "InputLanguage is not part of languages collection.",
                                                              "Unable to generate translation recommendations for Localizaions without InputLanguage.");

            var usePreferredInsted = EvaluateLanguagePreference(preferPreferredOverInputLangauge, localizedTexts,
                                                                targetLanguage, preferredLanguage, inputLanguage);

            //Will find a fitting entry, because EvaluateLanguagePreference returns false
            //to usePreferredInsted if list does not contain the preferredLanguage and this function
            //throws InputLanguageNotFoundException is inputLanguage is not in the list.
            var recommendedTranslation = localizedTexts.First(loc => Equals(loc.Language,
                                                                            usePreferredInsted ? preferredLanguage : inputLanguage)).Text;

            return(targetLanguage.Name + "--" + recommendedTranslation);
        }