/** {@inheritDoc} */
  public ConnectionProvider initiateService(Map configurationValues, ServicesRegistry registry) {
    final ClassLoaderService classLoaderService = registry.getService(ClassLoaderService.class);

    ConnectionProvider connectionProvider = null;
    String providerClassName = (String) getConfiguredConnectionProviderName(configurationValues);
    if (providerClassName != null) {
      connectionProvider =
          instantiateExplicitConnectionProvider(providerClassName, classLoaderService);
    } else if (configurationValues.get(Environment.DATASOURCE) != null) {
      connectionProvider = new DatasourceConnectionProviderImpl();
    }

    if (connectionProvider == null) {
      if (c3p0ConfigDefined(configurationValues) && c3p0ProviderPresent(classLoaderService)) {
        connectionProvider =
            instantiateExplicitConnectionProvider(C3P0_PROVIDER_CLASS_NAME, classLoaderService);
      }
    }

    if (connectionProvider == null) {
      if (proxoolConfigDefined(configurationValues) && proxoolProviderPresent(classLoaderService)) {
        connectionProvider =
            instantiateExplicitConnectionProvider(PROXOOL_PROVIDER_CLASS_NAME, classLoaderService);
      }
    }

    if (connectionProvider == null) {
      if (configurationValues.get(Environment.URL) != null) {
        connectionProvider = new DriverManagerConnectionProviderImpl();
      }
    }

    if (connectionProvider == null) {
      log.warn(
          "No appropriate connection provider encountered, assuming application will be supplying connections");
      connectionProvider = new UserSuppliedConnectionProviderImpl();
    }

    final Map injectionData = (Map) configurationValues.get(INJECTION_DATA);
    if (injectionData != null && injectionData.size() > 0) {
      final ConnectionProvider theConnectionProvider = connectionProvider;
      new BeanInfoHelper(connectionProvider.getClass())
          .applyToBeanInfo(
              connectionProvider,
              new BeanInfoHelper.BeanInfoDelegate() {
                public void processBeanInfo(BeanInfo beanInfo) throws Exception {
                  PropertyDescriptor[] descritors = beanInfo.getPropertyDescriptors();
                  for (int i = 0, size = descritors.length; i < size; i++) {
                    String propertyName = descritors[i].getName();
                    if (injectionData.containsKey(propertyName)) {
                      Method method = descritors[i].getWriteMethod();
                      method.invoke(theConnectionProvider, injectionData.get(propertyName));
                    }
                  }
                }
              });
    }

    return connectionProvider;
  }
  @Override
  public ConnectionProvider initiateService(
      Map configurationValues, ServiceRegistryImplementor registry) {
    if (MultiTenancyStrategy.determineMultiTenancyStrategy(configurationValues)
        != MultiTenancyStrategy.NONE) {
      // nothing to do, but given the separate hierarchies have to handle this here.
    }

    final ClassLoaderService classLoaderService = registry.getService(ClassLoaderService.class);

    ConnectionProvider connectionProvider = null;
    String providerClassName = getConfiguredConnectionProviderName(configurationValues);
    if (providerClassName != null) {
      connectionProvider =
          instantiateExplicitConnectionProvider(providerClassName, classLoaderService);
    } else if (configurationValues.get(Environment.DATASOURCE) != null) {
      connectionProvider = new DatasourceConnectionProviderImpl();
    }

    if (connectionProvider == null) {
      if (c3p0ConfigDefined(configurationValues) && c3p0ProviderPresent(classLoaderService)) {
        connectionProvider =
            instantiateExplicitConnectionProvider(C3P0_PROVIDER_CLASS_NAME, classLoaderService);
      }
    }

    if (connectionProvider == null) {
      if (proxoolConfigDefined(configurationValues) && proxoolProviderPresent(classLoaderService)) {
        connectionProvider =
            instantiateExplicitConnectionProvider(PROXOOL_PROVIDER_CLASS_NAME, classLoaderService);
      }
    }

    if (connectionProvider == null) {
      if (configurationValues.get(Environment.URL) != null) {
        connectionProvider = new DriverManagerConnectionProviderImpl();
      }
    }

    if (connectionProvider == null) {
      LOG.noAppropriateConnectionProvider();
      connectionProvider = new UserSuppliedConnectionProviderImpl();
    }

    final Map injectionData = (Map) configurationValues.get(INJECTION_DATA);
    if (injectionData != null && injectionData.size() > 0) {
      final ConnectionProvider theConnectionProvider = connectionProvider;
      new BeanInfoHelper(connectionProvider.getClass())
          .applyToBeanInfo(
              connectionProvider,
              new BeanInfoHelper.BeanInfoDelegate() {
                public void processBeanInfo(BeanInfo beanInfo) throws Exception {
                  PropertyDescriptor[] descritors = beanInfo.getPropertyDescriptors();
                  for (int i = 0, size = descritors.length; i < size; i++) {
                    String propertyName = descritors[i].getName();
                    if (injectionData.containsKey(propertyName)) {
                      Method method = descritors[i].getWriteMethod();
                      method.invoke(theConnectionProvider, injectionData.get(propertyName));
                    }
                  }
                }
              });
    }

    return connectionProvider;
  }