@Override
  public List<FileEntriesLayer> createLayers() throws IOException {
    // Clear the exploded-artifact root first
    if (Files.exists(targetExplodedJarRoot)) {
      MoreFiles.deleteRecursively(targetExplodedJarRoot, RecursiveDeleteOption.ALLOW_INSECURE);
    }

    try (JarFile jarFile = new JarFile(jarPath.toFile())) {
      ZipUtil.unzip(jarPath, targetExplodedJarRoot, true);
      ZipEntry layerIndex = jarFile.getEntry(BOOT_INF + "/layers.idx");
      if (layerIndex != null) {
        return createLayersForLayeredSpringBootJar(targetExplodedJarRoot);
      }

      Predicate<Path> isFile = Files::isRegularFile;

      // Non-snapshot layer
      Predicate<Path> isInBootInfLib =
          path -> path.startsWith(targetExplodedJarRoot.resolve(BOOT_INF).resolve("lib"));
      Predicate<Path> isSnapshot = path -> path.getFileName().toString().contains("SNAPSHOT");
      Predicate<Path> isInBootInfLibAndIsNotSnapshot = isInBootInfLib.and(isSnapshot.negate());
      Predicate<Path> nonSnapshotPredicate = isFile.and(isInBootInfLibAndIsNotSnapshot);
      FileEntriesLayer nonSnapshotLayer =
          ArtifactLayers.getDirectoryContentsAsLayer(
              ArtifactLayers.DEPENDENCIES,
              targetExplodedJarRoot,
              nonSnapshotPredicate,
              JarLayers.APP_ROOT);

      // Snapshot layer
      Predicate<Path> isInBootInfLibAndIsSnapshot = isInBootInfLib.and(isSnapshot);
      Predicate<Path> snapshotPredicate = isFile.and(isInBootInfLibAndIsSnapshot);
      FileEntriesLayer snapshotLayer =
          ArtifactLayers.getDirectoryContentsAsLayer(
              ArtifactLayers.SNAPSHOT_DEPENDENCIES,
              targetExplodedJarRoot,
              snapshotPredicate,
              JarLayers.APP_ROOT);

      // Spring-boot-loader layer.
      Predicate<Path> isLoader = path -> path.startsWith(targetExplodedJarRoot.resolve("org"));
      Predicate<Path> loaderPredicate = isFile.and(isLoader);
      FileEntriesLayer loaderLayer =
          ArtifactLayers.getDirectoryContentsAsLayer(
              "spring-boot-loader", targetExplodedJarRoot, loaderPredicate, JarLayers.APP_ROOT);

      // Classes layer.
      Predicate<Path> isClass = path -> path.getFileName().toString().endsWith(".class");
      Predicate<Path> isInBootInfClasses =
          path -> path.startsWith(targetExplodedJarRoot.resolve(BOOT_INF).resolve("classes"));
      Predicate<Path> classesPredicate = isInBootInfClasses.and(isClass);
      FileEntriesLayer classesLayer =
          ArtifactLayers.getDirectoryContentsAsLayer(
              ArtifactLayers.CLASSES, targetExplodedJarRoot, classesPredicate, JarLayers.APP_ROOT);

      // Resources layer.
      Predicate<Path> isInMetaInf =
          path -> path.startsWith(targetExplodedJarRoot.resolve("META-INF"));
      Predicate<Path> isResource = isInMetaInf.or(isInBootInfClasses.and(isClass.negate()));
      Predicate<Path> resourcesPredicate = isFile.and(isResource);
      FileEntriesLayer resourcesLayer =
          ArtifactLayers.getDirectoryContentsAsLayer(
              ArtifactLayers.RESOURCES,
              targetExplodedJarRoot,
              resourcesPredicate,
              JarLayers.APP_ROOT);

      return Arrays.asList(
          nonSnapshotLayer, loaderLayer, snapshotLayer, resourcesLayer, classesLayer);
    }
  }
@Test
  public void testCreateLayers_nonLayered() throws IOException, URISyntaxException {
    Path springBootJar = Paths.get(Resources.getResource(SPRING_BOOT_NOT_LAYERED).toURI());
    Path destDir = temporaryFolder.newFolder().toPath();
    SpringBootExplodedProcessor springBootExplodedModeProcessor =
        new SpringBootExplodedProcessor(springBootJar, destDir, JAR_JAVA_VERSION);

    List<FileEntriesLayer> layers = springBootExplodedModeProcessor.createLayers();

    assertThat(layers.size()).isEqualTo(5);

    FileEntriesLayer nonSnapshotLayer = layers.get(0);
    FileEntriesLayer loaderLayer = layers.get(1);
    FileEntriesLayer snapshotLayer = layers.get(2);
    FileEntriesLayer resourcesLayer = layers.get(3);
    FileEntriesLayer classesLayer = layers.get(4);

    assertThat(nonSnapshotLayer.getName()).isEqualTo("dependencies");
    assertThat(
            nonSnapshotLayer.getEntries().stream()
                .map(FileEntry::getExtractionPath)
                .collect(Collectors.toList()))
        .containsExactly(
            AbsoluteUnixPath.get("/app/BOOT-INF/lib/dependency1.jar"),
            AbsoluteUnixPath.get("/app/BOOT-INF/lib/dependency2.jar"));

    assertThat(loaderLayer.getName()).isEqualTo("spring-boot-loader");
    assertThat(
            loaderLayer.getEntries().stream()
                .map(FileEntry::getExtractionPath)
                .collect(Collectors.toList()))
        .containsExactly(
            AbsoluteUnixPath.get("/app/org/springframework/boot/loader/data/data1.class"),
            AbsoluteUnixPath.get("/app/org/springframework/boot/loader/launcher1.class"));

    assertThat(snapshotLayer.getName()).isEqualTo("snapshot dependencies");
    assertThat(snapshotLayer.getEntries().get(0).getExtractionPath())
        .isEqualTo(AbsoluteUnixPath.get("/app/BOOT-INF/lib/dependency3-SNAPSHOT.jar"));

    assertThat(resourcesLayer.getName()).isEqualTo("resources");
    assertThat(resourcesLayer.getEntries().get(0).getExtractionPath())
        .isEqualTo(AbsoluteUnixPath.get("/app/META-INF/MANIFEST.MF"));

    assertThat(classesLayer.getName()).isEqualTo("classes");
    assertThat(
            classesLayer.getEntries().stream()
                .map(FileEntry::getExtractionPath)
                .collect(Collectors.toList()))
        .containsExactly(
            AbsoluteUnixPath.get("/app/BOOT-INF/classes/class1.class"),
            AbsoluteUnixPath.get("/app/BOOT-INF/classes/classDirectory/class2.class"));
  }