docs: public RunRemoteProcessMessageData setupUserProperties(Map<String, Object> properties)
      {
          try {
              Record recUser = this.getMainRecord();
              
              String processClassName = (String)properties.get(RunRemoteProcessMessageData.PROCESS_CLASS_NAME);
              
              // Step 1 - Get the web site prefix
              String sitePrefix = (String)properties.get(MenusMessageData.SITE_PREFIX);
              String fullSitePrefix = sitePrefix;
              String strDomain = (String)properties.get(DBParams.DOMAIN);
              if (strDomain == null)
              {
                  strDomain = this.getProperty(DBParams.DOMAIN);
                  if ((strDomain == null) || (strDomain.length() == 0))
                      strDomain = DEFAULT_DOMAIN;
                  if (strDomain.indexOf('.') != strDomain.lastIndexOf('.'))
                      strDomain = strDomain.substring(strDomain.indexOf('.') + 1);
              }
              String homeMenu = (String)properties.get(MenusMessageData.SITE_HOME_MENU);
          
              // Next, Create a main site menu for this new domain.
              Record recMenus = this.getRecord(Menus.MENUS_FILE);
              recMenus.addNew();
              String siteTemplate = (String)properties.get(SITE_TEMPLATE_CODE_PARAM);
              recMenus.getField(Menus.CODE).setString(siteTemplate);
              int iOldOrder = recMenus.getDefaultOrder();
              recMenus.setKeyArea(Menus.CODE_KEY);
              BaseBuffer buffer = null;
              if (recMenus.seek(null))
              {
                  buffer = new VectorBuffer(null);
                  buffer.fieldsToBuffer(recMenus);
              }
              else
                  return null;        // Error - Site template does not exist
              recMenus.setKeyArea(iOldOrder);
              
              recMenus.addNew();
              if (buffer != null)     // Always
                  buffer.bufferToFields(recMenus, DBConstants.DISPLAY, DBConstants.INIT_MOVE);
              
              recMenus.getField(Menus.SEQUENCE).setValue(100);
              String siteNameTemplate = (String)properties.get(SITE_NAME_TEMPLATE_PARAM);
              if (siteNameTemplate == null)
                  siteNameTemplate = "{0}''s Demo site";
              String siteName = MessageFormat.format(siteNameTemplate, sitePrefix.toUpperCase().substring(0,1) + sitePrefix.substring(1));
              recMenus.getField(Menus.NAME).setString(siteName);
              ((PropertiesField)recMenus.getField(Menus.PARAMS)).setProperty(MAIN_USER_PARAM, recUser.getField(UserInfo.USER_NAME).toString());
              String templateArchivePath = ((PropertiesField)recMenus.getField(Menus.PARAMS)).getProperty(DBConstants.USER_ARCHIVE_FOLDER);
              if ((templateArchivePath == null) || (templateArchivePath.length() == 0))
                  templateArchivePath = Utility.addToPath(DEFAULT_ARCHIVE_FOLDER, CURRENT_TEST_DATA_DIR);
              
              int iErrorCode = DBConstants.DUPLICATE_KEY;
              int iCounter = 0;
              while (iErrorCode == DBConstants.DUPLICATE_KEY)
              {
                  try {
                      fullSitePrefix = sitePrefix;
                      if (iCounter > 0)
                          fullSitePrefix += Integer.toString(iCounter);
          
                      recMenus.getField(Menus.CODE).setString(fullSitePrefix + '.' + strDomain);
          
                      recMenus.add();
                      iErrorCode = DBConstants.NORMAL_RETURN;
                  } catch (DBException ex) {
                      iErrorCode = ex.getErrorCode();
                      if (iErrorCode != DBConstants.DUPLICATE_KEY)
                      {
                          ex.printStackTrace();
                          return null;     // Error
                      }
                      iCounter++;
                      if (iCounter >= 100)
                          break;
                  }
              }
              // Now we have this user's domain: sitePrefix
              
              // Update the user's account to show they own this new domain
              if (iErrorCode == DBConstants.NORMAL_RETURN)
              {
                  iOldOrder = recUser.getDefaultOrder();
                  recUser.setKeyArea(UserInfo.ID_KEY);
                  recUser.edit();
                  ((PropertiesField)recUser.getField(UserInfo.PROPERTIES)).setProperty(MenusMessageData.DOMAIN_NAME, recMenus.getField(Menus.CODE).toString());
                  ((PropertiesField)recUser.getField(UserInfo.PROPERTIES)).setProperty(DBParams.HOME, homeMenu);
                  recUser.set();
                  recUser.setKeyArea(iOldOrder);
              }
              
              TreeMessage message = new TreeMessage(null, null);
              RunRemoteProcessMessageData runRemoteProcessRequest = new RunRemoteProcessMessageData(message, null);
          
              CreateSiteMessageData createSiteRequest = new CreateSiteMessageData(runRemoteProcessRequest, null);
              runRemoteProcessRequest.addMessageDataDesc(createSiteRequest);
              MessageRecordDesc userInfoMessageData = (MessageRecordDesc)createSiteRequest.getMessageDataDesc(UserInfo.USER_INFO_FILE);
              MessageRecordDesc menusMessageData = (MessageRecordDesc)createSiteRequest.getMessageDataDesc(Menus.MENUS_FILE);
              
              String user = this.getProperty(DBParams.USER_NAME);
              String auth = this.getProperty(DBParams.AUTH_TOKEN);
              runRemoteProcessRequest.put(RunRemoteProcessMessageData.PROCESS_CLASS_NAME, processClassName);
              runRemoteProcessRequest.put(DBParams.USER_NAME, user);
              runRemoteProcessRequest.put(DBParams.AUTH_TOKEN, auth);
              
              userInfoMessageData.putRawRecordData(recUser);  // User, password
          
              menusMessageData.put(MenusMessageData.DOMAIN_NAME, fullSitePrefix + '.' + strDomain);
              menusMessageData.put(MenusMessageData.SITE_PREFIX, fullSitePrefix);
              menusMessageData.put(MenusMessageData.SITE_NAME, siteName);
              menusMessageData.put(MenusMessageData.XSL_TEMPLATE_PATH, templateArchivePath);
              menusMessageData.put(MenusMessageData.SITE_TEMPLATE_MENU, siteTemplate);
              menusMessageData.put(MenusMessageData.SITE_HOME_MENU, homeMenu);
          
              return runRemoteProcessRequest;
              
          } catch (DBException ex) {
              return null;
          }
      }