docs: public void addSite(
          String server,
          String uri,
          String title,
          String position,
          String errorPage,
          String webserver,
          String sslMode,
          String secureServer,
          String exclusive,
          String error,
          String usePermanentRedirects)
      throws CmsConfigurationException {
  
          if (m_frozen) {
              throw new CmsRuntimeException(Messages.get().container(Messages.ERR_CONFIG_FROZEN_0));
          }
  
          if (getSiteRoots().contains(uri)) {
              throw new CmsRuntimeException(Messages.get().container(Messages.ERR_SITE_ALREADY_CONFIGURED_1, uri));
          }
  
          if (CmsStringUtil.isEmptyOrWhitespaceOnly(server)) {
              throw new CmsRuntimeException(Messages.get().container(Messages.ERR_EMPTY_SERVER_URL_0));
          }
  
          // create a new site object
          CmsSiteMatcher matcher = new CmsSiteMatcher(server);
          CmsSite site = new CmsSite(uri, matcher);
          // set the title
          site.setTitle(title);
          // set the position
          if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(position)) {
              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
              }
              site.setPosition(pos);
          }
          // set the error page
          site.setErrorPage(errorPage);
          site.setWebserver(Boolean.valueOf(webserver).booleanValue());
          site.setSSLMode(CmsSSLMode.getModeFromXML(sslMode));
          if (CmsStringUtil.isNotEmpty(secureServer)) {
              matcher = new CmsSiteMatcher(secureServer);
              site.setSecureServer(matcher);
              site.setExclusiveUrl(Boolean.valueOf(exclusive).booleanValue());
              site.setExclusiveError(Boolean.valueOf(error).booleanValue());
              site.setUsePermanentRedirects(Boolean.valueOf(usePermanentRedirects).booleanValue());
          }
  
          // note that Digester first calls the addAliasToConfigSite method.
          // therefore, the aliases are already set
          site.setAliases(m_aliases);
  
          boolean valid = true;
          List<CmsSiteMatcher> toAdd = new ArrayList<CmsSiteMatcher>();
          for (CmsSiteMatcher matcherToAdd : site.getAllMatchers()) {
              valid = valid & isServerValid(matcherToAdd) & !toAdd.contains(matcherToAdd);
              toAdd.add(matcherToAdd);
          }
  
          if (!valid) {
              throw new CmsConfigurationException(
                  Messages.get().container(Messages.ERR_DUPLICATE_SERVER_NAME_1, matcher.getUrl()));
          }
  
          for (CmsSiteMatcher matcherToAdd : site.getAllMatchers()) {
              addServer(matcherToAdd, site);
          }
  
          m_aliases = new ArrayList<CmsSiteMatcher>();
          site.setParameters(m_siteParams);
          m_siteParams = new TreeMap<String, String>();
          m_siteRootSites = new HashMap<String, CmsSite>(m_siteRootSites);
          m_siteRootSites.put(site.getSiteRoot(), site);
          if (CmsLog.INIT.isInfoEnabled()) {
              CmsLog.INIT.info(Messages.get().getBundle().key(Messages.INIT_SITE_ROOT_ADDED_1, site.toString()));
          }
      }