public static void main(String[] args) throws Exception {

    String propertyFile = null;

    // create the command line parser
    CommandLineParser parser = new PosixParser();
    Options options = new Options();
    options.addOption("f", "file", true, "The properties file");
    options.addOption("v", "verbose", false, "Verbose logging output");
    options.addOption("h", "help", false, "Help output");

    try {
      CommandLine line = parser.parse(options, args);

      if (line.hasOption('v')) {
        org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.DEBUG);
      }

      if (line.hasOption('h')) {
        usage(options);
      }

      if (line.hasOption('f')) {
        propertyFile = line.getOptionValue('f');
      } else {
        throw new Exception("Please supply -f");
      }

    } catch (Exception e) {
      log.error("Invalid command line: " + e, e);
      usage(options);
    }

    Properties props = new Properties();
    props.load(new FileReader(propertyFile));
    startFromProperties(props);

    Runtime.getRuntime()
        .addShutdownHook(
            new Thread(
                new Runnable() {
                  @Override
                  public void run() {
                    log.info("Received shutdown signal. Shutting down...");
                    server.stop(3);
                  }
                }));
  }
  public static HttpServer startFromProperties(Properties props) throws Exception {
    org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.DEBUG);
    int port = Integer.parseInt(props.getProperty("config.port", "8080"));

    startHttpServer(port);

    Set<String> snaaNames = parseCSV(props.getProperty("config.snaas", ""));

    // set optional proxy for shibboleth
    ShibbolethProxy shibbolethProxy;
    shibbolethProxy = setOptionalShibbolethProxy(props);

    String type, urnprefix, path;
    for (String snaaName : snaaNames) {

      type = props.getProperty(snaaName + ".type", "");
      path = props.getProperty(snaaName + ".path", "/snaa/" + snaaName);

      if ("dummy".equals(type)) {

        urnprefix = props.getProperty(snaaName + ".urnprefix", "urn:default:" + snaaName);
        startDummySNAA(path, urnprefix);

      } else if ("shibboleth".equals(type)) {

        urnprefix = props.getProperty(snaaName + ".urnprefix", "urn:default:" + snaaName);

        String authorizationClassName =
            props.getProperty(
                snaaName + ".authorization_class",
                "eu.wisebed.testbed.api.snaa.authorization.AlwaysAllowAuthorization");

        IUserAuthorization authorization = getAuthorizationModule(authorizationClassName);

        if (authorizationClassName.endsWith(".AttributeBasedAuthorization")) {
          createAndSetAuthenticationAttributes(snaaName, props, authorization);
        }

        String secretAuthkeyUrl = props.getProperty(snaaName + ".authorization.url");

        startShibbolethSNAA(
            path, urnprefix, secretAuthkeyUrl, authorization, shibbolethInjector, shibbolethProxy);

      } else if ("jaas".equals(type)) {

        urnprefix = props.getProperty(snaaName + ".urnprefix", "urn:default:" + snaaName);
        String jaasModuleName = props.getProperty(snaaName + ".module", null);
        String jaasConfigFile = props.getProperty(snaaName + ".configfile", null);
        String authorizationClassName =
            props.getProperty(
                snaaName + ".authorization_class",
                "eu.wisebed.testbed.api.snaa.authorization.AlwaysAllowAuthorization");

        IUserAuthorization authorization = getAuthorizationModule(authorizationClassName);

        if (authorizationClassName.endsWith(".AttributeBasedAuthorization")) {
          createAndSetAuthenticationAttributes(snaaName, props, authorization);
        }

        if (jaasConfigFile == null) {
          throw new Exception(("Supply a value for " + snaaName + ".configfile"));
        }

        if (jaasModuleName == null) {
          throw new Exception(("Supply a value for " + snaaName + ".module"));
        }

        startJAASSNAA(
            path,
            urnprefix,
            jaasModuleName,
            jaasConfigFile,
            getAuthorizationModule(authorizationClassName));

      } else if ("wisebed-federator".equals(type) || "federator".equals(type)) {
        FederatorType fedType = FederatorType.GENERIC;
        String secretAuthkeyUrl = null;

        if ("wisebed-federator".equals(type)) {
          fedType = FederatorType.WISEBED;
          secretAuthkeyUrl = props.getProperty(snaaName + ".authentication.url");
        }

        // endpoint url -> set<urnprefix>
        Map<String, Set<String>> federatedUrnPrefixes = new HashMap<String, Set<String>>();

        Set<String> federates = parseCSV(props.getProperty(snaaName + ".federates", ""));
        for (String federatedName : federates) {

          Set<String> urnPrefixes =
              parseCSV(props.getProperty(snaaName + "." + federatedName + ".urnprefixes"));
          String endpointUrl = props.getProperty(snaaName + "." + federatedName + ".endpointurl");

          federatedUrnPrefixes.put(endpointUrl, urnPrefixes);
        }

        startFederator(
            fedType,
            path,
            secretAuthkeyUrl,
            shibbolethInjector,
            shibbolethProxy,
            federatedUrnPrefixes);

      } else {
        log.error("Found unknown type " + type + " for snaa name " + snaaName + ". Ignoring...");
      }
    }

    return server;
  }