docs: public static SimpleEntry<Integer, String> inferDataSourceClassFromDriver(ClassLoader loader, Set<String> searched, int... types) {
          final boolean trace = TraceComponent.isAnyTracingEnabled();
          if (trace && tc.isDebugEnabled())
              Tr.debug(tc, "infer from driver", loader, Arrays.toString(types));
  
          if (loader == null)
              loader = priv.getContextClassLoader();
  
          String[] found = new String[NUM_DATA_SOURCE_INTERFACES];
          int preferredType = types[0];
  
          // Load JDBC driver class from service registry and use the package to infer the data source class
          ServiceLoader<Driver> serviceLoader = ServiceLoader.load(Driver.class, loader);
          if (serviceLoader != null) {
              // In order to give preference to JDBC drivers supplied by the user, omit JDBC drivers that are packaged with Java
              List<Driver> drivers = new ArrayList<Driver>();
              for (Iterator<Driver> it = serviceLoader.iterator(); it.hasNext(); ) {
                  Driver driver = it.next();
                  if (!driver.getClass().getName().startsWith("sun."))
                      drivers.add(driver);
              }
  
              for (Iterator<Driver> it = drivers.iterator(); found[preferredType] == null && it.hasNext(); ) {
                  Driver driver = it.next();
                  String driverClassName = driver.getClass().getName();
                  String driverPackage = null;
  
                  // Truncate the deepest subpackage to allow for the possibility that the Driver impl
                  // might be in a different subpackage than the data source impls.
                  int lastDot = driverClassName.lastIndexOf('.');
                  if (lastDot > 0) {
                      int dot = driverClassName.lastIndexOf('.', lastDot - 1);
                      dot = dot <= 10 ? lastDot : dot; // avoid packages that are so short they might be generic (org.apache.) 
                      driverPackage = driverClassName.substring(0, dot);
                      searched.add(driverPackage);
  
                      if (trace && tc.isDebugEnabled())
                          Tr.debug(tc, "infer from " + driverClassName, driverPackage);
  
                      for (Iterator<String[]> c = classNamesByKey.values().iterator(); found[preferredType] == null && c.hasNext(); ) {
                          String[] classNames = c.next(); 
                          for (int type, t = 0; t < types.length && found[preferredType] == null; t++)
                              if (found[type = types[t]] == null && classNames[type] != null && classNames[type].startsWith(driverPackage))
                                  try {
                                      loader.loadClass(classNames[type]);
                                      found[type] = classNames[type];
  
                                      if (trace && tc.isDebugEnabled())
                                          Tr.debug(tc, "found type " + type + ": " + classNames[type]);
                                  } catch (ClassNotFoundException x) {
                                      if (trace && tc.isDebugEnabled())
                                          Tr.debug(tc, classNames[type] + " not found on " + loader);
                                  }
                      }
                  }
  
                  // Guess data source names by replacing Driver with *DataSource in class name
                  if (found[preferredType] == null)
                      for (int type : types) {
                          if (type == DATA_SOURCE && found[type] == null)
                              found[type] = tryToLoad(DataSource.class, loader,
                                                      driverClassName.replace("Driver", "DataSource"));
                          else if (type == CONNECTION_POOL_DATA_SOURCE && found[type] == null)
                              found[type] = tryToLoad(ConnectionPoolDataSource.class, loader,
                                                      driverClassName.replace("Driver", "ConnectionPoolDataSource"),
                                                      driverClassName.replace("Driver", "DataSource"));
                          else if (type == XA_DATA_SOURCE && found[type] == null)
                              found[type] = tryToLoad(XADataSource.class, loader,
                                                      driverClassName.replace("Driver", "XADataSource"),
                                                      driverClassName.replace("Driver", "DataSource"));
                      }
  
                  // Scan the driver JAR file for class names in the same or similar packages that might be data sources
                  if (found[preferredType] == null && driverPackage != null) {
                      String driverFile = loader.getResource(driverClassName.replace('.', '/') + ".class").getFile();
                      if (trace && tc.isDebugEnabled())
                          Tr.debug(tc, "Driver impl file", driverFile);
  
                      int i = driverFile.indexOf('!');
                      if (i > 0)
                          try {
                              driverPackage = driverPackage.replace('.', '/');
                              int start = driverFile.startsWith("file:") ? 5 : 0;
                              String jarFile = driverFile.substring(start, i);
                              ZipInputStream zin = new ZipInputStream(new FileInputStream(jarFile));
                              try {
                                  for (ZipEntry entry; found[preferredType] == null && (entry = zin.getNextEntry()) != null; ) { 
                                      String name = entry.getName();
                                      if (name.contains(driverPackage) && name.contains("DataSource") && name.endsWith(".class")) {
                                          name = name.substring(name.indexOf(driverPackage), name.lastIndexOf('.')).replace('/', '.');
                                          try {
                                              Class<?> c = loader.loadClass(name);
                                              if (CommonDataSource.class.isAssignableFrom(c)) {
                                                  if (trace && tc.isDebugEnabled())
                                                      Tr.debug(tc, "checking " + name);
                                                  if (found[DATA_SOURCE] == null && DataSource.class.isAssignableFrom(c))
                                                      found[DATA_SOURCE] = name;
                                                  if (found[CONNECTION_POOL_DATA_SOURCE] == null && ConnectionPoolDataSource.class.isAssignableFrom(c))
                                                      found[CONNECTION_POOL_DATA_SOURCE] = name;
                                                  if (found[XA_DATA_SOURCE] == null && XADataSource.class.isAssignableFrom(c))
                                                      found[XA_DATA_SOURCE] = name;
                                              } else
                                                  if (trace && tc.isDebugEnabled())
                                                      Tr.debug(tc, name + " not a data source");
                                          } catch (ClassNotFoundException x) {
                                              if (trace && tc.isDebugEnabled())
                                                  Tr.debug(tc, name + " not found on " + loader);
                                          }
                                      }
                                  }
                              } finally {
                                  zin.close();
                              }
                          } catch (IOException x) {
                              if (trace && tc.isDebugEnabled())
                                  Tr.debug(tc, "Error reading JDBC driver binary", AdapterUtil.stackTraceToString(x));
                          }
                  }
              }
          }
  
          if (trace && tc.isDebugEnabled())
              Tr.debug(tc, "found data sources", found);
  
          for (int type : types)
              if (found[type] != null)
                  return new SimpleEntry<Integer, String>(type, found[type]);
  
          return null;
      }