docs: public I_CmsExtractionResult extractContent(
          CmsObject cms,
          CmsResource resource,
          I_CmsSearchIndex index,
          Locale forceLocale)
      throws CmsException {
  
          logContentExtraction(resource, index);
          I_CmsExtractionResult ex = null;
          try {
              CmsFile file = readFile(cms, resource);
              CmsXmlContainerPage containerPage = CmsXmlContainerPageFactory.unmarshal(cms, file);
  
              List<I_CmsExtractionResult> all = new ArrayList<I_CmsExtractionResult>();
              CmsContainerPageBean containerBean = containerPage.getContainerPage(cms);
              if (containerBean != null) {
                  for (CmsContainerElementBean element : containerBean.getElements()) {
                      // check all elements in this container
                      // get the formatter configuration for this element
                      try {
                          element.initResource(cms);
                          CmsResource elementResource = element.getResource();
                          if (!(cms.readProject(index.getProject()).isOnlineProject()
                              && elementResource.isExpired(System.currentTimeMillis()))) {
                              CmsADEConfigData adeConfig = OpenCms.getADEManager().lookupConfiguration(
                                  cms,
                                  file.getRootPath());
                              CmsFormatterConfiguration formatters = adeConfig.getFormatters(cms, element.getResource());
                              if ((formatters != null)
                                  && (element.getFormatterId() != null)
                                  && formatters.isSearchContent(element.getFormatterId())) {
                                  // the content of this element must be included for the container page
                                  all.add(
                                      CmsSolrDocumentXmlContent.extractXmlContent(
                                          cms,
                                          elementResource,
                                          index,
                                          forceLocale));
                              }
                          }
                      } catch (CmsException e) {
                          LOG.debug(
                              Messages.get().getBundle().key(
                                  Messages.LOG_SKIPPING_CONTAINERPAGE_ELEMENT_WITH_UNREADABLE_RESOURCE_2,
                                  file.getRootPath(),
                                  element.getId()),
                              e);
                      }
                  }
              }
              // we have to overwrite the resource and content locales with the one from this container page
              // TODO: Is this really the wanted behavior? It seems to be done like this before.
              Map<String, String> fieldMappings = new HashMap<String, String>(1);
              // Add to each container page the contents in all available locales,
              // in case one containerpage is used in multiple languages.
              List<Locale> localesAvailable = OpenCms.getLocaleManager().getAvailableLocales(cms, resource);
              Map<Locale, LinkedHashMap<String, String>> multilingualValues = new HashMap<Locale, LinkedHashMap<String, String>>(
                  localesAvailable.size());
              for (Locale localeAvailable : localesAvailable) {
                  multilingualValues.put(localeAvailable, new LinkedHashMap<String, String>());
              }
              Locale locale = forceLocale != null
              ? forceLocale
              : index.getLocaleForResource(cms, resource, containerPage.getLocales());
              ex = new CmsExtractionResult(locale, multilingualValues, fieldMappings);
              ex = ex.merge(all);
              return ex;
          } catch (Exception e) {
              throw new CmsIndexException(
                  Messages.get().container(Messages.ERR_TEXT_EXTRACTION_1, resource.getRootPath()),
                  e);
          }
      }