/// <summary>
        /// Creates or updates collection
        /// </summary>
        /// <param name="collectionName"></param>
        /// <param name="categoryName"></param>
        public void SetCollection(string collectionName, string categoryName)
        {
            lock (Lock)
            {
                // Get the localization collection. If it does not exist, create it first
                var localizationCategory = LocalizationCategories.FirstOrDefault(x => x.Name.ToLower() == categoryName.ToLower());
                if (localizationCategory == null)
                {
                    localizationCategory = new LocalizationCategory
                    {
                        Name = categoryName
                    };
                    Provider.InsertOrUpdateLocalizationCategory(localizationCategory);
                    LocalizationCategories = Provider.LoadLocalizationCategories();
                    localizationCategory   = LocalizationCategories.FirstOrDefault(x => x.Name.ToLower() == categoryName.ToLower());
                }

                if (localizationCategory == null)
                {
                    return;
                }

                var collection = LocalizationCollections.FirstOrDefault(x => x.Name.ToLower() == collectionName.ToLower())
                                 ?? new LocalizationCollection
                {
                    LocalizationCategoryId = localizationCategory.Id
                };
                collection.Name = collectionName;
                Provider.InsertOrUpdateLocalizationCollection(collection);
                LocalizationCollections = Provider.LoadLocalizationCollections();
            }
        }
 /// <summary>
 /// Returns localization collection
 /// </summary>
 /// <param name="collection"></param>
 /// <param name="category"></param>
 /// <returns></returns>
 public LocalizationCollection GetCollection(string collection, string category = null)
 => LocalizationCollections.FirstOrDefault(x =>
                                           x.Name.ToLower() == collection.ToLower() &&
                                           (string.IsNullOrEmpty(category) || x.LocalizationCategory?.Name.ToLower() == category.ToLower()));
        /// <summary>
        /// Sets new translation for the provided key and language (or current culture language if not provided)
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="collection"></param>
        /// <param name="category"></param>
        /// <param name="culture"></param>
        public void Set(string key, string value, string collection, string category, CultureInfo culture = null)
        {
            lock (Lock)
            {
                // Get the localization key Id. If it does not exist, create it first
                var localizationKey = LocalizationKeys.FirstOrDefault(x => x.Name.ToLower() == key.ToLower());
                if (localizationKey == null)
                {
                    localizationKey = new LocalizationKey {
                        Name = key
                    };
                    Provider.InsertLocalizationKey(localizationKey);
                    LocalizationKeys = Provider.LoadLocalizationKeys();
                    localizationKey  = LocalizationKeys.FirstOrDefault(x => x.Name.ToLower() == key.ToLower());
                }
                if (localizationKey == null)
                {
                    return;
                }

                // Get the localization language. If it does not exist, create it first
                var langName             = GetLanguageNameFromCulture(culture).ToLower();
                var langDisplayName      = GetLanguageDisplayNameFromCulture(culture);
                var localizationLanguage = LocalizationLanguages.FirstOrDefault(x => x.Name.ToLower() == GetLanguageNameFromCulture(culture).ToLower());
                if (localizationLanguage == null)
                {
                    localizationLanguage = new LocalizationLanguage
                    {
                        Name  = langName,
                        Value = langDisplayName
                    };
                    Provider.InsertLocalizationLanguage(localizationLanguage);
                    LocalizationLanguages = Provider.LoadLocalizationLanguages();
                    localizationLanguage  = LocalizationLanguages.FirstOrDefault(x => x.Name.ToLower() == GetLanguageNameFromCulture(culture).ToLower());
                }
                if (localizationLanguage == null)
                {
                    return;
                }

                // Get the localization collection. If it does not exist, create it first
                var localizationCategory = LocalizationCategories.FirstOrDefault(x => x.Name.ToLower() == category.ToLower());
                if (localizationCategory == null)
                {
                    localizationCategory = new LocalizationCategory
                    {
                        Name = category
                    };
                    Provider.InsertOrUpdateLocalizationCategory(localizationCategory);
                    LocalizationCategories = Provider.LoadLocalizationCategories();
                    localizationCategory   = LocalizationCategories.FirstOrDefault(x => x.Name.ToLower() == category.ToLower());
                }
                if (localizationCategory == null)
                {
                    return;
                }

                // Get the localization collection. If it does not exist, create it first
                var localizationCollection = LocalizationCollections.FirstOrDefault(x =>
                                                                                    x.Name.ToLower() == collection.ToLower() &&
                                                                                    x.LocalizationCategoryId == localizationCategory.Id);

                if (localizationCollection == null)
                {
                    localizationCollection = new LocalizationCollection
                    {
                        Name = collection,
                        LocalizationCategoryId = localizationCategory.Id
                    };
                    Provider.InsertOrUpdateLocalizationCollection(localizationCollection);
                    LocalizationCollections = Provider.LoadLocalizationCollections();
                    localizationCollection  = LocalizationCollections.FirstOrDefault(x =>
                                                                                     x.Name.ToLower() == collection.ToLower() &&
                                                                                     x.LocalizationCategoryId == localizationCategory.Id);
                }
                if (localizationCollection == null)
                {
                    return;
                }
                localizationCollection.LocalizationCategory   = localizationCategory;
                localizationCollection.LocalizationCategoryId = localizationCategory.Id;

                // Don't check the collection since only one combination of key and language is allowed across collections
                var entry = LocalizationEntries.FirstOrDefault(x => x.LocalizationKeyId == localizationKey.Id &&
                                                               x.LocalizationLanguageId == localizationLanguage.Id);

                if (entry == null)
                {
                    // Create
                    entry = new LocalizationEntry
                    {
                        Value = value,
                        LocalizationCollectionId = localizationCollection.Id,
                        LocalizationKeyId        = localizationKey.Id,
                        LocalizationLanguageId   = localizationLanguage.Id,
                        CreatedOn = DateTime.UtcNow,
                        UpdatedOn = DateTime.UtcNow
                    };
                    Provider.InsertLocalizationEntry(entry);
                    LocalizationEntries = Provider.LoadLocalizationEntries();
                }
            }
        }