protected void deleteKey(Locale locale, String bundleName, String key) {
    Properties tempProp = i18nMgr.getPropertiesWithoutResolvingRecursively(locale, bundleName);
    tempProp.remove(key);
    i18nMgr.saveOrUpdateProperties(tempProp, locale, bundleName);

    checkForEmptyPropertyAndDelete(locale, bundleName);
    checkForEmptyBundleAndDelete(bundleName);
  }
 public void sortKeysTask(boolean reallySortIt) {
   List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles();
   Set<String> allLangs = getAllLanguages();
   int counter = 0;
   for (String langKey : allLangs) {
     Locale locale = i18nMgr.getLocaleOrNull(langKey);
     for (String bundleName : allBundles) {
       Properties properties =
           i18nMgr.getPropertiesWithoutResolvingRecursively(locale, bundleName);
       if (reallySortIt) {
         // since opened as SortedProperties, save will sort it. Nothing changed, just resorted
         if (properties.size() != 0) {
           i18nMgr.saveOrUpdateProperties(properties, locale, bundleName);
         }
       } else {
         log.info("Sorting " + langKey + ":" + bundleName);
       }
       counter++;
     }
   }
   log.info("Sorted " + counter + " properties files");
 }
 /**
  * Check for keys that exist in target languages but not in EN or DE. Delete such keys in the
  * target languages
  *
  * @param reallyRemoveIt true: really delete; false: verbose dry run
  * @param referenceLanguages array that contains the language keys that serves as a reference
  *     (e.g. en and de)
  * @param languages the languages that should be cleaned up
  */
 public void removeDeletedKeys(
     boolean reallyRemoveIt, String[] referenceLanguages, Set<String> languages) {
   // first get all available keys from de and en language
   Set<String> validCombinedKeys = new HashSet<String>();
   // copy list to prevent concurrent modification exception
   List<String> allBundles = new ArrayList<String>(I18nModule.getBundleNamesContainingI18nFiles());
   for (String bundleName : allBundles) {
     for (String refLangKey : referenceLanguages) {
       Properties properties =
           i18nMgr.getPropertiesWithoutResolvingRecursively(
               i18nMgr.getLocaleOrNull(refLangKey), bundleName);
       if (properties == null) {
         throw new OLATRuntimeException("Invalid reference language::" + refLangKey, null);
       } else {
         for (Object keyObj : properties.keySet()) {
           String key = (String) keyObj;
           String combinedKey = bundleName + ":" + key;
           validCombinedKeys.add(combinedKey);
         }
       }
     }
   }
   log.info(
       "removeDeletedKeys: found "
           + validCombinedKeys.size()
           + " valid keys in "
           + ArrayHelper.toString(referenceLanguages));
   //
   // For each language except DE and EN, go through all i18n files and
   // remove keys not in the valid set
   for (String langKey : languages) {
     boolean isRefLang = false;
     for (String refLangKey : referenceLanguages) {
       if (refLangKey.equals(langKey)) {
         isRefLang = true;
         break;
       }
     }
     if (isRefLang) continue;
     // Not a reference language - delete from here
     Locale locale = i18nMgr.getLocaleOrNull(langKey);
     for (String bundleName : allBundles) {
       Properties properties =
           i18nMgr.getPropertiesWithoutResolvingRecursively(locale, bundleName);
       int propCount = properties.size();
       // copy keys to prevent concurrent modification
       Set<String> availableKeys = new HashSet<String>();
       for (Object key : properties.keySet()) {
         availableKeys.add((String) key);
       }
       for (String key : availableKeys) {
         String combinedKey = bundleName + ":" + key;
         if (!validCombinedKeys.contains(combinedKey)) {
           if (reallyRemoveIt) {
             log.info(
                 "Deleting "
                     + langKey
                     + ":"
                     + bundleName
                     + ":"
                     + key
                     + " - does not exist in "
                     + ArrayHelper.toString(referenceLanguages));
             properties.remove(key);
           } else {
             log.info(
                 "Should be deleted: "
                     + langKey
                     + ":"
                     + bundleName
                     + ":"
                     + key
                     + " - does not exist in "
                     + ArrayHelper.toString(referenceLanguages));
           }
         }
       }
       int delCount = (propCount - properties.size());
       if (reallyRemoveIt && delCount > 0) {
         // only save when changed
         i18nMgr.saveOrUpdateProperties(properties, locale, bundleName);
         log.info(
             "For language::"
                 + langKey
                 + " the in bundle:: "
                 + bundleName
                 + " deleted "
                 + delCount
                 + " keys");
       }
       // delete empty bundles
       if (reallyRemoveIt && properties.size() == 0) {
         i18nMgr.deleteProperties(locale, bundleName);
         log.info(
             "Bundle:: "
                 + bundleName
                 + " deleted for language "
                 + langKey
                 + "entirely because it was empty");
       }
     }
   }
 }