class AbstractProviderRegistry implements ProviderRegistry<P, S> {

    @Override
    public synchronized S register(P provider) {
        checkNotNull(provider, "Provider cannot be null");
        checkState(!services.containsKey(provider.id()), "Provider %s already registered", provider.id());

        // If the provider is a primary one, check for a conflict.
        ProviderId pid = provider.id();
        checkState(pid.isAncillary() || !providersByScheme.containsKey(pid.scheme()),
                   "A primary provider with id %s is already registered",
                   providersByScheme.get(pid.scheme()));

        S service = createProviderService(provider);
        services.put(provider.id(), service);
        providers.put(provider.id(), provider);

        // Register the provider by URI scheme only if it is not ancillary.
        if (!pid.isAncillary()) {
            providersByScheme.put(pid.scheme(), provider);
        }

        return service;
    }

}