public void recordTimestamp(String className, ClassLoader loader) {
    if (!(loader instanceof ModuleClassLoader)) {
      return;
    }
    Map<String, Long> stamps = null;
    final ModuleClassLoader moduleClassLoader = (ModuleClassLoader) loader;
    final ModuleIdentifier moduleIdentifier = moduleClassLoader.getModule().getIdentifier();
    if (loadersByModuleIdentifier.containsKey(moduleIdentifier)) {
      final ModuleClassLoader oldLoader = loadersByModuleIdentifier.get(moduleIdentifier);
      if (oldLoader != moduleClassLoader) {
        loadersByModuleIdentifier.put(moduleIdentifier, moduleClassLoader);
        timestamps.put(moduleClassLoader, stamps = new ConcurrentHashMap<String, Long>());
      } else {
        stamps = timestamps.get(moduleClassLoader);
      }
    } else {
      loadersByModuleIdentifier.put(moduleIdentifier, moduleClassLoader);
      timestamps.put(moduleClassLoader, stamps = new ConcurrentHashMap<String, Long>());
    }

    final URL file = loader.getResource(className.replace(".", "/") + ".class");
    className = className.replace("/", ".");
    if (file != null) {
      URLConnection connection = null;
      try {
        connection = file.openConnection();
        stamps.put(className, connection.getLastModified());
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
    @Override
    public Iterable<JavaFileObject> list(
        Location location, String packageName, Set<Kind> kinds, boolean recurse)
        throws IOException {
      if (location == StandardLocation.PLATFORM_CLASS_PATH) {
        return standardJavaFileManager.list(location, packageName, kinds, recurse);
      }
      List<JavaFileObject> ret = new ArrayList<>();
      if (kinds.contains(Kind.CLASS) && location.equals(StandardLocation.CLASS_PATH)) {
        if (classLoader instanceof ModuleClassLoader) {
          ModuleClassLoader mcl = (ModuleClassLoader) classLoader;
          final String packageWithSlashes = packageName.replace(".", "/");
          try {
            Iterator<Resource> resources =
                mcl.getModule()
                    .iterateResources(
                        new PathFilter() {
                          @Override
                          public boolean accept(String path) {
                            if (recurse) {
                              return path.startsWith(packageWithSlashes);
                            } else {
                              return path.equals(packageWithSlashes);
                            }
                          }
                        });
            while (resources.hasNext()) {
              Resource res = resources.next();
              if (!res.getName().endsWith(".class")) {
                continue;
              }
              String binaryName =
                  res.getName().replace("/", ".").substring(0, res.getName().length() - 6);
              try {
                ret.add(
                    new ZipJavaFileObject(
                        org.fakereplace.util.FileReader.readFileBytes(res.openStream()),
                        binaryName,
                        res.getURL().toURI()));
              } catch (URISyntaxException e) {
                e.printStackTrace();
              }
            }
          } catch (ModuleLoadException e) {
            e.printStackTrace();
          }
        } else {
          URL res = classLoader.getResource(packageName.replace(".", "/"));
          if (res != null) {
            if (res.getProtocol().equals("file")) {
              Path dirPath = Paths.get(res.getFile());
              listDir(packageName, dirPath, recurse, ret);
            } else if (res.getProtocol().equals("jar")) {
              JarURLConnection connection = (JarURLConnection) res.openConnection();
              Enumeration<JarEntry> entryEnum = connection.getJarFile().entries();
              while (entryEnum.hasMoreElements()) {
                JarEntry entry = entryEnum.nextElement();
                String name = entry.getName();
                if (name.endsWith(".class") && !entry.isDirectory()) {
                  if (name.startsWith(packageName.replace(".", "/"))) {
                    String rem = name.substring(packageName.length());
                    if (rem.startsWith("/")) {
                      rem = rem.substring(1);
                    }
                    if (!recurse) {
                      if (rem.contains("/")) {
                        continue;
                      }
                    }
                    String binaryName =
                        entry
                            .getName()
                            .replace("/", ".")
                            .substring(0, entry.getName().length() - 6);
                    try {
                      URI uri = new URI(res.toExternalForm() + "/" + rem);
                      ret.add(
                          new ZipJavaFileObject(
                              org.fakereplace.util.FileReader.readFileBytes(
                                  uri.toURL().openStream()),
                              binaryName,
                              uri));
                    } catch (Exception e) {
                      e.printStackTrace();
                    }
                  }
                }
              }
            } else {
              System.err.println(
                  "Could not find package "
                      + packageName
                      + " in "
                      + classLoader
                      + " unknown protocol "
                      + res.getProtocol());
            }
          } else {
            return standardJavaFileManager.list(location, packageName, kinds, recurse);
          }
        }
      } else {
        return standardJavaFileManager.list(location, packageName, kinds, recurse);
      }

      return ret;
    }