docs: protected void initResourceBundle(Element root, CmsXmlContentDefinition contentDefinition, boolean single)
      throws CmsXmlException {
  
          if (m_messageBundleNames == null) {
              // it's uncommon to have more then one bundle so just initialize an array length of 2
              m_messageBundleNames = new ArrayList<String>(2);
          }
  
          if (single) {
              // single "resourcebundle" node
  
              String messageBundleName = root.attributeValue(APPINFO_ATTR_NAME);
              if (messageBundleName == null) {
                  throw new CmsXmlException(
                      Messages.get().container(
                          Messages.ERR_XMLCONTENT_MISSING_RESOURCE_BUNDLE_NAME_2,
                          root.getName(),
                          contentDefinition.getSchemaLocation()));
              }
              if (!m_messageBundleNames.contains(messageBundleName)) {
                  // avoid duplicates
                  m_messageBundleNames.add(messageBundleName);
              }
              // clear the cached resource bundles for this bundle
              CmsResourceBundleLoader.flushBundleCache(messageBundleName, false);
  
          } else {
              // multiple "resourcebundles" node
  
              // get an iterator for all "propertybundle" subnodes
              Iterator<Element> propertybundles = CmsXmlGenericWrapper.elementIterator(root, APPINFO_PROPERTYBUNDLE);
              while (propertybundles.hasNext()) {
                  // iterate all "propertybundle" elements in the "resourcebundle" node
                  Element propBundle = propertybundles.next();
                  String propertyBundleName = propBundle.attributeValue(APPINFO_ATTR_NAME);
                  if (!m_messageBundleNames.contains(propertyBundleName)) {
                      // avoid duplicates
                      m_messageBundleNames.add(propertyBundleName);
                  }
                  // clear the cached resource bundles for this bundle
                  CmsResourceBundleLoader.flushBundleCache(propertyBundleName, false);
              }
  
              // get an iterator for all "xmlbundle" subnodes
              Iterator<Element> xmlbundles = CmsXmlGenericWrapper.elementIterator(root, APPINFO_XMLBUNDLE);
              while (xmlbundles.hasNext()) {
                  Element xmlbundle = xmlbundles.next();
                  String xmlBundleName = xmlbundle.attributeValue(APPINFO_ATTR_NAME);
                  // cache the bundle from the XML
                  if (!m_messageBundleNames.contains(xmlBundleName)) {
                      // avoid duplicates
                      m_messageBundleNames.add(xmlBundleName);
                  }
                  // clear the cached resource bundles for this bundle
                  CmsResourceBundleLoader.flushBundleCache(xmlBundleName, true);
                  Iterator<Element> bundles = CmsXmlGenericWrapper.elementIterator(xmlbundle, APPINFO_BUNDLE);
                  while (bundles.hasNext()) {
                      // iterate all "bundle" elements in the "xmlbundle" node
                      Element bundle = bundles.next();
                      String localeStr = bundle.attributeValue(APPINFO_ATTR_LOCALE);
                      Locale locale;
                      if (CmsStringUtil.isEmptyOrWhitespaceOnly(localeStr)) {
                          // no locale set, so use no locale
                          locale = null;
                      } else {
                          // use provided locale
                          locale = CmsLocaleManager.getLocale(localeStr);
                      }
                      boolean isDefaultLocaleAndNotNull = (locale != null)
                          && locale.equals(CmsLocaleManager.getDefaultLocale());
  
                      CmsListResourceBundle xmlBundle = null;
  
                      Iterator<Element> resources = CmsXmlGenericWrapper.elementIterator(bundle, APPINFO_RESOURCE);
                      while (resources.hasNext()) {
                          // now collect all resource bundle keys
                          Element resource = resources.next();
                          String key = resource.attributeValue(APPINFO_ATTR_KEY);
                          String value = resource.attributeValue(APPINFO_ATTR_VALUE);
                          if (CmsStringUtil.isEmptyOrWhitespaceOnly(value)) {
                              // read from inside XML tag if value attribute is not set
                              value = resource.getTextTrim();
                          }
                          if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(key)
                              && CmsStringUtil.isNotEmptyOrWhitespaceOnly(value)) {
                              if (xmlBundle == null) {
                                  // use lazy initilaizing of the bundle
                                  xmlBundle = new CmsListResourceBundle();
                              }
                              xmlBundle.addMessage(key.trim(), value.trim());
                          }
                      }
                      if (xmlBundle != null) {
                          CmsResourceBundleLoader.addBundleToCache(xmlBundleName, locale, xmlBundle);
                          if (isDefaultLocaleAndNotNull) {
                              CmsResourceBundleLoader.addBundleToCache(xmlBundleName, null, xmlBundle);
                          }
                      }
                  }
              }
          }
      }