private static @NotNull LoaderData buildData(@NotNull Path path, boolean isClassPathIndexEnabled) {
    Path indexFile = isClassPathIndexEnabled ? path.resolve("classpath.index") : null;
    LoaderData loaderData = indexFile == null ? null : readFromIndex(indexFile);

    int nsMsFactor = 1_000_000;
    int currentLoaders = totalLoaders.incrementAndGet();
    long currentScanningTime;
    if (loaderData == null) {
      long started = System.nanoTime();

      StrippedLongArrayList nameHashes = new StrippedLongArrayList();

      ClasspathCache.LoaderDataBuilder loaderDataBuilder = new ClasspathCache.LoaderDataBuilder();
      buildPackageAndNameCache(path, loaderDataBuilder, nameHashes);
      loaderData = new LoaderData(loaderDataBuilder.resourcePackageHashes.toArray(),
                                  loaderDataBuilder.classPackageHashes.toArray(),
                                  new NameFilter(Xor16.construct(nameHashes.elements(), 0, nameHashes.size())));
      long doneNanos = System.nanoTime() - started;
      currentScanningTime = totalScanning.addAndGet(doneNanos);
      if (doFsActivityLogging) {
        //noinspection UseOfSystemOutOrSystemErr
        System.out.println("Scanned: " + path + " for " + (doneNanos / nsMsFactor) + "ms");
      }

      if (isClassPathIndexEnabled) {
        Path tempFile = null;
        try {
          tempFile = indexFile.getParent().resolve("classpath.index." + Long.toUnsignedString(tempCounter.getAndIncrement()) + ".tmp");
          saveIndex(loaderData, tempFile);
          try {
            Files.move(tempFile, indexFile, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
          }
          catch (AtomicMoveNotSupportedException e) {
            Files.move(tempFile, indexFile, StandardCopyOption.REPLACE_EXISTING);
          }
        }
        catch (IOException e) {
          try {
            Files.deleteIfExists(tempFile);
          }
          catch (IOException ignore) {
          }

          //noinspection CallToPrintStackTrace
          e.printStackTrace();
        }
      }
    }
    else {
      currentScanningTime = totalScanning.get();
    }

    if (doFsActivityLogging) {
      //noinspection UseOfSystemOutOrSystemErr
      System.out.println("Scanning: " + (currentScanningTime / nsMsFactor) + "ms" +
                         ", loading: " + (totalReading.get() / nsMsFactor) + "ms for " + currentLoaders + " loaders");
    }
    return loaderData;
  }
private static @NotNull LoaderData buildData(@NotNull Path path, boolean isClassPathIndexEnabled)