public static bool ContainsRecursive(this TranslationSet haystack, TranslationSet needle)
        {
            if (haystack == null)
            {
                return false;
            }

            if (needle == null)
            {
                throw new ArgumentNullException(nameof(needle));
            }

            if (ReferenceEquals(haystack, needle)
                || haystack.Translations.Select(t => t.Words.Select(w => new Word(w, t.Language))).Any(ws => needle.Translations.Any(t => t.Words.Select(ww => new Word(ww, t.Language)).Any(ww => ws.Any(w => w.Equals(ww))))))
            {
                return true;
            }

            var any = false;
            Parallel.ForEach(
                haystack.Parents,
                (parent, state) =>
                {
                    if (parent.ContainsRecursive(needle))
                    {
                        any = true;
                        state.Break();
                    }
                });
            return any;
        }
        private static async Task WriteToAsync(TextWriter writer, TranslationSet translationSet, IComparer <CultureData> languageComparer)
        {
            if (translationSet.Translations.Count == 0 && translationSet.LinkedData.Count == 0)
            {
                return;
            }

            foreach (var parent in translationSet.Parents)
            {
                await WriteParentAsync(writer, parent, languageComparer);
            }

            var english = Culture.FromIsoName("en");

            foreach (var translation in translationSet.Translations.Where(t => t.Language.Equals(english))) // "en" first
            {
                await WriteTranslationAsync(writer, translation);
            }

            foreach (var translation in translationSet.Translations.Where(t => !t.Language.Equals(english)))
            {
                await WriteTranslationAsync(writer, translation);
            }

            foreach (var linkedData in translationSet.LinkedData)
            {
                await WriteTranslationAsync(writer, linkedData);
            }

            await writer.WriteLineAsync();
        }
        private static async Task WriteParentAsync(TextWriter writer, TranslationSet parent, IComparer <CultureData> languageComparer)
        {
            var mostImportantTranslation = parent.Translations.Where(t => t.Words.Count > 0).OrderByDescending(t => t.Language, languageComparer).FirstOrDefault();

            if (mostImportantTranslation == null)
            {
                return;
            }

            await writer.WriteAsync(Constants.ParentIndicator);

            await writer.WriteAsync(mostImportantTranslation.Language.Name);

            await writer.WriteAsync(Constants.LanguageSeparator);

            await writer.WriteLineAsync(string.Join(Constants.TermSeparator + " ", mostImportantTranslation.Words.First()));
        }
        private static async Task WriteParentAsync(TextWriter writer, TranslationSet parent, IComparer<CultureData> languageComparer)
        {
            var mostImportantTranslation = parent.Translations.Where(t => t.Words.Count > 0).OrderByDescending(t => t.Language, languageComparer).FirstOrDefault();
            if (mostImportantTranslation == null)
            {
                return;
            }

            await writer.WriteAsync(Constants.ParentIndicator);
            await writer.WriteAsync(mostImportantTranslation.Language.Name);
            await writer.WriteAsync(Constants.LanguageSeparator);
            await writer.WriteLineAsync(string.Join(Constants.TermSeparator + " ", mostImportantTranslation.Words.First()));
        }
        private static async Task WriteToAsync(TextWriter writer, TranslationSet translationSet, IComparer<CultureData> languageComparer)
        {
            if (translationSet.Translations.Count == 0 && translationSet.LinkedData.Count == 0)
            {
                return;
            }

            foreach (var parent in translationSet.Parents)
            {
                await WriteParentAsync(writer, parent, languageComparer);
            }

            var english = Culture.FromIsoName("en");
            foreach (var translation in translationSet.Translations.Where(t => t.Language.Equals(english))) // "en" first
            {
                await WriteTranslationAsync(writer, translation);
            }

            foreach (var translation in translationSet.Translations.Where(t => !t.Language.Equals(english)))
            {
                await WriteTranslationAsync(writer, translation);
            }

            foreach (var linkedData in translationSet.LinkedData)
            {
                await WriteTranslationAsync(writer, linkedData);
            }

            await writer.WriteLineAsync();
        }
 private static Translation EvaluateMostImportantTranslation(TranslationSet ts, IComparer<CultureData> languageComparer)
 {
     return EvaluateMostImportantTranslation(ts.Translations, languageComparer);
 }