/// <summary>
        /// Save translation context as missing in a new file in case it is missing
        /// </summary>
        private async Task SaveTranslationContextMissing(Dictionary <string, string> texts, string lang, string area, string context)
        {
            XmlTranslationRoot root = await GetMissingTranslationRootAsync(lang, area, context);


            // Check if the area already exists in the root object, otherwise create it
            var areaNode = root.FirstOrDefault(al => al.Lang == lang && al.Area == area);

            if (areaNode == null)
            {
                areaNode = new XmlTranslationAreaLang()
                {
                    Area = area, Lang = lang
                }; root.Add(areaNode);
            }

            // Check if the context already exists in the area node, otherwise create it
            var contextNode = areaNode.Contexts.ContainsKey(context) ? areaNode.Contexts[context] : null;

            if (contextNode == null)
            {
                contextNode = new XmlTranslationAreaContext()
                {
                    Name = context
                }; areaNode.Contexts.Add(context, contextNode);
            }

            // Update the context, if needed and save the modified file
            var alreadySet  = contextNode.Missing.Select(k => k.Key);
            var alreadySet2 = contextNode.Entries.Select(k => k.Key);
            var keysToAdd   = texts.Keys.Except(alreadySet).Except(alreadySet2).ToList();

            if (keysToAdd.Count() > 0)
            {
                foreach (var t in keysToAdd)
                {
                    contextNode.Missing.Add(new XmlTranslationKeyText()
                    {
                        Key = t, Text = texts[t]
                    });
                }

                // if some changed happened, save the request origin
                //var infos = GetRouteInfo();
                //contextNode.MissingInfo.Add($"[{infos.Method}] {infos.RouteTemplate} {infos.RouteName} {infos.RequestUrl}");
                contextNode.MissingInfo.Add($"[{area}] {context}");

                // Keep log size reasonable
                if (contextNode.MissingInfo.Count > 150)
                {
                    contextNode.MissingInfo = contextNode.MissingInfo.Distinct().Take(100).ToList();
                }

                await root.Save();
            }
        }
        // Assumes that files are well named, and one language per file
        private List <XmlTranslationRoot> InitTranslations(string lang)
        {
            var xtrs = new List <XmlTranslationRoot>();

            foreach (var c in _Configs.Where(c => c.Langs == null || c.Langs.Count == 0 || c.Langs.Contains(lang)))
            {
                foreach (var d in c.Folders)
                {
                    xtrs.AddRange(XmlTranslationRoot.LoadAll(d, pattern: $"*.{lang}.xml", includeSubdirectories: true));
                }
            }
            return(xtrs);
        }
        public async Task <XmlTranslationRoot> GetMissingTranslationRootAsync(string lang, string area, string context)
        {
            var(missingFolder, fileName) = GetMissingFile(lang, area, context);
            var missingFile = Path.Combine(missingFolder, fileName);

            // Build a translation root object.
            //   If the file exists, load it
            //   Otherwise create it
            XmlTranslationRoot root;

            if (File.Exists(missingFile))
            {
                root = XmlTranslationRoot.Load(missingFile);
            }
            else
            {
                root          = new XmlTranslationRoot();
                root.FilePath = missingFile;
                await root.SaveNew(missingFolder, fileName);
            }
            return(root);
        }
        /// <summary>
        /// Check if some translations are missing from a context
        /// </summary>
        private async Task <(IEnumerable <string> ValidKeys, IEnumerable <string> MissingKeys)> CheckIfKeysAreMissing(Dictionary <string, string> texts, XmlTranslationAreaContext validContext, XmlTranslationRoot root, string lang, string area, string context)
        {
            // Check if missing keys in translation context
            var missingKeys = texts.Keys.Except(validContext.Entries.Keys);

            if (missingKeys.Count() > 0)
            {
                var texts2 = new Dictionary <string, string>();
                foreach (var k in missingKeys)
                {
                    texts2[k] = texts[k];
                }
                await SaveTranslationContextMissing(texts2, lang, area, context);

                /*
                 * // Check if missing keys have not been saved already
                 * var missing = missingKeys.Except(context.Missing.Select(k => k.Key));
                 * // If any missing, then save the missing keys into the appropriate section of the translation file
                 * if (missing.Count() > 0)
                 * {
                 *  foreach (var m in missing)
                 *  {
                 *      // For each missing key, save the key and the default translation text
                 *      context.Missing.Add(new XmlTranslationKeyText() { Key = m, Text = texts[m] });
                 *  }
                 *  // Save the translation file as it has been modified
                 *  await root.Save();
                 * }*/
            }

            var validKeys = texts.Keys.Except(missingKeys).ToList();

            return(validKeys, missingKeys);
        }