KNOX-2395 - Make Gateway Services Pluggable (#358)

diff --git a/gateway-release/home/conf/gateway-site.xml b/gateway-release/home/conf/gateway-site.xml
index 2b214da..7ca8705 100644
--- a/gateway-release/home/conf/gateway-site.xml
+++ b/gateway-release/home/conf/gateway-site.xml
@@ -19,6 +19,10 @@
 <configuration>
 
     <property>
+        <name>gateway.service.alias.impl</name>
+        <value>org.apache.knox.gateway.services.security.impl.RemoteAliasService</value>
+    </property>
+    <property>
         <name>gateway.port</name>
         <value>8443</value>
         <description>The HTTP port for the Gateway.</description>
diff --git a/gateway-server/pom.xml b/gateway-server/pom.xml
index 5afed31..142101e 100644
--- a/gateway-server/pom.xml
+++ b/gateway-server/pom.xml
@@ -71,6 +71,10 @@
         </dependency>
         <dependency>
             <groupId>org.apache.knox</groupId>
+            <artifactId>gateway-service-hashicorp-vault</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.knox</groupId>
             <artifactId>gateway-i18n</artifactId>
         </dependency>
         <dependency>
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
index 18c3a4b..3c18484 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/GatewayMessages.java
@@ -698,4 +698,10 @@
 
   @Message(level = MessageLevel.ERROR, text = "Error creating provider descriptor {0} from topology {1}, cause: {2}")
   void errorSavingDescriptorConfiguration(String providerPath, String topologyName, String message);
+
+  @Message(level = MessageLevel.ERROR, text = "No service found by type {0}")
+  void noServiceFound(String serviceType);
+
+  @Message(level = MessageLevel.INFO, text = "Using {0} implementation for {1}")
+  void usingServiceImplementation(String implementation, String serviceType);
 }
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
index d03deec..2968b44 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
@@ -97,6 +97,7 @@
 
   private static final String[] GATEWAY_CONFIG_FILENAMES = {GATEWAY_CONFIG_FILE_PREFIX + "-default.xml", GATEWAY_CONFIG_FILE_PREFIX + "-site.xml"};
 
+  private static final String GATEWAY_SERVICE_PREFIX = GATEWAY_CONFIG_FILE_PREFIX + ".service.";
   public static final String HTTP_HOST = GATEWAY_CONFIG_FILE_PREFIX + ".host";
   public static final String HTTP_PORT = GATEWAY_CONFIG_FILE_PREFIX + ".port";
   public static final String HTTP_PATH = GATEWAY_CONFIG_FILE_PREFIX + ".path";
@@ -1165,4 +1166,10 @@
     return getBoolean(KNOX_TOKEN_PERMISSIVE_VALIDATION_ENABLED,
         KNOX_TOKEN_PERMISSIVE_VALIDATION_ENABLED_DEFAULT);
   }
+
+  @Override
+  public String getServiceParameter(String service, String parameter) {
+    return get(GATEWAY_SERVICE_PREFIX + service + "." + parameter, "");
+  }
+
 }
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/CLIGatewayServices.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/CLIGatewayServices.java
index 1223be1..4fdbf55 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/CLIGatewayServices.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/CLIGatewayServices.java
@@ -17,44 +17,28 @@
  */
 package org.apache.knox.gateway.services;
 
+import java.util.List;
+import java.util.Map;
+
 import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.deploy.DeploymentContext;
 import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
 import org.apache.knox.gateway.descriptor.ResourceDescriptor;
-import org.apache.knox.gateway.service.config.remote.RemoteConfigurationRegistryClientServiceFactory;
-import org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClientService;
-import org.apache.knox.gateway.services.security.impl.RemoteAliasService;
-import org.apache.knox.gateway.services.topology.impl.DefaultTopologyService;
-import org.apache.knox.gateway.services.security.impl.DefaultAliasService;
-import org.apache.knox.gateway.services.security.impl.DefaultCryptoService;
-import org.apache.knox.gateway.services.security.impl.DefaultKeystoreService;
 import org.apache.knox.gateway.services.security.impl.CLIMasterService;
 import org.apache.knox.gateway.topology.Provider;
 
-import java.util.List;
-import java.util.Map;
-
 public class CLIGatewayServices extends AbstractGatewayServices {
 
+  private final GatewayServiceFactory gatewayServiceFactory = new GatewayServiceFactory();
+
   public CLIGatewayServices() {
     super("Services", "GatewayServices");
   }
 
   @Override
   public void init(GatewayConfig config, Map<String,String> options) throws ServiceLifecycleException {
-    CLIMasterService ms = new CLIMasterService();
-    ms.init(config, options);
-    addService(ServiceType.MASTER_SERVICE, ms);
-
-    DefaultKeystoreService ks = new DefaultKeystoreService();
-    ks.setMasterService(ms);
-    ks.init(config, options);
-    addService(ServiceType.KEYSTORE_SERVICE, ks);
-
-    DefaultAliasService defaultAlias = new DefaultAliasService();
-    defaultAlias.setKeystoreService(ks);
-    defaultAlias.setMasterService(ms);
-    defaultAlias.init(config, options);
+    addService(ServiceType.MASTER_SERVICE, gatewayServiceFactory.create(this, ServiceType.MASTER_SERVICE, config, options, CLIMasterService.class.getName()));
+    addService(ServiceType.KEYSTORE_SERVICE, gatewayServiceFactory.create(this, ServiceType.KEYSTORE_SERVICE, config, options));
 
     /*
     Doesn't make sense for this to be set to the remote alias service since the impl could
@@ -62,32 +46,13 @@
     IE: If ZK digest auth and using ZK remote alias service, then wouldn't be able to connect
     to ZK anyway due to the circular dependency.
      */
-    final RemoteConfigurationRegistryClientService registryClientService =
-        RemoteConfigurationRegistryClientServiceFactory.newInstance(config);
-    registryClientService.setAliasService(defaultAlias);
-    registryClientService.init(config, options);
-    addService(ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, registryClientService);
+    addService(ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, gatewayServiceFactory.create(this, ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, config, options));
 
+    addService(ServiceType.ALIAS_SERVICE, gatewayServiceFactory.create(this, ServiceType.ALIAS_SERVICE, config, options));
 
-    /* create an instance so that it can be passed to other services */
-    final RemoteAliasService alias = new RemoteAliasService(defaultAlias, ms);
-    /*
-     * Setup and initialize remote Alias Service.
-     * NOTE: registryClientService.init() needs to
-     * be called before alias.start();
-     */
-    alias.init(config, options);
-    addService(ServiceType.ALIAS_SERVICE, alias);
+    addService(ServiceType.CRYPTO_SERVICE, gatewayServiceFactory.create(this, ServiceType.CRYPTO_SERVICE, config, options));
 
-    DefaultCryptoService crypto = new DefaultCryptoService();
-    crypto.setKeystoreService(ks);
-    crypto.setAliasService(alias);
-    crypto.init(config, options);
-    addService(ServiceType.CRYPTO_SERVICE, crypto);
-
-    DefaultTopologyService tops = new DefaultTopologyService();
-    tops.init(  config, options  );
-    addService(ServiceType.TOPOLOGY_SERVICE, tops);
+    addService(ServiceType.TOPOLOGY_SERVICE, gatewayServiceFactory.create(this, ServiceType.TOPOLOGY_SERVICE, config, options));
   }
 
   @Override
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
index b120dec..0517763 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/DefaultGatewayServices.java
@@ -17,37 +17,22 @@
  */
 package org.apache.knox.gateway.services;
 
+import java.util.List;
+import java.util.Map;
+
 import org.apache.knox.gateway.GatewayMessages;
 import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.deploy.DeploymentContext;
 import org.apache.knox.gateway.descriptor.FilterParamDescriptor;
 import org.apache.knox.gateway.descriptor.ResourceDescriptor;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
-import org.apache.knox.gateway.service.config.remote.RemoteConfigurationRegistryClientServiceFactory;
-import org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClientService;
-import org.apache.knox.gateway.services.registry.impl.DefaultServiceDefinitionRegistry;
-import org.apache.knox.gateway.services.metrics.impl.DefaultMetricsService;
 import org.apache.knox.gateway.services.security.KeystoreService;
-import org.apache.knox.gateway.services.security.impl.RemoteAliasService;
-import org.apache.knox.gateway.services.token.impl.AliasBasedTokenStateService;
-import org.apache.knox.gateway.services.topology.impl.DefaultClusterConfigurationMonitorService;
-import org.apache.knox.gateway.services.topology.impl.DefaultTopologyService;
-import org.apache.knox.gateway.services.hostmap.impl.DefaultHostMapperService;
-import org.apache.knox.gateway.services.registry.impl.DefaultServiceRegistryService;
 import org.apache.knox.gateway.services.security.KeystoreServiceException;
-import org.apache.knox.gateway.services.security.impl.DefaultAliasService;
-import org.apache.knox.gateway.services.security.impl.DefaultCryptoService;
-import org.apache.knox.gateway.services.security.impl.DefaultKeystoreService;
-import org.apache.knox.gateway.services.security.impl.DefaultMasterService;
-import org.apache.knox.gateway.services.security.impl.JettySSLService;
-import org.apache.knox.gateway.services.token.impl.DefaultTokenAuthorityService;
 import org.apache.knox.gateway.topology.Provider;
 
-import java.util.List;
-import java.util.Map;
-
 public class DefaultGatewayServices extends AbstractGatewayServices {
   private static GatewayMessages log = MessagesFactory.get( GatewayMessages.class );
+  private final GatewayServiceFactory gatewayServiceFactory = new GatewayServiceFactory();
 
   public DefaultGatewayServices() {
     super("Services", "GatewayServices");
@@ -55,19 +40,9 @@
 
   @Override
   public void init(GatewayConfig config, Map<String,String> options) throws ServiceLifecycleException {
-    DefaultMasterService ms = new DefaultMasterService();
-    ms.init(config, options);
-    addService(ServiceType.MASTER_SERVICE, ms);
-
-    DefaultKeystoreService ks = new DefaultKeystoreService();
-    ks.setMasterService(ms);
-    ks.init(config, options);
-    addService(ServiceType.KEYSTORE_SERVICE, ks);
-
-    final DefaultAliasService defaultAlias = new DefaultAliasService();
-    defaultAlias.setKeystoreService(ks);
-    defaultAlias.setMasterService(ms);
-    defaultAlias.init(config, options);
+    //order is important: different service factory implementations may use already added services
+    addService(ServiceType.MASTER_SERVICE, gatewayServiceFactory.create(this, ServiceType.MASTER_SERVICE, config, options));
+    addService(ServiceType.KEYSTORE_SERVICE, gatewayServiceFactory.create(this, ServiceType.KEYSTORE_SERVICE, config, options));
 
     /*
     Doesn't make sense for this to be set to the remote alias service since the impl could
@@ -75,80 +50,34 @@
     IE: If ZK digest auth and using ZK remote alias service, then wouldn't be able to connect
     to ZK anyway due to the circular dependency.
      */
-    final RemoteConfigurationRegistryClientService registryClientService =
-        RemoteConfigurationRegistryClientServiceFactory.newInstance(config);
-    registryClientService.setAliasService(defaultAlias);
-    registryClientService.init(config, options);
-    addService(ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, registryClientService);
+    addService(ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, gatewayServiceFactory.create(this, ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE, config, options));
 
+    addService(ServiceType.ALIAS_SERVICE, gatewayServiceFactory.create(this, ServiceType.ALIAS_SERVICE, config, options));
 
-    /* create an instance so that it can be passed to other services */
-    final RemoteAliasService alias = new RemoteAliasService(defaultAlias, ms);
-    /*
-     * Setup and initialize remote Alias Service.
-     * NOTE: registryClientService.init() needs to
-     * be called before alias.start();
-     */
-    alias.init(config, options);
-    addService(ServiceType.ALIAS_SERVICE, alias);
+    addService(ServiceType.CRYPTO_SERVICE, gatewayServiceFactory.create(this, ServiceType.CRYPTO_SERVICE, config, options));
 
-    DefaultCryptoService crypto = new DefaultCryptoService();
-    crypto.setKeystoreService(ks);
-    crypto.setAliasService(alias);
-    crypto.init(config, options);
-    addService(ServiceType.CRYPTO_SERVICE, crypto);
-
-    JettySSLService ssl = new JettySSLService();
-    ssl.setAliasService(alias);
-    ssl.setKeystoreService(ks);
-    ssl.init(config, options);
-    addService(ServiceType.SSL_SERVICE, ssl);
+    addService(ServiceType.SSL_SERVICE, gatewayServiceFactory.create(this, ServiceType.SSL_SERVICE, config, options));
 
     // The DefaultTokenAuthorityService needs to be initialized after the JettySSLService to ensure
     // that the signing keystore is available for it.
-    DefaultTokenAuthorityService ts = new DefaultTokenAuthorityService();
-    ts.setAliasService(alias);
-    ts.setKeystoreService(ks);
-    ts.init(config, options);
-    // prolly should not allow the token service to be looked up?
-    addService(ServiceType.TOKEN_SERVICE, ts);
+    // probably should not allow the token service to be looked up?
+    addService(ServiceType.TOKEN_SERVICE, gatewayServiceFactory.create(this, ServiceType.TOKEN_SERVICE, config, options));
 
-    AliasBasedTokenStateService tss = new AliasBasedTokenStateService();
-    tss.setAliasService(alias);
-    tss.init(config, options);
-    addService(ServiceType.TOKEN_STATE_SERVICE, tss);
+    addService(ServiceType.TOKEN_STATE_SERVICE, gatewayServiceFactory.create(this, ServiceType.TOKEN_STATE_SERVICE, config, options));
 
-    DefaultServiceRegistryService sr = new DefaultServiceRegistryService();
-    sr.setCryptoService( crypto );
-    sr.init( config, options );
-    addService(ServiceType.SERVICE_REGISTRY_SERVICE, sr);
+    addService(ServiceType.SERVICE_REGISTRY_SERVICE, gatewayServiceFactory.create(this, ServiceType.SERVICE_REGISTRY_SERVICE, config, options));
 
-    DefaultHostMapperService hm = new DefaultHostMapperService();
-    hm.init( config, options );
-    addService(ServiceType.HOST_MAPPING_SERVICE, hm );
+    addService(ServiceType.HOST_MAPPING_SERVICE, gatewayServiceFactory.create(this, ServiceType.HOST_MAPPING_SERVICE, config, options));
 
-    DefaultServerInfoService sis = new DefaultServerInfoService();
-    sis.init( config, options );
-    addService(ServiceType.SERVER_INFO_SERVICE, sis );
+    addService(ServiceType.SERVER_INFO_SERVICE, gatewayServiceFactory.create(this, ServiceType.SERVER_INFO_SERVICE, config, options));
 
-    DefaultClusterConfigurationMonitorService ccs = new DefaultClusterConfigurationMonitorService();
-    ccs.setAliasService(alias);
-    ccs.setKeystoreService(ks);
-    ccs.init(config, options);
-    addService(ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE, ccs);
+    addService(ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE, gatewayServiceFactory.create(this, ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE, config, options));
 
-    DefaultTopologyService tops = new DefaultTopologyService();
-    tops.setAliasService(alias);
-    tops.init(  config, options  );
-    addService(ServiceType.TOPOLOGY_SERVICE, tops  );
+    addService(ServiceType.TOPOLOGY_SERVICE, gatewayServiceFactory.create(this, ServiceType.TOPOLOGY_SERVICE, config, options));
 
-    DefaultServiceDefinitionRegistry sdr = new DefaultServiceDefinitionRegistry();
-    sdr.init( config, options );
-    addService(ServiceType.SERVICE_DEFINITION_REGISTRY, sdr );
+    addService(ServiceType.SERVICE_DEFINITION_REGISTRY, gatewayServiceFactory.create(this, ServiceType.SERVICE_DEFINITION_REGISTRY, config, options));
 
-    DefaultMetricsService metricsService = new DefaultMetricsService();
-    metricsService.init( config, options );
-    addService(ServiceType.METRICS_SERVICE, metricsService );
+    addService(ServiceType.METRICS_SERVICE, gatewayServiceFactory.create(this, ServiceType.METRICS_SERVICE, config, options));
   }
 
   @Override
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/GatewayServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/GatewayServiceFactory.java
new file mode 100644
index 0000000..3e43bc2
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/GatewayServiceFactory.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services;
+
+import java.util.Map;
+import java.util.ServiceLoader;
+
+import org.apache.knox.gateway.GatewayMessages;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+
+public class GatewayServiceFactory implements ServiceFactory {
+  private static final GatewayMessages LOG = MessagesFactory.get(GatewayMessages.class);
+  private ServiceLoader<ServiceFactory> serviceFactories;
+
+  @Override
+  public Service create(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options) throws ServiceLifecycleException {
+    return create(gatewayServices, serviceType, gatewayConfig, options, null);
+  }
+
+  @Override
+  public Service create(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    for (ServiceFactory serviceFactory : getServiceFactories()) {
+      service = implementation == null ? serviceFactory.create(gatewayServices, serviceType, gatewayConfig, options)
+          : serviceFactory.create(gatewayServices, serviceType, gatewayConfig, options, implementation);
+      if (service != null) {
+        break;
+      }
+    }
+    if (service != null) {
+      service.init(gatewayConfig, options);
+    } else {
+      LOG.noServiceFound(serviceType.getServiceTypeName());
+    }
+    return service;
+  }
+
+  private ServiceLoader<ServiceFactory> getServiceFactories() {
+    if (serviceFactories == null) {
+      serviceFactories = ServiceLoader.load(ServiceFactory.class);
+    }
+    return serviceFactories;
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AbstractServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AbstractServiceFactory.java
new file mode 100644
index 0000000..ab02ec0
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AbstractServiceFactory.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.knox.gateway.GatewayMessages;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.i18n.messages.MessagesFactory;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceFactory;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.KeystoreService;
+import org.apache.knox.gateway.services.security.MasterService;
+
+public abstract class AbstractServiceFactory implements ServiceFactory {
+
+  private static final GatewayMessages LOG = MessagesFactory.get(GatewayMessages.class);
+  private static final String IMPLEMENTATION_PARAM_NAME = "impl";
+  private static final String EMPTY_DEFAULT_IMPLEMENTATION = "";
+
+  @Override
+  public Service create(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options) throws ServiceLifecycleException {
+    return create(gatewayServices, serviceType, gatewayConfig, options, getImplementation(gatewayConfig));
+  }
+
+  @Override
+  public Service create(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (getServiceType() == serviceType) {
+      service = createService(gatewayServices, serviceType, gatewayConfig, options, implementation);
+      if (service == null && StringUtils.isNotBlank(implementation)) {
+        // no known service implementation created, try to create the custom one
+        try {
+          service = Service.class.cast(Class.forName(implementation).newInstance());
+          logServiceUsage(implementation, serviceType);
+        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+          throw new ServiceLifecycleException("Errror while instantiating " + serviceType.getShortName() + " service implementation " + implementation, e);
+        }
+      }
+    }
+    return service;
+  }
+
+  protected String getImplementation(GatewayConfig gatewayConfig) {
+    return gatewayConfig.getServiceParameter(getServiceType().getShortName(), IMPLEMENTATION_PARAM_NAME);
+  }
+
+  protected boolean matchesImplementation(String implementation, Class<? extends Object> clazz) {
+    return matchesImplementation(implementation, clazz, false);
+  }
+
+  protected boolean matchesImplementation(String implementation, Class<? extends Object> clazz, boolean acceptEmptyImplementation) {
+    boolean match = clazz.getName().equals(implementation);
+    if (!match && acceptEmptyImplementation) {
+      match = isEmptyDefaultImplementation(implementation);
+    }
+    return match;
+  }
+
+  private boolean isEmptyDefaultImplementation(String implementation) {
+    return EMPTY_DEFAULT_IMPLEMENTATION.equals(implementation);
+  }
+
+  protected boolean shouldCreateService(String implementation) {
+    return implementation == null || isEmptyDefaultImplementation(implementation) || getKnownImplementations().contains(implementation);
+  }
+
+  protected MasterService getMasterService(GatewayServices gatewayServices) {
+    return gatewayServices.getService(ServiceType.MASTER_SERVICE);
+  }
+
+  protected KeystoreService getKeystoreService(GatewayServices gatewayServices) {
+    return gatewayServices.getService(ServiceType.KEYSTORE_SERVICE);
+  }
+
+  protected AliasService getAliasService(GatewayServices gatewayServices) {
+    return gatewayServices.getService(ServiceType.ALIAS_SERVICE);
+  }
+
+  protected void logServiceUsage(String implementation, ServiceType serviceType) {
+    LOG.usingServiceImplementation("".equals(implementation) ? "default" : implementation, serviceType.getServiceTypeName());
+  }
+
+  // abstract methods
+
+  protected abstract Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options,
+      String implementation) throws ServiceLifecycleException;
+
+  protected abstract ServiceType getServiceType();
+
+  protected abstract Collection<String> getKnownImplementations();
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AliasServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AliasServiceFactory.java
new file mode 100644
index 0000000..d3e3227
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/AliasServiceFactory.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.knox.gateway.backend.hashicorp.vault.HashicorpVaultAliasService;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.impl.DefaultAliasService;
+import org.apache.knox.gateway.services.security.impl.RemoteAliasService;
+import org.apache.knox.gateway.services.security.impl.ZookeeperRemoteAliasService;
+import org.apache.knox.gateway.services.security.impl.ZookeeperRemoteAliasServiceProvider;
+
+public class AliasServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      final AliasService defaultAliasService = new DefaultAliasService();
+      ((DefaultAliasService) defaultAliasService).setMasterService(getMasterService(gatewayServices));
+      ((DefaultAliasService) defaultAliasService).setKeystoreService(getKeystoreService(gatewayServices));
+      defaultAliasService.init(gatewayConfig, options); // invoking init on DefaultAliasService twice is ok (in case implementation is set to 'default')
+
+      if (matchesImplementation(implementation, DefaultAliasService.class, true)) {
+        service = defaultAliasService;
+      } else if (matchesImplementation(implementation, HashicorpVaultAliasService.class)) {
+        service = new HashicorpVaultAliasService(defaultAliasService);
+      } else if (matchesImplementation(implementation, RemoteAliasService.class)) {
+        service = new RemoteAliasService(defaultAliasService, getMasterService(gatewayServices));
+      } else if (matchesImplementation(implementation, ZookeeperRemoteAliasService.class)) {
+        service = new ZookeeperRemoteAliasServiceProvider().newInstance(defaultAliasService, getMasterService(gatewayServices));
+      }
+
+      logServiceUsage(implementation, serviceType);
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.ALIAS_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return unmodifiableList(
+        asList(DefaultAliasService.class.getName(), HashicorpVaultAliasService.class.getName(), RemoteAliasService.class.getName(), ZookeeperRemoteAliasService.class.getName()));
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactory.java
new file mode 100644
index 0000000..14fe584
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.topology.impl.DefaultClusterConfigurationMonitorService;
+
+public class ClusterConfigurationMonitorServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultClusterConfigurationMonitorService();
+      ((DefaultClusterConfigurationMonitorService) service).setAliasService(getAliasService(gatewayServices));
+      ((DefaultClusterConfigurationMonitorService) service).setKeystoreService(getKeystoreService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultClusterConfigurationMonitorService.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/CryptoServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/CryptoServiceFactory.java
new file mode 100644
index 0000000..59daca1
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/CryptoServiceFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.impl.DefaultCryptoService;
+
+public class CryptoServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultCryptoService();
+      ((DefaultCryptoService) service).setKeystoreService(getKeystoreService(gatewayServices));
+      ((DefaultCryptoService) service).setAliasService(getAliasService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.CRYPTO_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultCryptoService.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactory.java
new file mode 100644
index 0000000..549abd2
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.hostmap.impl.DefaultHostMapperService;
+
+public class HostMappingServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    return shouldCreateService(implementation) ? new DefaultHostMapperService() : null;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.HOST_MAPPING_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultHostMapperService.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactory.java
new file mode 100644
index 0000000..ee83c22
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.impl.DefaultKeystoreService;
+
+public class KeystoreServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultKeystoreService();
+      ((DefaultKeystoreService) service).setMasterService(getMasterService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.KEYSTORE_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultKeystoreService.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MasterServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MasterServiceFactory.java
new file mode 100644
index 0000000..4b7d167
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MasterServiceFactory.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.impl.CLIMasterService;
+import org.apache.knox.gateway.services.security.impl.DefaultMasterService;
+
+public class MasterServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      if (matchesImplementation(implementation, DefaultMasterService.class, true)) {
+        service = new DefaultMasterService();
+      } else if (matchesImplementation(implementation, CLIMasterService.class)) {
+        service = new CLIMasterService();
+      }
+
+      logServiceUsage(implementation, serviceType);
+    }
+
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.MASTER_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return unmodifiableList(asList(DefaultMasterService.class.getName(), CLIMasterService.class.getName()));
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MetricsServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MetricsServiceFactory.java
new file mode 100644
index 0000000..af200e1
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/MetricsServiceFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.metrics.impl.DefaultMetricsService;
+
+public class MetricsServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    return shouldCreateService(implementation) ? new DefaultMetricsService() : null;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.METRICS_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultMetricsService.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/RemoteRegistryClientServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/RemoteRegistryClientServiceFactory.java
new file mode 100644
index 0000000..1ae7fe8
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/RemoteRegistryClientServiceFactory.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.service.config.remote.RemoteConfigurationRegistryClientServiceFactory;
+import org.apache.knox.gateway.service.config.remote.zk.ZooKeeperClientService;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.config.client.RemoteConfigurationRegistryClientService;
+import org.apache.knox.gateway.services.security.AliasService;
+
+// There are two implementations of 'RemoteConfigurationRegistryClientService':
+// - LocalFileSystemRemoteConfigurationRegistryClientService
+// - CuratorClientService
+// However, the first one - local - is for test-only purposes
+public class RemoteRegistryClientServiceFactory extends AbstractServiceFactory {
+
+  private final AliasServiceFactory aliasServiceFactory = new AliasServiceFactory();
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = RemoteConfigurationRegistryClientServiceFactory.newInstance(gatewayConfig);
+      // it should be the 'default' alias service
+      final AliasService localAliasService = (AliasService) aliasServiceFactory.create(gatewayServices, ServiceType.ALIAS_SERVICE, gatewayConfig, options, "");
+      localAliasService.init(gatewayConfig, options);
+      ((RemoteConfigurationRegistryClientService) service).setAliasService(localAliasService);
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.REMOTE_REGISTRY_CLIENT_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(ZooKeeperClientService.class.getName());
+  }
+
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactory.java
new file mode 100644
index 0000000..b9605a0
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.DefaultServerInfoService;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+
+public class ServerInfoServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    return shouldCreateService(implementation) ? new DefaultServerInfoService() : null;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.SERVER_INFO_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultServerInfoService.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactory.java
new file mode 100644
index 0000000..7961f07
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.registry.impl.DefaultServiceDefinitionRegistry;
+
+public class ServiceDefinitionRegistryFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    return shouldCreateService(implementation) ? new DefaultServiceDefinitionRegistry() : null;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.SERVICE_DEFINITION_REGISTRY;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultServiceDefinitionRegistry.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceRegistryServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceRegistryServiceFactory.java
new file mode 100644
index 0000000..f1be4e3
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/ServiceRegistryServiceFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.registry.impl.DefaultServiceRegistryService;
+
+public class ServiceRegistryServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultServiceRegistryService();
+      ((DefaultServiceRegistryService) service).setCryptoService(gatewayServices.getService(ServiceType.CRYPTO_SERVICE));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.SERVICE_REGISTRY_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultServiceRegistryService.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/SslServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/SslServiceFactory.java
new file mode 100644
index 0000000..f1792f0
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/SslServiceFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.impl.JettySSLService;
+
+public class SslServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new JettySSLService();
+      ((JettySSLService) service).setKeystoreService(getKeystoreService(gatewayServices));
+      ((JettySSLService) service).setAliasService(getAliasService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.SSL_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(JettySSLService.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenServiceFactory.java
new file mode 100644
index 0000000..f03deeb
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenServiceFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.token.impl.DefaultTokenAuthorityService;
+
+public class TokenServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultTokenAuthorityService();
+      ((DefaultTokenAuthorityService) service).setKeystoreService(getKeystoreService(gatewayServices));
+      ((DefaultTokenAuthorityService) service).setAliasService(getAliasService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.TOKEN_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultTokenAuthorityService.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactory.java
new file mode 100644
index 0000000..800fcb2
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactory.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.token.impl.AliasBasedTokenStateService;
+import org.apache.knox.gateway.services.token.impl.DefaultTokenStateService;
+import org.apache.knox.gateway.services.token.impl.JournalBasedTokenStateService;
+
+public class TokenStateServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      if (matchesImplementation(implementation, DefaultTokenStateService.class, true)) {
+        service = new DefaultTokenStateService();
+      } else if (matchesImplementation(implementation, AliasBasedTokenStateService.class)) {
+        service = new AliasBasedTokenStateService();
+        ((AliasBasedTokenStateService) service).setAliasService(getAliasService(gatewayServices));
+      } else if (matchesImplementation(implementation, JournalBasedTokenStateService.class)) {
+        service = new JournalBasedTokenStateService();
+      }
+
+      logServiceUsage(implementation, serviceType);
+    }
+
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.TOKEN_STATE_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return unmodifiableList(asList(DefaultTokenStateService.class.getName(), AliasBasedTokenStateService.class.getName(), JournalBasedTokenStateService.class.getName()));
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TopologyServiceFactory.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TopologyServiceFactory.java
new file mode 100644
index 0000000..74dffd5
--- /dev/null
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/factory/TopologyServiceFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.topology.impl.DefaultTopologyService;
+
+public class TopologyServiceFactory extends AbstractServiceFactory {
+
+  @Override
+  protected Service createService(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException {
+    Service service = null;
+    if (shouldCreateService(implementation)) {
+      service = new DefaultTopologyService();
+      ((DefaultTopologyService) service).setAliasService(getAliasService(gatewayServices));
+    }
+    return service;
+  }
+
+  @Override
+  protected ServiceType getServiceType() {
+    return ServiceType.TOPOLOGY_SERVICE;
+  }
+
+  @Override
+  protected Collection<String> getKnownImplementations() {
+    return Collections.singleton(DefaultTopologyService.class.getName());
+  }
+}
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultCryptoService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultCryptoService.java
index 755eb60..788055f 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultCryptoService.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultCryptoService.java
@@ -43,23 +43,23 @@
 
   private static final Map<String,ConfigurableEncryptor> ENCRYPTOR_CACHE = new HashMap<>();
 
-  private AliasService as;
-  private KeystoreService ks;
+  private AliasService aliasService;
+  private KeystoreService keystoreService;
   private GatewayConfig config;
 
   public void setKeystoreService(KeystoreService ks) {
-    this.ks = ks;
+    this.keystoreService = ks;
   }
 
   public void setAliasService(AliasService as) {
-    this.as = as;
+    this.aliasService = as;
   }
 
   @Override
   public void init(GatewayConfig config, Map<String, String> options)
       throws ServiceLifecycleException {
     this.config = config;
-  if (as == null) {
+  if (aliasService == null) {
       throw new ServiceLifecycleException("Alias service is not set");
     }
   }
@@ -77,7 +77,7 @@
   @Override
   public void createAndStoreEncryptionKeyForCluster(String clusterName, String alias) {
     try {
-      as.generateAliasForCluster(clusterName, alias);
+      aliasService.generateAliasForCluster(clusterName, alias);
     } catch (AliasServiceException e) {
       e.printStackTrace();
     }
@@ -87,7 +87,7 @@
   public EncryptionResult encryptForCluster(String clusterName, String alias, byte[] clear) {
     char[] password = null;
     try {
-      password = as.getPasswordFromAliasForCluster(clusterName, alias);
+      password = aliasService.getPasswordFromAliasForCluster(clusterName, alias);
     } catch (AliasServiceException e2) {
       e2.printStackTrace();
     }
@@ -111,7 +111,7 @@
     try {
       char[] password;
       ConfigurableEncryptor encryptor;
-        password = as.getPasswordFromAliasForCluster(clusterName, alias);
+        password = aliasService.getPasswordFromAliasForCluster(clusterName, alias);
         if (password != null) {
           encryptor = getEncryptor(clusterName,password );
           try {
@@ -134,7 +134,7 @@
     boolean verified = false;
     try {
       Signature sig=Signature.getInstance(algorithm);
-      sig.initVerify(ks.getCertificateForGateway().getPublicKey());
+      sig.initVerify(keystoreService.getCertificateForGateway().getPublicKey());
       sig.update(signed.getBytes(StandardCharsets.UTF_8));
       verified = sig.verify(signature);
     } catch (SignatureException | KeystoreServiceException | InvalidKeyException | NoSuchAlgorithmException | KeyStoreException e) {
@@ -148,8 +148,8 @@
   public byte[] sign(String algorithm, String payloadToSign) {
     try {
       char[] passphrase;
-      passphrase = as.getGatewayIdentityPassphrase();
-      PrivateKey privateKey = (PrivateKey) ks.getKeyForGateway(passphrase);
+      passphrase = aliasService.getGatewayIdentityPassphrase();
+      PrivateKey privateKey = (PrivateKey) keystoreService.getKeyForGateway(passphrase);
       Signature signature = Signature.getInstance(algorithm);
       signature.initSign(privateKey);
       signature.update(payloadToSign.getBytes(StandardCharsets.UTF_8));
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
index 5a58029..546d53d 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/DefaultKeystoreService.java
@@ -26,7 +26,6 @@
 import org.apache.knox.gateway.config.GatewayConfig;
 import org.apache.knox.gateway.i18n.messages.MessagesFactory;
 import org.apache.knox.gateway.i18n.resources.ResourcesFactory;
-import org.apache.knox.gateway.services.Service;
 import org.apache.knox.gateway.services.ServiceLifecycleException;
 import org.apache.knox.gateway.services.security.KeystoreService;
 import org.apache.knox.gateway.services.security.KeystoreServiceException;
@@ -68,7 +67,7 @@
 
 import javax.crypto.spec.SecretKeySpec;
 
-public class DefaultKeystoreService implements KeystoreService, Service {
+public class DefaultKeystoreService implements KeystoreService {
   private static final String DN_TEMPLATE = "CN={0},OU=Test,O=Hadoop,L=Test,ST=Test,C=US";
   private static final String CREDENTIALS_SUFFIX = "-credentials.jceks";
   private static final String CREDENTIALS_STORE_TYPE = "JCEKS";
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
index 6e79f36..867e3df 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/security/impl/JettySSLService.java
@@ -43,15 +43,15 @@
   private static final String GATEWAY_CREDENTIAL_STORE_NAME = "__gateway";
   private static GatewayMessages log = MessagesFactory.get( GatewayMessages.class );
 
-  private KeystoreService ks;
-  private AliasService as;
+  private KeystoreService keystoreService;
+  private AliasService aliasService;
 
   public void setAliasService(AliasService as) {
-    this.as = as;
+    this.aliasService = as;
   }
 
   public void setKeystoreService(KeystoreService ks) {
-    this.ks = ks;
+    this.keystoreService = ks;
   }
 
   @Override
@@ -60,9 +60,9 @@
     // set any JSSE or security related system properties
     System.setProperty(EPHEMERAL_DH_KEY_SIZE_PROPERTY, config.getEphemeralDHKeySize());
     try {
-      if (!ks.isCredentialStoreForClusterAvailable(GATEWAY_CREDENTIAL_STORE_NAME)) {
+      if (!keystoreService.isCredentialStoreForClusterAvailable(GATEWAY_CREDENTIAL_STORE_NAME)) {
         log.creatingCredentialStoreForGateway();
-        ks.createCredentialStoreForCluster(GATEWAY_CREDENTIAL_STORE_NAME);
+        keystoreService.createCredentialStoreForCluster(GATEWAY_CREDENTIAL_STORE_NAME);
         // LET'S NOT GENERATE A DIFFERENT KEY PASSPHRASE BY DEFAULT ANYMORE
         // IF A DEPLOYMENT WANTS TO CHANGE THE KEY PASSPHRASE TO MAKE IT MORE SECURE THEN
         // THEY CAN ADD THE ALIAS EXPLICITLY WITH THE CLI
@@ -76,16 +76,16 @@
     }
 
     try {
-      if (!ks.isKeystoreForGatewayAvailable()) {
+      if (!keystoreService.isKeystoreForGatewayAvailable()) {
         log.creatingKeyStoreForGateway();
-        ks.createKeystoreForGateway();
+        keystoreService.createKeystoreForGateway();
         char[] passphrase;
         try {
-          passphrase = as.getGatewayIdentityPassphrase();
+          passphrase = aliasService.getGatewayIdentityPassphrase();
         } catch (AliasServiceException e) {
           throw new ServiceLifecycleException("Error accessing credential store for the gateway.", e);
         }
-        ks.addSelfSignedCertForGateway(config.getIdentityKeyAlias(), passphrase);
+        keystoreService.addSelfSignedCertForGateway(config.getIdentityKeyAlias(), passphrase);
       }
       else {
         log.keyStoreForGatewayFoundNotCreating();
@@ -101,7 +101,7 @@
     Certificate cert;
     final String identityKeyAlias = config.getIdentityKeyAlias();
     try {
-      cert = as.getCertificateForGateway(identityKeyAlias);
+      cert = aliasService.getCertificateForGateway(identityKeyAlias);
     } catch (AliasServiceException e) {
       throw new ServiceLifecycleException("Cannot Retreive Gateway SSL Certificate. Server will not start.", e);
     }
@@ -143,7 +143,7 @@
 
     char[] keystorePasswordChars;
     try {
-      keystorePasswordChars = as.getGatewayIdentityKeystorePassword();
+      keystorePasswordChars = aliasService.getGatewayIdentityKeystorePassword();
     } catch (AliasServiceException e) {
       log.failedToGetPasswordForGatewayIdentityKeystore(e);
       throw e;
@@ -154,7 +154,7 @@
 
     char[] keypass;
     try {
-      keypass = as.getGatewayIdentityPassphrase();
+      keypass = aliasService.getGatewayIdentityPassphrase();
     } catch (AliasServiceException e) {
       log.failedToGetPassphraseForGatewayIdentityKey(e);
       throw e;
@@ -175,7 +175,7 @@
         trustStoreType = config.getTruststoreType();
 
         try {
-          truststorePassword = as.getPasswordFromAliasForGateway(trustStorePasswordAlias);
+          truststorePassword = aliasService.getPasswordFromAliasForGateway(trustStorePasswordAlias);
         } catch (AliasServiceException e) {
           log.failedToGetPasswordForGatewayTruststore(trustStorePasswordAlias, e);
           throw e;
@@ -188,7 +188,7 @@
         trustStoreType = identityKeystoreType;
 
         try {
-          truststorePassword = as.getGatewayIdentityKeystorePassword();
+          truststorePassword = aliasService.getGatewayIdentityKeystorePassword();
         } catch (AliasServiceException e) {
           log.failedToGetPasswordForGatewayTruststore(config.getIdentityKeystorePasswordAlias(), e);
           throw e;
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
index 465e370..a6f83ea 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/services/token/impl/DefaultTokenAuthorityService.java
@@ -73,8 +73,8 @@
   private static final GatewayResources RESOURCES = ResourcesFactory.get(GatewayResources.class);
 
   private static final Set<String> SUPPORTED_SIG_ALGS = new HashSet<>();
-  private AliasService as;
-  private KeystoreService ks;
+  private AliasService aliasService;
+  private KeystoreService keystoreService;
   private GatewayConfig config;
 
   private char[] cachedSigningKeyPassphrase;
@@ -92,11 +92,11 @@
   }
 
   public void setKeystoreService(KeystoreService ks) {
-    this.ks = ks;
+    this.keystoreService = ks;
   }
 
   public void setAliasService(AliasService as) {
-    this.as = as;
+    this.aliasService = as;
   }
 
   @Override
@@ -144,7 +144,7 @@
           throws KeystoreServiceException, TokenServiceException {
 
     if (signingKeystorePassphrase != null) {
-      return (RSAPrivateKey) ks.getSigningKey(signingKeystoreName,
+      return (RSAPrivateKey) keystoreService.getSigningKey(signingKeystoreName,
               getSigningKeyAlias(signingKeystoreAlias),
               getSigningKeyPassphrase(signingKeystorePassphrase));
     }
@@ -217,7 +217,7 @@
     PublicKey key;
     try {
       if (publicKey == null) {
-        key = ks.getSigningKeystore().getCertificate(getSigningKeyAlias()).getPublicKey();
+        key = keystoreService.getSigningKeystore().getCertificate(getSigningKeyAlias()).getPublicKey();
       }
       else {
         key = publicKey;
@@ -261,7 +261,7 @@
   @Override
   public void init(GatewayConfig config, Map<String, String> options)
       throws ServiceLifecycleException {
-    if (as == null || ks == null) {
+    if (aliasService == null || keystoreService == null) {
       throw new ServiceLifecycleException("Alias or Keystore service is not set");
     }
     this.config = config;
@@ -272,7 +272,7 @@
     // Ensure that the default signing keystore is available
     KeyStore keystore;
     try {
-      keystore = ks.getSigningKeystore();
+      keystore = keystoreService.getSigningKeystore();
       if (keystore == null) {
         throw new ServiceLifecycleException(RESOURCES.signingKeystoreNotAvailable(config.getSigningKeystorePath()));
       }
@@ -282,7 +282,7 @@
 
     // Ensure that the password for the signing key is available
     try {
-      cachedSigningKeyPassphrase = as.getSigningKeyPassphrase();
+      cachedSigningKeyPassphrase = aliasService.getSigningKeyPassphrase();
       if (cachedSigningKeyPassphrase == null) {
         throw new ServiceLifecycleException(RESOURCES.signingKeyPassphraseNotAvailable(config.getSigningKeyPassphraseAlias()));
       }
diff --git a/gateway-server/src/main/resources/META-INF/services/org.apache.knox.gateway.services.ServiceFactory b/gateway-server/src/main/resources/META-INF/services/org.apache.knox.gateway.services.ServiceFactory
new file mode 100644
index 0000000..02275ea
--- /dev/null
+++ b/gateway-server/src/main/resources/META-INF/services/org.apache.knox.gateway.services.ServiceFactory
@@ -0,0 +1,33 @@
+##########################################################################
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##########################################################################
+
+org.apache.knox.gateway.services.factory.AliasServiceFactory
+org.apache.knox.gateway.services.factory.ClusterConfigurationMonitorServiceFactory
+org.apache.knox.gateway.services.factory.CryptoServiceFactory
+org.apache.knox.gateway.services.factory.HostMappingServiceFactory
+org.apache.knox.gateway.services.factory.KeystoreServiceFactory
+org.apache.knox.gateway.services.factory.MasterServiceFactory
+org.apache.knox.gateway.services.factory.MetricsServiceFactory
+org.apache.knox.gateway.services.factory.RemoteRegistryClientServiceFactory
+org.apache.knox.gateway.services.factory.ServerInfoServiceFactory
+org.apache.knox.gateway.services.factory.ServiceDefinitionRegistryFactory
+org.apache.knox.gateway.services.factory.ServiceRegistryServiceFactory
+org.apache.knox.gateway.services.factory.SslServiceFactory
+org.apache.knox.gateway.services.factory.TokenServiceFactory
+org.apache.knox.gateway.services.factory.TokenStateServiceFactory
+org.apache.knox.gateway.services.factory.TopologyServiceFactory
\ No newline at end of file
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java
index 3e418b5..f449d05 100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java
@@ -38,7 +38,7 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+  import static org.junit.Assert.assertTrue;
 
 public class GatewayConfigImplTest {
 
@@ -405,4 +405,22 @@
     assertEquals(ZookeeperRemoteAliasService.TYPE, remoteAliasServiceConfiguration.get(REMOTE_ALIAS_SERVICE_TYPE));
   }
 
+  @Test
+  public void testGetServiceParameter() throws Exception {
+    final GatewayConfigImpl gatewayConfig = new GatewayConfigImpl();
+
+    // should return an empty string if 'gateway.service.alias.impl' is not set
+    assertEquals("", gatewayConfig.getServiceParameter("alias", "impl"));
+
+    gatewayConfig.set("gateway.service.alias.impl", "myAliasService");
+    gatewayConfig.set("gateway.service.tokenstate.impl", "myTokenStateService");
+
+    // should return an empty string if the given service is not defined
+    assertEquals("", gatewayConfig.getServiceParameter("notListedService", "impl"));
+
+    //should return the declared implementations
+    assertEquals("myAliasService", gatewayConfig.getServiceParameter("alias", "impl"));
+    assertEquals("myTokenStateService", gatewayConfig.getServiceParameter("tokenstate", "impl"));
+  }
+
 }
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/TestService.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/TestService.java
new file mode 100644
index 0000000..cae8ad9
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/TestService.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services;
+
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+
+public class TestService implements Service {
+
+  @Override
+  public void init(GatewayConfig config, Map<String, String> options) throws ServiceLifecycleException {
+  }
+
+  @Override
+  public void start() throws ServiceLifecycleException {
+  }
+
+  @Override
+  public void stop() throws ServiceLifecycleException {
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/AliasServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/AliasServiceFactoryTest.java
new file mode 100644
index 0000000..3dfdd14
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/AliasServiceFactoryTest.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.apache.knox.gateway.services.ServiceType.ALIAS_SERVICE;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.backend.hashicorp.vault.HashicorpVaultAliasService;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.impl.DefaultAliasService;
+import org.apache.knox.gateway.services.security.impl.RemoteAliasService;
+import org.apache.knox.gateway.services.security.impl.ZookeeperRemoteAliasService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AliasServiceFactoryTest extends ServiceFactoryTest {
+
+  private final AliasServiceFactory serviceFactory = new AliasServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.ALIAS_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultAliasService() throws Exception {
+    AliasService aliasService = (AliasService) serviceFactory.create(gatewayServices, ServiceType.ALIAS_SERVICE, gatewayConfig, options, DefaultAliasService.class.getName());
+    assertTrue(aliasService instanceof DefaultAliasService);
+    assertTrue(isMasterServiceSet(aliasService));
+    assertTrue(isKeystoreServiceSet(aliasService));
+
+    aliasService = (AliasService) serviceFactory.create(gatewayServices, ServiceType.ALIAS_SERVICE, gatewayConfig, options, "");
+    assertTrue(aliasService instanceof DefaultAliasService);
+    assertTrue(isMasterServiceSet(aliasService));
+    assertTrue(isKeystoreServiceSet(aliasService));
+  }
+
+  @Test
+  public void shouldReturnHashicorpVaultAliasService() throws Exception {
+    assertTrue(serviceFactory.create(gatewayServices, ALIAS_SERVICE, gatewayConfig, options, HashicorpVaultAliasService.class.getName()) instanceof HashicorpVaultAliasService);
+  }
+
+  @Test
+  public void shouldReturnRemoteAliasService() throws Exception {
+    assertTrue(serviceFactory.create(gatewayServices, ALIAS_SERVICE, gatewayConfig, options, RemoteAliasService.class.getName()) instanceof RemoteAliasService);
+  }
+
+  @Test
+  public void shouldReturnZookeeperAliasService() throws Exception {
+    assertTrue(serviceFactory.create(gatewayServices, ALIAS_SERVICE, gatewayConfig, options, ZookeeperRemoteAliasService.class.getName()) instanceof ZookeeperRemoteAliasService);
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactoryTest.java
new file mode 100644
index 0000000..46e4ca7
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ClusterConfigurationMonitorServiceFactoryTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.topology.impl.DefaultClusterConfigurationMonitorService;
+import org.apache.knox.gateway.topology.ClusterConfigurationMonitorService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ClusterConfigurationMonitorServiceFactoryTest extends ServiceFactoryTest {
+
+  private final ClusterConfigurationMonitorServiceFactory serviceFactory = new ClusterConfigurationMonitorServiceFactory();
+
+  @Before
+  public void setUp() {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultClusterConfigurationMonitorService() throws Exception {
+    final ClusterConfigurationMonitorService clusterConfigurationMonitorService = (ClusterConfigurationMonitorService) serviceFactory.create(gatewayServices,
+        ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE, gatewayConfig, options);
+    assertTrue(clusterConfigurationMonitorService instanceof DefaultClusterConfigurationMonitorService);
+    assertTrue(isAliasServiceSet(clusterConfigurationMonitorService));
+    assertTrue(isKeystoreServiceSet(clusterConfigurationMonitorService));
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/CryptoServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/CryptoServiceFactoryTest.java
new file mode 100644
index 0000000..e8dad07
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/CryptoServiceFactoryTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.CryptoService;
+import org.apache.knox.gateway.services.security.impl.DefaultCryptoService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CryptoServiceFactoryTest extends ServiceFactoryTest {
+  private final CryptoServiceFactory serviceFactory = new CryptoServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.CRYPTO_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultCryptoService() throws Exception {
+    final CryptoService cryptoService = (CryptoService) serviceFactory.create(gatewayServices, ServiceType.CRYPTO_SERVICE, gatewayConfig, options);
+    assertTrue(cryptoService instanceof DefaultCryptoService);
+    assertTrue(isKeystoreServiceSet(cryptoService));
+    assertTrue(isAliasServiceSet(cryptoService));
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactoryTest.java
new file mode 100644
index 0000000..3205be1
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/HostMappingServiceFactoryTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.hostmap.HostMapperService;
+import org.apache.knox.gateway.services.hostmap.impl.DefaultHostMapperService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class HostMappingServiceFactoryTest extends ServiceFactoryTest {
+
+  private final HostMappingServiceFactory serviceFactory = new HostMappingServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.HOST_MAPPING_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultHostMapperService() throws Exception {
+    final HostMapperService hostMapperService = (HostMapperService) serviceFactory.create(gatewayServices, ServiceType.HOST_MAPPING_SERVICE, gatewayConfig, options);
+    assertTrue(hostMapperService instanceof DefaultHostMapperService);
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactoryTest.java
new file mode 100644
index 0000000..a19ff73
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/KeystoreServiceFactoryTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.KeystoreService;
+import org.apache.knox.gateway.services.security.impl.DefaultKeystoreService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class KeystoreServiceFactoryTest extends ServiceFactoryTest {
+
+  private final KeystoreServiceFactory serviceFactory = new KeystoreServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.KEYSTORE_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultKeystoreService() throws Exception {
+    final KeystoreService keystoreService = (KeystoreService) serviceFactory.create(gatewayServices, ServiceType.KEYSTORE_SERVICE, gatewayConfig, options);
+    assertTrue(keystoreService instanceof DefaultKeystoreService);
+    assertTrue(isMasterServiceSet(keystoreService));
+  }
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MasterServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MasterServiceFactoryTest.java
new file mode 100644
index 0000000..36beaca
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MasterServiceFactoryTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.MasterService;
+import org.apache.knox.gateway.services.security.impl.CLIMasterService;
+import org.apache.knox.gateway.services.security.impl.DefaultMasterService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MasterServiceFactoryTest extends ServiceFactoryTest {
+
+  private final MasterServiceFactory serviceFactory = new MasterServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.CLUSTER_CONFIGURATION_MONITOR_SERVICE, ServiceType.MASTER_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultMasterService() throws Exception {
+    MasterService masterService = (MasterService) serviceFactory.create(gatewayServices, ServiceType.MASTER_SERVICE, null, null, DefaultMasterService.class.getName());
+    assertTrue(masterService instanceof DefaultMasterService);
+
+    masterService = (MasterService) serviceFactory.create(gatewayServices, ServiceType.MASTER_SERVICE, null, null, "");
+    assertTrue(masterService instanceof DefaultMasterService);
+  }
+
+  @Test
+  public void shouldReturnCliMasterService() throws Exception {
+    MasterService masterService = (MasterService) serviceFactory.create(gatewayServices, ServiceType.MASTER_SERVICE, null, null, CLIMasterService.class.getName());
+    assertTrue(masterService instanceof CLIMasterService);
+  }
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MetricsServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MetricsServiceFactoryTest.java
new file mode 100644
index 0000000..95eaea6
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/MetricsServiceFactoryTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.metrics.MetricsService;
+import org.apache.knox.gateway.services.metrics.impl.DefaultMetricsService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MetricsServiceFactoryTest extends ServiceFactoryTest {
+
+  private final MetricsServiceFactory serviceFactory = new MetricsServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.METRICS_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultMetricsService() throws Exception {
+    final MetricsService metricsService = (MetricsService) serviceFactory.create(gatewayServices, ServiceType.METRICS_SERVICE, gatewayConfig, options);
+    assertTrue(metricsService instanceof DefaultMetricsService);
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactoryTest.java
new file mode 100644
index 0000000..a97e490
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServerInfoServiceFactoryTest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.DefaultServerInfoService;
+import org.apache.knox.gateway.services.ServerInfoService;
+import org.apache.knox.gateway.services.ServiceType;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ServerInfoServiceFactoryTest extends ServiceFactoryTest {
+
+  private final ServerInfoServiceFactory serviceFactory = new ServerInfoServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.SERVER_INFO_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultServerInfoService() throws Exception {
+    final ServerInfoService serverInfoService = (ServerInfoService) serviceFactory.create(gatewayServices, ServiceType.SERVER_INFO_SERVICE, gatewayConfig, options);
+    assertTrue(serverInfoService instanceof DefaultServerInfoService);
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactoryTest.java
new file mode 100644
index 0000000..67e0a67
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceDefinitionRegistryFactoryTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.apache.knox.gateway.services.ServiceType.SERVICE_DEFINITION_REGISTRY;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.registry.ServiceDefinitionRegistry;
+import org.apache.knox.gateway.services.registry.impl.DefaultServiceDefinitionRegistry;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ServiceDefinitionRegistryFactoryTest extends ServiceFactoryTest {
+
+  private final ServiceDefinitionRegistryFactory serviceFactory = new ServiceDefinitionRegistryFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, SERVICE_DEFINITION_REGISTRY);
+  }
+
+  @Test
+  public void shouldReturnDefaultServiceDefinitionRegistry() throws Exception {
+    final ServiceDefinitionRegistry serviceDefinitionRegistry = (ServiceDefinitionRegistry) serviceFactory.create(gatewayServices, SERVICE_DEFINITION_REGISTRY, gatewayConfig,
+        options);
+    assertTrue(serviceDefinitionRegistry instanceof DefaultServiceDefinitionRegistry);
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceFactoryTest.java
new file mode 100644
index 0000000..c7dbced
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/ServiceFactoryTest.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.CoreMatchers.isA;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.knox.gateway.config.GatewayConfig;
+import org.apache.knox.gateway.services.GatewayServices;
+import org.apache.knox.gateway.services.Service;
+import org.apache.knox.gateway.services.ServiceLifecycleException;
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.TestService;
+import org.apache.knox.gateway.services.security.AliasService;
+import org.apache.knox.gateway.services.security.KeystoreService;
+import org.apache.knox.gateway.services.security.MasterService;
+import org.easymock.EasyMock;
+import org.junit.Rule;
+import org.junit.rules.ExpectedException;
+
+class ServiceFactoryTest {
+
+  @SuppressWarnings("deprecation")
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  protected final GatewayServices gatewayServices = EasyMock.createNiceMock(GatewayServices.class);
+  protected final GatewayConfig gatewayConfig = EasyMock.createNiceMock(GatewayConfig.class);
+  protected final Map<String, String> options = Collections.emptyMap();
+
+  protected void initConfig() {
+    final MasterService masterService = EasyMock.createNiceMock(MasterService.class);
+    expect(gatewayServices.getService(ServiceType.MASTER_SERVICE)).andReturn(masterService).anyTimes();
+    final KeystoreService keystoreservice = EasyMock.createNiceMock(KeystoreService.class);
+    expect(gatewayServices.getService(ServiceType.KEYSTORE_SERVICE)).andReturn(keystoreservice).anyTimes();
+    final AliasService aliasService = EasyMock.createNiceMock(AliasService.class);
+    expect(gatewayServices.getService(ServiceType.ALIAS_SERVICE)).andReturn(aliasService).anyTimes();
+    replay(gatewayServices);
+    expect(gatewayConfig.getServiceParameter(anyString(), anyString())).andReturn("").anyTimes();
+    replay(gatewayConfig);
+  }
+
+  protected void testBasics(AbstractServiceFactory serviceFactory, ServiceType nonMatchingServiceType, ServiceType matchingServiceType) throws Exception {
+    shouldReturnCorrectServiceType(serviceFactory, matchingServiceType);
+    shouldReturnNullForNonMatchingServiceType(serviceFactory, nonMatchingServiceType);
+    shouldReturnCustomImplementation(serviceFactory, matchingServiceType);
+    shouldFailWithClassNotFoundExceptionForUnknownImplementationWithClassNotOnClasspath(serviceFactory, matchingServiceType);
+  }
+
+  private void shouldReturnCorrectServiceType(AbstractServiceFactory serviceFactory, ServiceType serviceType) {
+    assertEquals(serviceType, serviceFactory.getServiceType());
+  }
+
+  private void shouldReturnNullForNonMatchingServiceType(AbstractServiceFactory serviceFactory, ServiceType serviceType) throws Exception {
+    assertNull(serviceFactory.create(gatewayServices, serviceType, gatewayConfig, options));
+  }
+
+  private void shouldFailWithClassNotFoundExceptionForUnknownImplementationWithClassNotOnClasspath(AbstractServiceFactory serviceFactory, ServiceType serviceType)
+      throws Exception {
+    expectedException.expect(ServiceLifecycleException.class);
+    final String implementation = "this.is.my.non.existing.Service";
+    expectedException.expectMessage(String.format(Locale.ROOT, "Errror while instantiating %s service implementation %s", serviceType.getShortName(), implementation));
+    expectedException.expectCause(isA(ClassNotFoundException.class));
+    serviceFactory.create(gatewayServices, serviceType, null, null, implementation);
+  }
+
+  private void shouldReturnCustomImplementation(AbstractServiceFactory serviceFactory, ServiceType matchingServiceType) throws Exception {
+    final Service service = serviceFactory.create(gatewayServices, matchingServiceType, null, null, "org.apache.knox.gateway.services.TestService");
+    assertTrue(service instanceof TestService);
+  }
+
+  protected boolean isMasterServiceSet(Service serviceToCheck) throws Exception {
+    return isServiceSet(serviceToCheck, "masterService");
+  }
+
+  protected boolean isKeystoreServiceSet(Service serviceToCheck) throws Exception {
+    return isServiceSet(serviceToCheck, "keystoreService");
+  }
+
+  protected boolean isAliasServiceSet(Service serviceToCheck) throws Exception {
+    return isServiceSet(serviceToCheck, "aliasService");
+  }
+
+  private boolean isServiceSet(Service serviceToCheck, String expectedServiceName) throws Exception {
+    final Field aliasServiceField = FieldUtils.getDeclaredField(serviceToCheck.getClass(), expectedServiceName, true);
+    final Object aliasServiceValue = aliasServiceField.get(serviceToCheck);
+    return aliasServiceValue != null;
+  }
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/SslServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/SslServiceFactoryTest.java
new file mode 100644
index 0000000..76b15fd
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/SslServiceFactoryTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.SSLService;
+import org.apache.knox.gateway.services.security.impl.JettySSLService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SslServiceFactoryTest extends ServiceFactoryTest {
+
+  private final SslServiceFactory serviceFactory = new SslServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.SSL_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnJettySslService() throws Exception {
+    final SSLService keystoreService = (SSLService) serviceFactory.create(gatewayServices, ServiceType.SSL_SERVICE, gatewayConfig, options);
+    assertTrue(keystoreService instanceof JettySSLService);
+    assertTrue(isKeystoreServiceSet(keystoreService));
+    assertTrue(isAliasServiceSet(keystoreService));
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenServiceFactoryTest.java
new file mode 100644
index 0000000..425a2a7
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenServiceFactoryTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.token.impl.DefaultTokenAuthorityService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TokenServiceFactoryTest extends ServiceFactoryTest {
+
+  private final TokenServiceFactory serviceFactory = new TokenServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.TOKEN_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultTokenService() throws Exception {
+    final DefaultTokenAuthorityService keystoreService = (DefaultTokenAuthorityService) serviceFactory.create(gatewayServices, ServiceType.TOKEN_SERVICE, gatewayConfig, options);
+    assertTrue(keystoreService instanceof DefaultTokenAuthorityService);
+    assertTrue(isKeystoreServiceSet(keystoreService));
+    assertTrue(isAliasServiceSet(keystoreService));
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactoryTest.java
new file mode 100644
index 0000000..7625d50
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TokenStateServiceFactoryTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.security.token.TokenStateService;
+import org.apache.knox.gateway.services.token.impl.AliasBasedTokenStateService;
+import org.apache.knox.gateway.services.token.impl.DefaultTokenStateService;
+import org.apache.knox.gateway.services.token.impl.JournalBasedTokenStateService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TokenStateServiceFactoryTest extends ServiceFactoryTest {
+
+  private final TokenStateServiceFactory serviceFactory = new TokenStateServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.TOKEN_STATE_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultAliasService() throws Exception {
+    TokenStateService tokenStateService = (TokenStateService) serviceFactory.create(gatewayServices, ServiceType.TOKEN_STATE_SERVICE, null, null, DefaultTokenStateService.class.getName());
+    assertTrue(tokenStateService instanceof DefaultTokenStateService);
+
+    tokenStateService = (TokenStateService) serviceFactory.create(gatewayServices, ServiceType.TOKEN_STATE_SERVICE, null, null, "");
+    assertTrue(tokenStateService instanceof DefaultTokenStateService);
+  }
+
+  @Test
+  public void shouldReturnAliasBasedTokenStateService() throws Exception {
+    final TokenStateService tokenStateService = (TokenStateService) serviceFactory.create(gatewayServices, ServiceType.TOKEN_STATE_SERVICE, null, null, AliasBasedTokenStateService.class.getName());
+    assertTrue(tokenStateService instanceof AliasBasedTokenStateService);
+    assertTrue(isAliasServiceSet(tokenStateService));
+  }
+
+  @Test
+  public void shouldReturnHJournalTokenStateService() throws Exception {
+    assertTrue(serviceFactory.create(gatewayServices, ServiceType.TOKEN_STATE_SERVICE, null, null, JournalBasedTokenStateService.class.getName()) instanceof JournalBasedTokenStateService);
+  }
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TopologyServiceFactoryTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TopologyServiceFactoryTest.java
new file mode 100644
index 0000000..151d42d
--- /dev/null
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/services/factory/TopologyServiceFactoryTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services.factory;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.knox.gateway.services.ServiceType;
+import org.apache.knox.gateway.services.topology.TopologyService;
+import org.apache.knox.gateway.services.topology.impl.DefaultTopologyService;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TopologyServiceFactoryTest extends ServiceFactoryTest {
+
+  private final TopologyServiceFactory serviceFactory = new TopologyServiceFactory();
+
+  @Before
+  public void setUp() throws Exception {
+    initConfig();
+  }
+
+  @Test
+  public void testBasics() throws Exception {
+    super.testBasics(serviceFactory, ServiceType.MASTER_SERVICE, ServiceType.TOPOLOGY_SERVICE);
+  }
+
+  @Test
+  public void shouldReturnDefaultTopologyService() throws Exception {
+    TopologyService topologyService = (TopologyService) serviceFactory.create(gatewayServices, ServiceType.TOPOLOGY_SERVICE, gatewayConfig, null);
+    assertTrue(topologyService instanceof DefaultTopologyService);
+    assertTrue(isAliasServiceSet(topologyService));
+  }
+
+}
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/BadUrlTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/BadUrlTest.java
index 7e1105d..2fca3c5 100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/BadUrlTest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/BadUrlTest.java
@@ -310,6 +310,8 @@
         .andReturn(TEST_KEY_ALIAS)
         .anyTimes();
 
+    EasyMock.expect(gatewayConfig.getServiceParameter(EasyMock.anyString(), EasyMock.anyString())).andReturn("").anyTimes();
+
     EasyMock.replay(gatewayConfig);
 
     try {
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketEchoTestBase.java b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketEchoTestBase.java
index 86a580a..bf11748 100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketEchoTestBase.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketEchoTestBase.java
@@ -336,6 +336,7 @@
         .andReturn(TEST_KEY_ALIAS)
         .anyTimes();
 
+    EasyMock.expect(gatewayConfig.getServiceParameter(EasyMock.anyString(), EasyMock.anyString())).andReturn("").anyTimes();
 
     EasyMock.replay(gatewayConfig);
 
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketMultipleConnectionTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketMultipleConnectionTest.java
index a2a4ae7..d7db608 100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketMultipleConnectionTest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/websockets/WebsocketMultipleConnectionTest.java
@@ -373,6 +373,8 @@
         .andReturn(TEST_KEY_ALIAS)
         .anyTimes();
 
+    EasyMock.expect(gatewayConfig.getServiceParameter(EasyMock.anyString(), EasyMock.anyString())).andReturn("").anyTimes();
+
     EasyMock.replay(gatewayConfig);
 
     try {
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
index 7825e7b..4e533ad 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/config/GatewayConfig.java
@@ -693,4 +693,9 @@
    * @return returns whether know token permissive validation is enabled
    */
   boolean isKnoxTokenPermissiveValidationEnabled();
+
+  /**
+   * @return the value of the given parameter for the given service if declared; an empty String otherwise
+   */
+  String getServiceParameter(String service, String parameter);
 }
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceFactory.java b/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceFactory.java
new file mode 100644
index 0000000..ca0301e
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.knox.gateway.services;
+
+import java.util.Map;
+
+import org.apache.knox.gateway.config.GatewayConfig;
+
+public interface ServiceFactory {
+
+  Service create(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options) throws ServiceLifecycleException;
+
+  Service create(GatewayServices gatewayServices, ServiceType serviceType, GatewayConfig gatewayConfig, Map<String, String> options, String implementation)
+      throws ServiceLifecycleException;
+
+}
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java b/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java
index 736ecad..38767f8 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/services/ServiceType.java
@@ -18,6 +18,8 @@
 
 package org.apache.knox.gateway.services;
 
+import java.util.Locale;
+
 public enum ServiceType {
   ALIAS_SERVICE("AliasService"),
   CLUSTER_CONFIGURATION_MONITOR_SERVICE("ClusterConfigurationMonitorService"),
@@ -36,12 +38,18 @@
   TOPOLOGY_SERVICE("TopologyService");
 
   private final String serviceTypeName;
+  private final String shortName;
 
   ServiceType(String serviceTypeName) {
     this.serviceTypeName = serviceTypeName;
+    this.shortName = serviceTypeName.toLowerCase(Locale.ROOT).replace("service", "");
   }
 
   public String getServiceTypeName() {
     return serviceTypeName;
   }
+
+  public String getShortName() {
+    return shortName;
+  }
 }
diff --git a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
index 95c1f71..68fb637 100644
--- a/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
+++ b/gateway-spi/src/main/java/org/apache/knox/gateway/services/security/KeystoreService.java
@@ -24,7 +24,9 @@
 import java.util.Map;
 import java.util.Set;
 
-public interface KeystoreService {
+import org.apache.knox.gateway.services.Service;
+
+public interface KeystoreService extends Service {
 
   void createKeystoreForGateway() throws KeystoreServiceException;
 
diff --git a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
index e3dbeaa..499fe3f 100644
--- a/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
+++ b/gateway-test-release-utils/src/main/java/org/apache/knox/gateway/GatewayTestConfig.java
@@ -812,4 +812,9 @@
   public boolean isKnoxTokenPermissiveValidationEnabled() {
     return false;
   }
+
+  @Override
+  public String getServiceParameter(String service, String parameter) {
+    return "";
+  }
 }