protected static void setupTls() {
    // Note that the settings below are conditional, so you can
    // override then with "java -Djavax...=Y... ConnectorServerAgent..."
    // It's definitely not safe to use -D to set passwords, though,
    // but it's useful for prototyping.

    String keyStore = spaceWideRegistry.getTlosSWConfigInfo().getJmxParams().getKeyStore();
    String trustStore = spaceWideRegistry.getTlosSWConfigInfo().getJmxParams().getTrustStore();
    String password = spaceWideRegistry.getTlosSWConfigInfo().getJmxParams().getPassword();

    if (System.getProperty("javax.net.ssl.trustStore") == null)
      System.setProperty("javax.net.ssl.trustStore", keyStore);
    if (System.getProperty("javax.net.ssl.keyStorePassword") == null)
      System.setProperty("javax.net.ssl.keyStorePassword", password);
    if (System.getProperty("javax.net.ssl.keyStore") == null)
      System.setProperty("javax.net.ssl.keyStore", trustStore);

    /*
     * The method above is the simplest (IMO therefore the best) method if
     * your application doesn't use certs for any other purpose. You should
     * use the instance-based TLS configuration method if your app uses
     * certs for any other purpose (i.e., it could fetch web pages over
     * https, or be a TLS Soap client, etc., or it could run multiple TLS
     * JMXConnectorServers).
     *
     * The instance-based method allocates a SSLSocketFactory based on the
     * SSLContext instance which you instantiate and configure, so you can
     * configure multiple SSLSocketFactories with different SSLContext
     * instances. This all applies to any standard JSSE TLS application, but
     * for JMX, you associate the allocated SSLSocketFactory to the
     * Connector with:
     *
     * env.put("jmx.remote.tls.socket.factory", yourFactory);
     */

    env.put("jmx.remote.profiles", "TLS");
    // env.put("jmx.remote.tls.enabled.protocols", "TLSv1");
    // env.put("jmx.remote.tls.enabled.cipher.suites",
    // "SSL_RSA_WITH_NULL_MD5");
    // Most users will probably want to use the default TLS
    // protocols and suites.
    env.put("jmx.remote.tls.need.client.authentication", Boolean.toString(isRequireClientAuth()));
    // Comment out the line above if you don't want to require
    // clients to have their own certs.

    // if ((new File("access.properties")).isFile())
    // env.put("jmx.remote.x.access.file", "access.properties");
    // IF file "access.properties" is present in $PWD (from where server
    // is started), it must have keys of permitted client cert subjects,
    // and values of "readwrite" or "readonly".
    // N.b. You MUST ESCAPE all spaces, colons, and equal signes in the
    // subject with backslashes!
    // Example record:
    // CN\=proto\ client\ 1,OU\=RND,O\=Fake\ Corp.,C\=US readwrite
  }
public class JMXTLSServer {

  private static MBeanServer mbeanServer;
  private static JMXConnectorServer jConnectorServer;
  private static Map<String, String> env = new HashMap<String, String>();

  private static SpaceWideRegistry spaceWideRegistry = SpaceWideRegistry.getInstance();

  private static Logger logger = SpaceWideRegistry.getGlobalLogger();

  /**
   * This function is designed for descrete testing procedures. DO NOT USE for server functionality.
   *
   * @author Serkan Taş 12.09.2012
   * @param spaceWideRegistry
   */
  public static void initialize(SpaceWideRegistry spaceWideRegistry) {
    JMXTLSServer.spaceWideRegistry = spaceWideRegistry;
    // initialize();
  }

  public static void initialize(String MBeanArray[], String MBeanTypeArray[]) {

    try {
      setupTls();

      logger.info("");
      logger.info("############# MBean Server ##################");

      logger.info("Create the MBean server...");
      mbeanServer = MBeanServerFactory.createMBeanServer();

      logger.info("Created !");

      for (int i = 0; i < MBeanArray.length; i++) {
        ObjectName mbeanName = new ObjectName("MBeans:type=" + MBeanTypeArray[i]);
        logger.info(MBeanArray[i] + " MBean is created ...");
        mbeanServer.createMBean(
            JMXServer.class.getPackage().getName() + ".beans." + MBeanArray[i],
            mbeanName,
            null,
            null);
      }

      logger.info(ResourceMapper.SECTION_DIVISON_KARE);
      logger.info("");
      logger.info("######### JMXMP-TLS Connector Server ############");
      logger.info("");

      // Create a JMXMP-TLS connector server
      //
      logger.info("Create a JMXMP-TLS connector server... > ");

      // hardcoded ip : localhost port : 5555
      int port =
          TlosSpaceWide.getSpaceWideRegistry()
              .getTlosSWConfigInfo()
              .getJmxParams()
              .getJmxTlsPort()
              .getPortNumber();
      if (port <= 0) {
        port = 5555;
      }

      logger.info("Using port number : " + port);

      String ipAddress =
          TlosSpaceWide.getSpaceWideRegistry().getServerConfig().getServerParams().getIpAddress();
      if (ipAddress == null || ipAddress.equals("")) {
        ipAddress = null;
      }

      logger.info("Using ip address : " + ipAddress);

      JMXServiceURL url = new JMXServiceURL("jmxmp", ipAddress, port);
      jConnectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbeanServer);

      logger.info("Created !");

      // Start the JMXMP-TLS connector server
      //
      logger.info("Start the JMXMP-TLS connector server... > ");
      jConnectorServer.start();

      logger.info("Started !");
      logger.info("Waiting for incoming connections...");
      logger.info("#############################################");
      logger.info("");

      String jmxUserName =
          "" + new Random(new Long(Calendar.getInstance().getTimeInMillis())).nextLong();
      Thread.sleep(10);
      String jmxPassWord =
          "" + new Random(new Long(Calendar.getInstance().getTimeInMillis())).nextLong();

      JmxUser jmxUser = new JmxUser();
      jmxUser.setJmxClientAuthanticationId(jmxUserName);
      jmxUser.setJmxClientAuthanticationKey(jmxPassWord);

      TlosSpaceWide.getSpaceWideRegistry().setJmxUser(jmxUser);

    } catch (MalformedURLException mue) {
      logger.error("### MalformedURLException ###");
      mue.printStackTrace();
      try {
        jConnectorServer.stop();
      } catch (IOException e) {
        e.printStackTrace();
      }
    } catch (SecurityException e) {
      // System.out.println(" ### SecurityException ### ");
      logger.error("### SecurityException ###");
      e.printStackTrace();
      System.exit(-1);
    } catch (BindException e) {
      // System.out.println(" ### BindException ### ");
      logger.error("### BindException ###");
      e.printStackTrace();
      System.exit(-1);
    } catch (Exception e) {
      // System.out.println(" ### Unclassified Error ### ");
      logger.error("### Unclassified Error ###");
      e.printStackTrace();
      System.exit(-1);
    }
  }

  public static void disconnect() {
    try {

      logger.info("Closing jmx server...");

      String[] connIdList = jConnectorServer.getConnectionIds();

      logger.info("Current active JMXMP-TLS client count : " + connIdList.length);
      logger.info("Waiting for the connections to be closed...");

      int counter = 0;

      while (true) {
        if (jConnectorServer.getConnectionIds().length == 0 || counter++ == 20) {
          break;
        }
        try {
          Thread.sleep(1000);
          System.out.print(".");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }

      if (counter == 20) {
        logger.info("Client(s) are not disconnected, terminated by server !");
      } else {
        logger.info("Client(s) disconnected !");
      }

      jConnectorServer.stop();

      logger.info("Closed !");
      logger.info("Releasing MBean Server...");

      MBeanServerFactory.releaseMBeanServer(mbeanServer);

      logger.info("Released !");

    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public static boolean authorizeAgent(JmxAgentUser jmxAgentUser) {

    SWAgent clientSideSwAgent = XmlUtils.convertToSwAgent(jmxAgentUser.getSwAgentXML());

    SWAgent serverSideSwAgent =
        TlosSpaceWide.getSpaceWideRegistry()
            .getAgentManagerReference()
            .getSwAgentsCache()
            .get(jmxAgentUser.getAgentId() + "");

    if (serverSideSwAgent == null
        || !clientSideSwAgent.getJmxUser().equals(serverSideSwAgent.getJmxUser())
        || !clientSideSwAgent.getJmxPassword().equals(serverSideSwAgent.getJmxPassword())) {
      return false;
    }
    return true;
  }

  public static boolean authorizeWeb(JmxUser jmxUser) {

    if (jmxUser == null) {
      logger.error("jmxUser is null !");
      return false;
    }

    String clientAuthanticationId =
        TlosSpaceWide.getSpaceWideRegistry().getJmxUser().getJmxClientAuthanticationId();
    String jmxClientAuthanticationKey =
        TlosSpaceWide.getSpaceWideRegistry().getJmxUser().getJmxClientAuthanticationKey();

    if (!clientAuthanticationId.equals(jmxUser.getJmxClientAuthanticationId())
        || !jmxClientAuthanticationKey.equals(jmxUser.getJmxClientAuthanticationKey())) {
      // return false;
    }
    return true;
  }

  protected static void setupTls() {
    // Note that the settings below are conditional, so you can
    // override then with "java -Djavax...=Y... ConnectorServerAgent..."
    // It's definitely not safe to use -D to set passwords, though,
    // but it's useful for prototyping.

    String keyStore = spaceWideRegistry.getTlosSWConfigInfo().getJmxParams().getKeyStore();
    String trustStore = spaceWideRegistry.getTlosSWConfigInfo().getJmxParams().getTrustStore();
    String password = spaceWideRegistry.getTlosSWConfigInfo().getJmxParams().getPassword();

    if (System.getProperty("javax.net.ssl.trustStore") == null)
      System.setProperty("javax.net.ssl.trustStore", keyStore);
    if (System.getProperty("javax.net.ssl.keyStorePassword") == null)
      System.setProperty("javax.net.ssl.keyStorePassword", password);
    if (System.getProperty("javax.net.ssl.keyStore") == null)
      System.setProperty("javax.net.ssl.keyStore", trustStore);

    /*
     * The method above is the simplest (IMO therefore the best) method if
     * your application doesn't use certs for any other purpose. You should
     * use the instance-based TLS configuration method if your app uses
     * certs for any other purpose (i.e., it could fetch web pages over
     * https, or be a TLS Soap client, etc., or it could run multiple TLS
     * JMXConnectorServers).
     *
     * The instance-based method allocates a SSLSocketFactory based on the
     * SSLContext instance which you instantiate and configure, so you can
     * configure multiple SSLSocketFactories with different SSLContext
     * instances. This all applies to any standard JSSE TLS application, but
     * for JMX, you associate the allocated SSLSocketFactory to the
     * Connector with:
     *
     * env.put("jmx.remote.tls.socket.factory", yourFactory);
     */

    env.put("jmx.remote.profiles", "TLS");
    // env.put("jmx.remote.tls.enabled.protocols", "TLSv1");
    // env.put("jmx.remote.tls.enabled.cipher.suites",
    // "SSL_RSA_WITH_NULL_MD5");
    // Most users will probably want to use the default TLS
    // protocols and suites.
    env.put("jmx.remote.tls.need.client.authentication", Boolean.toString(isRequireClientAuth()));
    // Comment out the line above if you don't want to require
    // clients to have their own certs.

    // if ((new File("access.properties")).isFile())
    // env.put("jmx.remote.x.access.file", "access.properties");
    // IF file "access.properties" is present in $PWD (from where server
    // is started), it must have keys of permitted client cert subjects,
    // and values of "readwrite" or "readonly".
    // N.b. You MUST ESCAPE all spaces, colons, and equal signes in the
    // subject with backslashes!
    // Example record:
    // CN\=proto\ client\ 1,OU\=RND,O\=Fake\ Corp.,C\=US readwrite
  }

  /**
   * Only used if running with TLS mode.
   *
   * <p>If you want to run TLS mode without Client certs, just override this class and override this
   * method to return false.
   *
   * @returns true (unless this method is overridden).
   */
  protected static boolean isRequireClientAuth() {
    return true;
  }
}