/** {@inheritDoc} */
  public SynapseConfiguration createSynapseConfiguration() {

    String synapseXMLLocation = serverConfigurationInformation.getSynapseXMLLocation();
    Properties properties = SynapsePropertiesLoader.loadSynapseProperties();
    if (serverConfigurationInformation.getResolveRoot() != null) {
      properties.put(
          SynapseConstants.RESOLVE_ROOT, serverConfigurationInformation.getResolveRoot());
    }

    if (serverConfigurationInformation.getSynapseHome() != null) {
      properties.put(
          SynapseConstants.SYNAPSE_HOME, serverConfigurationInformation.getSynapseHome());
    }

    if (synapseXMLLocation != null) {
      synapseConfiguration =
          SynapseConfigurationBuilder.getConfiguration(synapseXMLLocation, properties);
    } else {
      log.warn(
          "System property or init-parameter '"
              + SynapseConstants.SYNAPSE_XML
              + "' is not specified. Using default configuration..");
      synapseConfiguration = SynapseConfigurationBuilder.getDefaultConfiguration();
    }

    Enumeration keys = properties.keys();
    while (keys.hasMoreElements()) {
      String key = (String) keys.nextElement();
      synapseConfiguration.setProperty(key, properties.getProperty(key));
    }

    // Set the Axis2 ConfigurationContext to the SynapseConfiguration
    synapseConfiguration.setAxisConfiguration(configurationContext.getAxisConfiguration());
    MessageContextCreatorForAxis2.setSynConfig(synapseConfiguration);

    // set the Synapse configuration into the Axis2 configuration
    Parameter synapseConfigurationParameter =
        new Parameter(SynapseConstants.SYNAPSE_CONFIG, synapseConfiguration);
    try {
      configurationContext.getAxisConfiguration().addParameter(synapseConfigurationParameter);
    } catch (AxisFault e) {
      handleFatal(
          "Could not set parameters '"
              + SynapseConstants.SYNAPSE_CONFIG
              + "' to the Axis2 configuration : "
              + e.getMessage(),
          e);
    }

    addServerIPAndHostEntries();

    return synapseConfiguration;
  }
  /**
   * Create the file system for holding the synapse configuration for a new tanent.
   *
   * @param synapseConfigDir configuration directory where synapse configuration is created
   * @param tenantDomain name of the tenent
   */
  @SuppressWarnings({"ResultOfMethodCallIgnored"})
  private void createTenantSynapseConfigHierarchy(File synapseConfigDir, String tenantDomain) {

    if (!synapseConfigDir.mkdir()) {
      log.fatal(
          "Couldn't create the synapse-config root on the file system "
              + "for the tenant domain : "
              + tenantDomain);
      return;
    }

    File sequencesDir = new File(synapseConfigDir, MultiXMLConfigurationBuilder.SEQUENCES_DIR);
    File endpointsDir = new File(synapseConfigDir, MultiXMLConfigurationBuilder.ENDPOINTS_DIR);
    File entriesDir = new File(synapseConfigDir, MultiXMLConfigurationBuilder.LOCAL_ENTRY_DIR);
    File proxyServicesDir =
        new File(synapseConfigDir, MultiXMLConfigurationBuilder.PROXY_SERVICES_DIR);
    File eventSourcesDir = new File(synapseConfigDir, MultiXMLConfigurationBuilder.EVENTS_DIR);
    File tasksDir = new File(synapseConfigDir, MultiXMLConfigurationBuilder.TASKS_DIR);
    File executorsDir = new File(synapseConfigDir, MultiXMLConfigurationBuilder.EXECUTORS_DIR);

    if (!sequencesDir.mkdir()) {
      log.warn("Could not create " + sequencesDir);
    }
    if (!endpointsDir.mkdir()) {
      log.warn("Could not create " + endpointsDir);
    }
    if (!entriesDir.mkdir()) {
      log.warn("Could not create " + entriesDir);
    }
    if (!proxyServicesDir.mkdir()) {
      log.warn("Could not create " + proxyServicesDir);
    }
    if (!eventSourcesDir.mkdir()) {
      log.warn("Could not create " + eventSourcesDir);
    }
    if (!tasksDir.mkdir()) {
      log.warn("Could not create " + tasksDir);
    }
    if (!executorsDir.mkdir()) {
      log.warn("Could not create " + executorsDir);
    }

    SynapseConfiguration initialSynCfg = SynapseConfigurationBuilder.getDefaultConfiguration();
    SequenceMediator mainSequence = (SequenceMediator) initialSynCfg.getMainSequence();
    SequenceMediator faultSequence = (SequenceMediator) initialSynCfg.getFaultSequence();
    mainSequence.setFileName(SynapseConstants.MAIN_SEQUENCE_KEY + ".xml");
    faultSequence.setFileName(SynapseConstants.FAULT_SEQUENCE_KEY + ".xml");
    Registry registry = new WSO2Registry();
    initialSynCfg.setRegistry(registry);

    MultiXMLConfigurationSerializer serializer =
        new MultiXMLConfigurationSerializer(synapseConfigDir.getAbsolutePath());
    try {
      serializer.serializeSequence(mainSequence, initialSynCfg, null);
      serializer.serializeSequence(faultSequence, initialSynCfg, null);
      serializer.serializeSynapseRegistry(registry, initialSynCfg, null);
    } catch (Exception e) {
      handleException(
          "Couldn't serialise the initial synapse configuration "
              + "for the domain : "
              + tenantDomain,
          e);
    }
  }
  /**
   * Create the file system for holding the synapse configuration for a new tanent.
   *
   * @param synapseConfigDir configuration directory where synapse configuration is created
   * @param tenantDomain name of the tenent
   */
  @SuppressWarnings({"ResultOfMethodCallIgnored"})
  private void createTenantSynapseConfigHierarchy(File synapseConfigDir, String tenantDomain) {
    synapseConfigDir.mkdir();
    File sequencesDir = new File(synapseConfigDir, MultiXMLConfigurationBuilder.SEQUENCES_DIR);

    if (!sequencesDir.mkdir()) {
      log.warn("Could not create " + sequencesDir);
    }

    SynapseConfiguration initialSynCfg = SynapseConfigurationBuilder.getDefaultConfiguration();

    // SequenceMediator mainSequence = (SequenceMediator) initialSynCfg.getMainSequence();
    // SequenceMediator faultSequence = (SequenceMediator) initialSynCfg.getFaultSequence();
    InputStream in = null;
    StAXOMBuilder builder = null;
    SequenceMediatorFactory factory = new SequenceMediatorFactory();
    try {
      if (authFailureHandlerSequence == null) {
        in =
            FileUtils.openInputStream(
                new File(synapseConfigRootPath + authFailureHandlerSequenceName + ".xml"));
        builder = new StAXOMBuilder(in);
        authFailureHandlerSequence =
            (SequenceMediator)
                factory.createMediator(builder.getDocumentElement(), new Properties());
        authFailureHandlerSequence.setFileName(authFailureHandlerSequenceName + ".xml");
      }
      if (resourceMisMatchSequence == null) {
        in =
            FileUtils.openInputStream(
                new File(synapseConfigRootPath + resourceMisMatchSequenceName + ".xml"));
        builder = new StAXOMBuilder(in);
        resourceMisMatchSequence =
            (SequenceMediator)
                factory.createMediator(builder.getDocumentElement(), new Properties());
        resourceMisMatchSequence.setFileName(resourceMisMatchSequenceName + ".xml");
      }
      if (throttleOutSequence == null) {
        in =
            FileUtils.openInputStream(
                new File(synapseConfigRootPath + throttleOutSequenceName + ".xml"));
        builder = new StAXOMBuilder(in);
        throttleOutSequence =
            (SequenceMediator)
                factory.createMediator(builder.getDocumentElement(), new Properties());
        throttleOutSequence.setFileName(throttleOutSequenceName + ".xml");
      }
      //            if (buildSequence == null) {
      //                in = FileUtils.openInputStream(new File(synapseConfigRootPath +
      // buildSequenceName + ".xml"));
      //                builder = new StAXOMBuilder(in);
      //                buildSequence = (SequenceMediator)
      // factory.createMediator(builder.getDocumentElement(), new Properties());
      //                buildSequence.setFileName(buildSequenceName + ".xml");
      //            }
      if (sandboxKeyErrorSequence == null) {
        in =
            FileUtils.openInputStream(
                new File(synapseConfigRootPath + sandboxKeyErrorSequenceName + ".xml"));
        builder = new StAXOMBuilder(in);
        sandboxKeyErrorSequence =
            (SequenceMediator)
                factory.createMediator(builder.getDocumentElement(), new Properties());
        sandboxKeyErrorSequence.setFileName(sandboxKeyErrorSequenceName + ".xml");
      }
      if (productionKeyErrorSequence == null) {
        in =
            FileUtils.openInputStream(
                new File(synapseConfigRootPath + productionKeyErrorSequenceName + ".xml"));
        builder = new StAXOMBuilder(in);
        productionKeyErrorSequence =
            (SequenceMediator)
                factory.createMediator(builder.getDocumentElement(), new Properties());
        productionKeyErrorSequence.setFileName(productionKeyErrorSequenceName + ".xml");
      }
      FileUtils.copyFile(
          new File(synapseConfigRootPath + mainSequenceName + ".xml"),
          new File(
              synapseConfigDir.getAbsolutePath()
                  + File.separator
                  + "sequences"
                  + File.separator
                  + mainSequenceName
                  + ".xml"));

      FileUtils.copyFile(
          new File(synapseConfigRootPath + faultSequenceName + ".xml"),
          new File(
              synapseConfigDir.getAbsolutePath()
                  + File.separator
                  + "sequences"
                  + File.separator
                  + faultSequenceName
                  + ".xml"));
      FileUtils.copyFile(
          new File(synapseConfigRootPath + saml2SequenceName + ".xml"),
          new File(
              synapseConfigDir.getAbsolutePath()
                  + File.separator
                  + "sequences"
                  + File.separator
                  + saml2SequenceName
                  + ".xml"));

    } catch (IOException e) {
      log.error("Error while reading WebApp manager specific synapse sequences" + e);

    } catch (XMLStreamException e) {
      log.error("Error while parsing WebApp manager specific synapse sequences" + e);
    } finally {
      IOUtils.closeQuietly(in);
    }

    Registry registry = new WSO2Registry();
    initialSynCfg.setRegistry(registry);
    MultiXMLConfigurationSerializer serializer =
        new MultiXMLConfigurationSerializer(synapseConfigDir.getAbsolutePath());
    try {
      serializer.serializeSequence(authFailureHandlerSequence, initialSynCfg, null);
      serializer.serializeSequence(sandboxKeyErrorSequence, initialSynCfg, null);
      serializer.serializeSequence(productionKeyErrorSequence, initialSynCfg, null);
      //            serializer.serializeSequence(buildSequence, initialSynCfg, null);
      serializer.serializeSequence(throttleOutSequence, initialSynCfg, null);
      serializer.serializeSequence(resourceMisMatchSequence, initialSynCfg, null);
      serializer.serializeSynapseRegistry(registry, initialSynCfg, null);
    } catch (Exception e) {
      handleException(
          "Couldn't serialise the initial synapse configuration "
              + "for the domain : "
              + tenantDomain,
          e);
    }
  }