public HybridUserProvider() {

    // Migrate user provider properties
    JiveGlobals.migrateProperty("hybridUserProvider.primaryProvider.className");
    JiveGlobals.migrateProperty("hybridUserProvider.secondaryProvider.className");
    JiveGlobals.migrateProperty("hybridUserProvider.tertiaryProvider.className");

    userproviders = new ArrayList<UserProvider>();

    // Load primary, secondary, and tertiary user providers.
    String primaryClass = JiveGlobals.getProperty("hybridUserProvider.primaryProvider.className");
    if (primaryClass == null) {
      Log.error(
          "A primary UserProvider must be specified via openfire.xml or the system properties");
      return;
    }
    try {
      Class c = ClassUtils.forName(primaryClass);
      UserProvider primaryProvider = (UserProvider) c.newInstance();
      userproviders.add(primaryProvider);
      Log.debug("Primary user provider: " + primaryClass);
    } catch (Exception e) {
      Log.error(
          "Unable to load primary user provider: "
              + primaryClass
              + ". Users in this provider will be disabled.",
          e);
      return;
    }
    String secondaryClass =
        JiveGlobals.getProperty("hybridUserProvider.secondaryProvider.className");
    if (secondaryClass != null) {
      try {
        Class c = ClassUtils.forName(secondaryClass);
        UserProvider secondaryProvider = (UserProvider) c.newInstance();
        userproviders.add(secondaryProvider);
        Log.debug("Secondary user provider: " + secondaryClass);
      } catch (Exception e) {
        Log.error("Unable to load secondary user provider: " + secondaryClass, e);
      }
    }
    String tertiaryClass = JiveGlobals.getProperty("hybridUserProvider.tertiaryProvider.className");
    if (tertiaryClass != null) {
      try {
        Class c = ClassUtils.forName(tertiaryClass);
        UserProvider tertiaryProvider = (UserProvider) c.newInstance();
        userproviders.add(tertiaryProvider);
        Log.debug("Tertiary user provider: " + tertiaryClass);
      } catch (Exception e) {
        Log.error("Unable to load tertiary user provider: " + tertiaryClass, e);
      }
    }
  }
  /** Loads the provider names from the jive properties config file. */
  private static void loadProviders() {
    if (factory == null) {
      // Use className as a convenient object to get a lock on.
      synchronized (classNames) {
        if (factory == null) {
          try {
            Class[] providers = new Class[classNames.length];
            for (int i = 0; i < classNames.length; i++) {
              // Convert XML based provider setup to Database based
              JiveGlobals.migrateProperty(propNames[i]);

              String className = classNames[i];
              // See if the classname has been set as a Jive property.
              String classNameProp = JiveGlobals.getProperty(propNames[i]);
              if (classNameProp != null) {
                className = classNameProp;
              }
              try {
                providers[i] = ClassUtils.forName(className);
              } catch (Exception e) {
                Log.error("Exception loading class: " + className, e);
              }
            }
            setProviders(providers);
          } catch (Exception e) {
            Log.error("Exception loading class: " + classNames, e);
          }
        }
      }
    }
  }
  public NativeAuthProvider() {
    // Convert XML based provider setup to Database based
    JiveGlobals.migrateProperty("nativeAuth.domain");

    this.domain = JiveGlobals.getProperty("nativeAuth.domain");

    // Configure the library path so that we can load the shaj native library
    // from the Openfire lib directory.
    // Find the root path of this class.
    try {
      String binaryPath =
          (new URL(Shaj.class.getProtectionDomain().getCodeSource().getLocation(), "."))
              .openConnection()
              .getPermission()
              .getName();
      binaryPath = (new File(binaryPath)).getCanonicalPath();

      // Add the binary path to "java.library.path".
      String newLibPath = binaryPath + File.pathSeparator + System.getProperty("java.library.path");
      System.setProperty("java.library.path", newLibPath);
      Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
      fieldSysPath.setAccessible(true);
      fieldSysPath.set(System.class.getClassLoader(), null);
    } catch (Exception e) {
      Log.error(e);
    }

    // Configure Shaj to log output to the Openfire logger.
    com.cenqua.shaj.log.Log.Factory.setInstance(
        new com.cenqua.shaj.log.Log() {
          public boolean isDebug() {
            return Log.isDebugEnabled();
          }

          public void error(String string) {
            Log.error(string);
          }

          public void error(String string, Throwable throwable) {
            Log.error(string, throwable);
          }

          public void debug(String string) {
            Log.debug("NativeAuthProvider: " + string);
          }
        });
  }
  /**
   * Initializes the server's security audit provider, based on configuration and defaults to
   * DefaultSecurityAuditProvider if the specified provider is not valid or not specified.
   */
  private void initProvider() {
    // Convert XML based provider setup to Database based
    JiveGlobals.migrateProperty("provider.securityAudit.className");

    String className =
        JiveGlobals.getProperty(
            "provider.securityAudit.className",
            "org.jivesoftware.openfire.security.DefaultSecurityAuditProvider");
    // Check if we need to reset the provider class
    if (provider == null || !className.equals(provider.getClass().getName())) {
      try {
        Class c = ClassUtils.forName(className);
        provider = (SecurityAuditProvider) c.newInstance();
      } catch (Exception e) {
        Log.error("Error loading security audit provider: " + className, e);
        provider = new DefaultSecurityAuditProvider();
      }
    }
  }
  private void init() {
    // Register the trust manager to use when using HTTPS
    Protocol easyhttps =
        new Protocol("https", (ProtocolSocketFactory) new SSLProtocolSocketFactory(this), 443);
    Protocol.registerProtocol("https", easyhttps);

    // Convert XML based provider setup to Database based
    JiveGlobals.migrateProperty("clearspace.uri");
    JiveGlobals.migrateProperty("clearspace.sharedSecret");

    // Make sure that all Clearspace components are set up, unless they were overridden
    // Note that the auth provider is our way of knowing that we are set up with Clearspace,
    // so don't bother checking to set it.
    if (isEnabled()) {
      if (JiveGlobals.getProperty("provider.user.className") == null) {
        JiveGlobals.setProperty(
            "provider.user.className",
            "org.jivesoftware.openfire.clearspace.ClearspaceUserProvider");
      }
      if (JiveGlobals.getProperty("provider.group.className") == null) {
        JiveGlobals.setProperty(
            "provider.group.className",
            "org.jivesoftware.openfire.clearspace.ClearspaceGroupProvider");
      }
      if (JiveGlobals.getProperty("provider.vcard.className") == null) {
        JiveGlobals.setProperty(
            "provider.vcard.className",
            "org.jivesoftware.openfire.clearspace.ClearspaceVCardProvider");
      }
      if (JiveGlobals.getProperty("provider.lockout.className") == null) {
        JiveGlobals.setProperty(
            "provider.lockout.className",
            "org.jivesoftware.openfire.clearspace.ClearspaceLockOutProvider");
      }
      if (JiveGlobals.getProperty("provider.securityAudit.className") == null) {
        JiveGlobals.setProperty(
            "provider.securityAudit.className",
            "org.jivesoftware.openfire.clearspace.ClearspaceSecurityAuditProvider");
      }
      if (JiveGlobals.getProperty("provider.admin.className") == null) {
        JiveGlobals.setProperty(
            "provider.admin.className",
            "org.jivesoftware.openfire.clearspace.ClearspaceAdminProvider");
      }
    }

    this.uri = properties.get("clearspace.uri");
    if (uri != null) {
      if (!this.uri.endsWith("/")) {
        this.uri = this.uri + "/";
      }
      // Updates the host/port attributes based on the uri
      updateHostPort();
    }
    sharedSecret = properties.get("clearspace.sharedSecret");

    // Creates the cache maps
    userIDCache = new DefaultCache<String, Long>("clearspace.userid", 1000, JiveConstants.DAY);
    groupIDCache = new DefaultCache<String, Long>("clearspace.groupid", 1000, JiveConstants.DAY);
    usernameCache = new DefaultCache<Long, String>("clearspace.username", 1000, JiveConstants.DAY);

    if (Log.isDebugEnabled()) {
      StringBuilder buf = new StringBuilder();
      buf.append("Created new ClearspaceManager() instance, fields:\n");
      buf.append("\t URI: ").append(uri).append("\n");
      buf.append("\t sharedSecret: ").append(sharedSecret).append("\n");

      Log.debug("ClearspaceManager: " + buf.toString());
    }

    // Init nonce cache
    nonceCache = CacheFactory.createCache("Clearspace SSO Nonce");
    // Init nonce generator
    nonceGenerator = new Random();
  }