docs: private static Set<String> getClassNamesFromPackage(String packageName) throws IOException, URISyntaxException
      {
          ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
          Enumeration<URL> packageURLs;
          Set<String> names = new HashSet<String>();
  
          packageName = packageName.replace(".", "/");
          packageURLs = classLoader.getResources(packageName);
  
          while (packageURLs.hasMoreElements())
          {
              URL packageURL = packageURLs.nextElement();
              if (packageURL.getProtocol().equals("jar"))
              {
                  String jarFileName;
  
                  Enumeration<JarEntry> jarEntries;
                  String entryName;
  
                  // build jar file name, then loop through entries
                  jarFileName = URLDecoder.decode(packageURL.getFile(), "UTF-8");
                  jarFileName = jarFileName.substring(5, jarFileName.indexOf("!"));
                  logger.info(">" + jarFileName);
                  try (JarFile jf = new JarFile(jarFileName);)
                  {
                      jarEntries = jf.entries();
                      while (jarEntries.hasMoreElements())
                      {
                          entryName = jarEntries.nextElement().getName();
                          if (entryName.startsWith(packageName) && entryName.endsWith(".class"))
                          {
                              entryName = entryName.substring(packageName.length() + 1, entryName.lastIndexOf('.'));
                              names.add(entryName);
                          }
                      }
                  }
  
                  // loop through files in classpath
              }
              else
              {
                  URI uri = new URI(packageURL.toString());
                  File folder = new File(uri.getPath());
                  // won't work with path which contains blank (%20)
                  // File folder = new File(packageURL.getFile());
                  File[] files = folder.listFiles();
                  if (files != null)
                  {
                      for (File actual : files)
                      {
                          String entryName = actual.getName();
                          entryName = entryName.substring(0, entryName.lastIndexOf('.'));
                          names.add(entryName);
                      }
                  }
              }
          }
  
          // clean up
          Iterator<String> itr = names.iterator();
          while (itr.hasNext())
          {
              String name = itr.next();
              if (name.equals("package") || name.endsWith(".") || name.length() == 0)
              {
                  itr.remove();
              }
          }
  
          return names;
      }