docs: protected void appendResourceToManifest(CmsResource resource, boolean source, boolean isSuperFolder)
      throws CmsImportExportException, SAXException {
  
          try {
              // only write <source> if resource is a file
              String fileName = trimResourceName(getCms().getSitePath(resource));
              if (fileName.startsWith("system/orgunits")) {
                  // it is not allowed to export organizational unit resources
                  // export the organizational units instead
                  return;
              }
  
              // define the file node
              Element fileElement = m_resourceNode.addElement(CmsImportVersion10.N_FILE);
  
              if (resource.isFile()) {
                  if (source) {
                      fileElement.addElement(CmsImportVersion10.N_SOURCE).addText(fileName);
                  }
              } else {
                  m_exportCount++;
                  I_CmsReport report = getReport();
                  // output something to the report for the folder
                  report.print(
                      org.opencms.report.Messages.get().container(
                          org.opencms.report.Messages.RPT_SUCCESSION_1,
                          String.valueOf(m_exportCount)),
                      I_CmsReport.FORMAT_NOTE);
                  report.print(Messages.get().container(Messages.RPT_EXPORT_0), I_CmsReport.FORMAT_NOTE);
                  report.print(
                      org.opencms.report.Messages.get().container(
                          org.opencms.report.Messages.RPT_ARGUMENT_1,
                          getCms().getSitePath(resource)));
                  report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
                  report.println(
                      org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
                      I_CmsReport.FORMAT_OK);
  
                  if (LOG.isInfoEnabled()) {
                      LOG.info(
                          Messages.get().getBundle().key(
                              Messages.LOG_EXPORTING_OK_2,
                              String.valueOf(m_exportCount),
                              getCms().getSitePath(resource)));
                  }
              }
  
              boolean isReducedExportMode = m_parameters.getExportMode().equals(ExportMode.REDUCED);
              boolean isMinimalMetaData = isReducedExportMode && isSuperFolder && exportWithMinimalMetaData(fileName);
  
              // <destination>
              fileElement.addElement(CmsImportVersion10.N_DESTINATION).addText(fileName);
              // <type>
              fileElement.addElement(CmsImportVersion10.N_TYPE).addText(
                  OpenCms.getResourceManager().getResourceType(resource.getTypeId()).getTypeName());
  
              if (!isMinimalMetaData) {
                  //  <uuidstructure>
                  fileElement.addElement(CmsImportVersion10.N_UUIDSTRUCTURE).addText(
                      resource.getStructureId().toString());
                  if (resource.isFile()) {
                      //  <uuidresource>
                      fileElement.addElement(CmsImportVersion10.N_UUIDRESOURCE).addText(
                          resource.getResourceId().toString());
                  }
              }
  
              if (!isReducedExportMode) {
                  // <datelastmodified>
                  fileElement.addElement(CmsImportVersion10.N_DATELASTMODIFIED).addText(
                      getDateLastModifiedForExport(resource));
                  // <userlastmodified>
                  String userNameLastModified = null;
                  try {
                      userNameLastModified = getCms().readUser(resource.getUserLastModified()).getName();
                  } catch (@SuppressWarnings("unused") CmsException e) {
                      userNameLastModified = OpenCms.getDefaultUsers().getUserAdmin();
                  }
                  fileElement.addElement(CmsImportVersion10.N_USERLASTMODIFIED).addText(userNameLastModified);
              }
              if (!isMinimalMetaData) {
                  // <datecreated>
                  fileElement.addElement(CmsImportVersion10.N_DATECREATED).addText(
                      CmsDateUtil.getHeaderDate(resource.getDateCreated()));
              }
              if (!isReducedExportMode) {
                  // <usercreated>
                  String userNameCreated = null;
                  try {
                      userNameCreated = getCms().readUser(resource.getUserCreated()).getName();
                  } catch (@SuppressWarnings("unused") CmsException e) {
                      userNameCreated = OpenCms.getDefaultUsers().getUserAdmin();
                  }
                  fileElement.addElement(CmsImportVersion10.N_USERCREATED).addText(userNameCreated);
              }
              if (!isMinimalMetaData) {
                  // <release>
                  if (resource.getDateReleased() != CmsResource.DATE_RELEASED_DEFAULT) {
                      fileElement.addElement(CmsImportVersion10.N_DATERELEASED).addText(
                          CmsDateUtil.getHeaderDate(resource.getDateReleased()));
                  }
                  // <expire>
                  if (resource.getDateExpired() != CmsResource.DATE_EXPIRED_DEFAULT) {
                      fileElement.addElement(CmsImportVersion10.N_DATEEXPIRED).addText(
                          CmsDateUtil.getHeaderDate(resource.getDateExpired()));
                  }
                  // <flags>
                  int resFlags = resource.getFlags();
                  resFlags &= ~CmsResource.FLAG_LABELED;
                  fileElement.addElement(CmsImportVersion10.N_FLAGS).addText(Integer.toString(resFlags));
  
                  // write the properties to the manifest
                  Element propertiesElement = fileElement.addElement(CmsImportVersion10.N_PROPERTIES);
                  List<CmsProperty> properties = getCms().readPropertyObjects(getCms().getSitePath(resource), false);
                  // sort the properties for a well defined output order
                  Collections.sort(properties);
                  for (int i = 0, n = properties.size(); i < n; i++) {
                      CmsProperty property = properties.get(i);
                      if (isIgnoredProperty(property)) {
                          continue;
                      }
                      addPropertyNode(propertiesElement, property.getName(), property.getStructureValue(), false);
                      addPropertyNode(propertiesElement, property.getName(), property.getResourceValue(), true);
                  }
  
                  // Write the relations to the manifest
                  List<CmsRelation> relations = getCms().getRelationsForResource(
                      resource,
                      CmsRelationFilter.TARGETS.filterNotDefinedInContent());
                  Element relationsElement = fileElement.addElement(CmsImportVersion10.N_RELATIONS);
                  // iterate over the relations
                  for (CmsRelation relation : relations) {
                      // relation may be broken already:
                      try {
                          CmsResource target = relation.getTarget(getCms(), CmsResourceFilter.ALL);
                          String structureId = target.getStructureId().toString();
                          String sitePath = getCms().getSitePath(target);
                          String relationType = relation.getType().getName();
                          addRelationNode(relationsElement, structureId, sitePath, relationType);
                      } catch (CmsVfsResourceNotFoundException crnfe) {
                          // skip this relation:
                          if (LOG.isWarnEnabled()) {
                              LOG.warn(
                                  Messages.get().getBundle().key(
                                      Messages.LOG_IMPORTEXPORT_WARN_DELETED_RELATIONS_2,
                                      new String[] {relation.getTargetPath(), resource.getRootPath()}),
                                  crnfe);
                          }
                      }
                  }
  
                  // append the nodes for access control entries
                  Element acl = fileElement.addElement(CmsImportVersion10.N_ACCESSCONTROL_ENTRIES);
  
                  // read the access control entries
                  List<CmsAccessControlEntry> fileAcEntries = getCms().getAccessControlEntries(
                      getCms().getSitePath(resource),
                      false);
                  Iterator<CmsAccessControlEntry> i = fileAcEntries.iterator();
  
                  // create xml elements for each access control entry
                  while (i.hasNext()) {
                      CmsAccessControlEntry ace = i.next();
                      Element a = acl.addElement(CmsImportVersion10.N_ACCESSCONTROL_ENTRY);
  
                      // now check if the principal is a group or a user
                      int flags = ace.getFlags();
                      String acePrincipalName = "";
                      CmsUUID acePrincipal = ace.getPrincipal();
                      if ((flags & CmsAccessControlEntry.ACCESS_FLAGS_ALLOTHERS) > 0) {
                          acePrincipalName = CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_NAME;
                      } else if ((flags & CmsAccessControlEntry.ACCESS_FLAGS_OVERWRITE_ALL) > 0) {
                          acePrincipalName = CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_NAME;
                      } else if ((flags & CmsAccessControlEntry.ACCESS_FLAGS_GROUP) > 0) {
                          // the principal is a group
                          try {
                              acePrincipalName = getCms().readGroup(acePrincipal).getPrefixedName();
                          } catch (@SuppressWarnings("unused") CmsException e) {
                              // the group for this permissions does not exist anymore, so simply skip it
                          }
                      } else if ((flags & CmsAccessControlEntry.ACCESS_FLAGS_USER) > 0) {
                          // the principal is a user
                          try {
                              acePrincipalName = getCms().readUser(acePrincipal).getPrefixedName();
                          } catch (@SuppressWarnings("unused") CmsException e) {
                              // the user for this permissions does not exist anymore, so simply skip it
                          }
                      } else {
                          // the principal is a role
                          acePrincipalName = CmsRole.PRINCIPAL_ROLE + "." + CmsRole.valueOfId(acePrincipal).getRoleName();
                      }
  
                      // only add the permission if a principal was set
                      if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(acePrincipalName)) {
                          a.addElement(CmsImportVersion10.N_ACCESSCONTROL_PRINCIPAL).addText(acePrincipalName);
                          a.addElement(CmsImportVersion10.N_FLAGS).addText(Integer.toString(flags));
  
                          Element b = a.addElement(CmsImportVersion10.N_ACCESSCONTROL_PERMISSIONSET);
                          b.addElement(CmsImportVersion10.N_ACCESSCONTROL_ALLOWEDPERMISSIONS).addText(
                              Integer.toString(ace.getAllowedPermissions()));
                          b.addElement(CmsImportVersion10.N_ACCESSCONTROL_DENIEDPERMISSIONS).addText(
                              Integer.toString(ace.getDeniedPermissions()));
                      }
                  }
              } else {
                  fileElement.addElement(CmsImportVersion10.N_PROPERTIES);
              }
  
              // write the XML
              digestElement(m_resourceNode, fileElement);
          } catch (CmsImportExportException e) {
  
              throw e;
          } catch (CmsException e) {
  
              CmsMessageContainer message = Messages.get().container(
                  Messages.ERR_IMPORTEXPORT_ERROR_APPENDING_RESOURCE_TO_MANIFEST_1,
                  resource.getRootPath());
              if (LOG.isDebugEnabled()) {
                  LOG.debug(message.key(), e);
              }
  
              throw new CmsImportExportException(message, e);
          }
      }