docs: public List<CmsSite> getAvailableSites(
          CmsObject cms,
          boolean workplaceMode,
          boolean showShared,
          String ouFqn,
          CmsSSLMode filterMode) {
  
          List<String> siteroots = new ArrayList<String>(m_siteMatcherSites.size() + 1);
          Map<String, CmsSiteMatcher> siteServers = new HashMap<String, CmsSiteMatcher>(m_siteMatcherSites.size() + 1);
          List<CmsSite> result = new ArrayList<CmsSite>(m_siteMatcherSites.size() + 1);
  
          Iterator<CmsSiteMatcher> i;
          // add site list
          i = m_siteMatcherSites.keySet().iterator();
          while (i.hasNext()) {
              CmsSite site = m_siteMatcherSites.get(i.next());
              String folder = CmsFileUtil.addTrailingSeparator(site.getSiteRoot());
              if (!siteroots.contains(folder)) {
                  siteroots.add(folder);
                  siteServers.put(folder, site.getSiteMatcher());
              }
          }
          // add default site
          if (workplaceMode && (m_defaultSite != null)) {
              String folder = CmsFileUtil.addTrailingSeparator(m_defaultSite.getSiteRoot());
              if (!siteroots.contains(folder)) {
                  siteroots.add(folder);
              }
          }
  
          String storedSiteRoot = cms.getRequestContext().getSiteRoot();
          try {
              // for all operations here we need no context
              cms.getRequestContext().setSiteRoot("/");
              if (workplaceMode && OpenCms.getRoleManager().hasRole(cms, CmsRole.VFS_MANAGER)) {
                  if (!siteroots.contains("/")) {
                      // add the root site if the user is in the workplace and has the required role
                      siteroots.add("/");
                  }
                  if (!siteroots.contains(CmsFileUtil.addTrailingSeparator(storedSiteRoot))) {
                      siteroots.add(CmsFileUtil.addTrailingSeparator(storedSiteRoot));
                  }
              }
              // add the shared site
              String shared = OpenCms.getSiteManager().getSharedFolder();
              if (showShared && (shared != null) && !siteroots.contains(shared)) {
                  siteroots.add(shared);
              }
              // all sites are compatible for root admins in the root OU, skip unnecessary tests
              boolean allCompatible = OpenCms.getRoleManager().hasRole(cms, CmsRole.ROOT_ADMIN)
                  && (ouFqn.isEmpty() || ouFqn.equals(CmsOrganizationalUnit.SEPARATOR));
              List<CmsResource> resources = Collections.emptyList();
              if (!allCompatible) {
                  try {
                      resources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ouFqn);
                  } catch (CmsException e) {
                      return Collections.emptyList();
                  }
              }
              Collections.sort(siteroots); // sort by resource name
              Iterator<String> roots = siteroots.iterator();
              while (roots.hasNext()) {
                  String folder = roots.next();
                  boolean compatible = allCompatible;
                  if (!compatible) {
                      Iterator<CmsResource> itResources = resources.iterator();
                      while (itResources.hasNext()) {
                          CmsResource resource = itResources.next();
                          if (resource.getRootPath().startsWith(folder) || folder.startsWith(resource.getRootPath())) {
                              compatible = true;
                              break;
                          }
                      }
                  }
                  // select only sites compatibles to the given organizational unit
                  if (compatible) {
                      try {
                          CmsResource res = cms.readResource(folder);
                          if (!workplaceMode
                              || cms.hasPermissions(
                                  res,
                                  CmsPermissionSet.ACCESS_VIEW,
                                  false,
                                  CmsResourceFilter.ONLY_VISIBLE)) {
  
                              // get the title and the position from the system configuration first
                              CmsSite configuredSite = m_siteRootSites.get(CmsFileUtil.removeTrailingSeparator(folder));
  
                              // get the title
                              String title = null;
                              if ((configuredSite != null)
                                  && CmsStringUtil.isNotEmptyOrWhitespaceOnly(configuredSite.getTitle())) {
                                  title = configuredSite.getTitle();
                              }
                              if (title == null) {
                                  title = getSiteTitle(cms, res);
                              }
  
                              // get the position
                              String position = null;
                              if ((configuredSite != null) && (configuredSite.getPosition() != Float.MAX_VALUE)) {
                                  position = Float.toString(configuredSite.getPosition());
                              }
                              if (position == null) {
                                  // not found, use the 'NavPos' property
                                  position = cms.readPropertyObject(
                                      res,
                                      CmsPropertyDefinition.PROPERTY_NAVPOS,
                                      false).getValue();
                              }
                              if (configuredSite != null) {
                                  float pos = Float.MAX_VALUE;
                                  try {
                                      pos = Float.parseFloat(position);
                                  } catch (Throwable e) {
                                      // m_position will have Float.MAX_VALUE, so this site will appear last
                                  }
                                  CmsSite clone = configuredSite.clone();
                                  clone.setPosition(pos);
                                  clone.setTitle(title);
                                  if (filterMode == null) {
                                      result.add(clone);
                                  } else {
                                      if (filterMode.equals(clone.getSSLMode())) {
                                          result.add(clone);
                                      }
                                  }
                              } else {
                                  // add the site to the result
  
                                  result.add(
                                      new CmsSite(
                                          folder,
                                          res.getStructureId(),
                                          title,
                                          siteServers.get(folder),
                                          position));
                              }
                          }
                      } catch (CmsException e) {
                          // user probably has no read access to the folder, ignore and continue iterating
                      }
                  }
              }
  
              // sort and ensure that the shared folder is the last element in the list
              Collections.sort(result, new Comparator<CmsSite>() {
  
                  public int compare(CmsSite o1, CmsSite o2) {
  
                      if (isSharedFolder(o1.getSiteRoot())) {
                          return +1;
                      }
                      if (isSharedFolder(o2.getSiteRoot())) {
                          return -1;
                      }
                      return o1.compareTo(o2);
                  }
              });
          } catch (Throwable t) {
              LOG.error(Messages.get().getBundle().key(Messages.LOG_READ_SITE_PROP_FAILED_0), t);
          } finally {
              // restore the user's current context
              cms.getRequestContext().setSiteRoot(storedSiteRoot);
          }
          return result;
  
      }