class InstanceProviderManager {

    InstanceProvider getProvider(String provider, HostnameResolver hostnameResolver) {
        int idx = provider.lastIndexOf('.');
        if (idx == -1) {
            LOGGER.error("getProviderClient: Invalid provider service name: {}", provider);
            return null;
        }
        
        final String domainName = provider.substring(0, idx);
        DataCache dataCache = dataStore.getDataCache(domainName);
        if (dataCache == null) {
            LOGGER.error("getProviderClient: Unknown domain: {}", domainName);
            return null;
        }
        
        String providerEndpoint = null;
        boolean validProviderName = false;
        List<com.yahoo.athenz.zms.ServiceIdentity> services = dataCache.getDomainData().getServices();
        if (services == null) {
            LOGGER.error("getProviderClient: Unknown provider servicee: {}", provider);
            return null;
        }
        
        for (com.yahoo.athenz.zms.ServiceIdentity service : services) {
            if (service.getName().equals(provider)) {
                providerEndpoint = service.getProviderEndpoint();
                validProviderName = true;
                break;
            }
        }

        // if we don't have an endpoint then we have an invalid and/or no service
        
        if (providerEndpoint == null || providerEndpoint.isEmpty()) {
            if (validProviderName) {
                LOGGER.error("getProviderClient: Unknown provider service name: {}",
                        provider);
            } else {
                LOGGER.error("getProviderClient: Provider service {} does not have endpoint defined",
                        provider);
            }
            return null;
        }

        // before using our endpoint we need to make sure
        // it's valid according to configuration settings
        
        InstanceProvider instanceProvider = null;
        URI uri;
        try {
            uri = new URI(providerEndpoint);
        } catch (URISyntaxException ex) {
            LOGGER.error("getProviderClient: Unable to parse {}: {}", providerEndpoint,
                    ex.getMessage());
            return null;
        }
        
        ProviderScheme schemeType = getProviderEndpointScheme(uri);
        switch (schemeType) {
        case HTTPS:
            instanceProvider = new InstanceHttpProvider();
            instanceProvider.initialize(provider, providerEndpoint, sslContext, keyStore);
            break;
        case CLASS:
            instanceProvider = getClassProvider(uri.getHost(), provider, hostnameResolver);
            break;
        default:
            break;
        }
        
        return instanceProvider;
    }

    public  InstanceProviderManager(DataStore dataStore, SSLContext sslContext, KeyStore keyStore);

}