docs: private <T extends CommonDataSource> T create(final String className, final Hashtable<?, ?> props, String dsID) throws SQLException {
          if (classloader != null && className.startsWith("org.apache.derby.jdbc.Embedded") && isDerbyEmbedded.compareAndSet(false, true)) {
              embDerbyRefCount.add(classloader);
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                  Tr.debug(this, tc, "ref count for shutdown", classloader, embDerbyRefCount);
          }
  
          final boolean trace = TraceComponent.isAnyTracingEnabled();
          if (trace && tc.isEntryEnabled())
              Tr.entry(tc, "create", className, classloader, PropertyService.hidePasswords(props));
  
          //Add a value for connectionFactoryClassName when using UCP if one is not specified
          if (className.startsWith("oracle.ucp.jdbc") && !props.containsKey("connectionFactoryClassName")) {
              if (className.equals("oracle.ucp.jdbc.PoolDataSourceImpl") && props instanceof PropertyService) {
                  if (trace && tc.isDebugEnabled())
                      Tr.debug(tc, "Setting connectionFactoryClassName property to oracle.jdbc.pool.OracleDataSource");
                  ((PropertyService) props).setProperty("connectionFactoryClassName", "oracle.jdbc.pool.OracleDataSource");
              } else if (className.equals("oracle.ucp.jdbc.PoolXADataSourceImpl") && props instanceof PropertyService) {
                  if (trace && tc.isDebugEnabled())
                      Tr.debug(tc, "Setting connectionFactoryClassName property to oracle.jdbc.xa.client.OracleXADataSource");
                  ((PropertyService) props).setProperty("connectionFactoryClassName", "oracle.jdbc.xa.client.OracleXADataSource");
              }
          }
          try {
              T ds = AccessController.doPrivileged(new PrivilegedExceptionAction<T>() {
                  public T run() throws Exception {
                      ClassLoader loader, origTCCL = Thread.currentThread().getContextClassLoader();
                      try {
                          if (classloader == null)
                              loader = origTCCL; // Use thread context class loader of application in absence of server configured library
                          else
                              Thread.currentThread().setContextClassLoader(loader = classloader);
  
                          @SuppressWarnings("unchecked")
                          Class<T> dsClass = (Class<T>) loader.loadClass(className);
                          introspectedClasses.add(dsClass);
                          T ds = dsClass.newInstance();
  
                          // Set all of the JDBC vendor properties
                          Hashtable<?, ?> p = (Hashtable<?, ?>) props.clone();
                          for (PropertyDescriptor descriptor : Introspector.getBeanInfo(dsClass).getPropertyDescriptors()) {
                              String name = descriptor.getName();
                              Object value = p.remove(name);
  
                              // handle osgi vs non-osgi URL property
                              if (value == null && name.equals("url")) {
                                  value = p.remove("URL");
                              }
  
                              boolean isPassword = PropertyService.isPassword(name);
  
                              if (value != null)
                                  try {
                                      if (value instanceof String) {
                                          String str = (String) value;
                                          // Decode passwords
                                          if (isPassword)
                                              str = PasswordUtil.getCryptoAlgorithm(str) == null ? str : PasswordUtil.decode(str);
                                          setProperty(ds, descriptor, str, !isPassword);
                                      } else {
                                          // Property already has correct non-String type
                                          if (trace && tc.isDebugEnabled())
                                              Tr.debug(tc, "set " + name + " = " + value);
                                          descriptor.getWriteMethod().invoke(ds, value);
                                      }
                                  } catch (Throwable x) {
                                      if (x instanceof InvocationTargetException)
                                          x = x.getCause();
                                      FFDCFilter.processException(x, getClass().getName(), "217", this, new Object[] { className, name, value });
                                      boolean isURL = ("URL".equals(name) || "url".equals(name)) && value instanceof String;
                                      SQLException failure = connectorSvc.ignoreWarnOrFail(tc, x, SQLException.class, "PROP_SET_ERROR", name,
                                                                                                       "=" + (isPassword ? "******" : isURL ? PropertyService.filterURL((String) value) : value),
                                                                                                       AdapterUtil.stackTraceToString(x));
                                      if (failure != null)
                                          throw failure;
                                  }
                          }
  
                          // Are there any properties remaining for which we couldn't find setters?
                          if (!p.isEmpty())
                              for (Object propertyName : p.keySet())
                                  // Filter out properties that only apply to XA or that shouldn't be set on the driver
                                  if ((!PROPS_FOR_XA_ONLY.contains(propertyName) || ds instanceof XADataSource) && !PROPS_NOT_SET_ON_DRIVER.contains(propertyName) ) {
                                      SQLException failure = connectorSvc.ignoreWarnOrFail(tc, null, SQLException.class, "PROP_NOT_FOUND", className, propertyName);
                                      if (failure != null)
                                          throw failure;
                                  }
  
                          return ds;
                      } finally {
                          if (classloader != null)
                              Thread.currentThread().setContextClassLoader(origTCCL);
                      }
                  }
              });
              if (trace && tc.isEntryEnabled())
                  Tr.exit(tc, "create", ds);
              return ds;
          } catch (PrivilegedActionException privX) {
              Throwable x = privX.getCause();
              FFDCFilter.processException(x, JDBCDriverService.class.getName(), "234");
              int lastDot = className.lastIndexOf('.');
              Set<String> searched = Collections.singleton(lastDot > 0 ? className.substring(0, lastDot) : className);
              SQLException sqlX = x instanceof ClassNotFoundException ? classNotFound(className, searched, dsID, x)
                              : x instanceof SQLException ? (SQLException) x
                                              : new SQLNonTransientException(x);
              if (trace && tc.isEntryEnabled())
                  Tr.exit(tc, "create", x);
              throw sqlX;
          }
      }