docs: @SuppressWarnings("unchecked")
      private void apply(File root, List<? extends String> classPath) throws MojoExecutionException, IOException {
          if (!root.exists()) {
              if (warnOnMissingOutputDirectory) {
                  getLog().warn("Skipping instrumentation due to missing directory: " + root);
              } else {
                  getLog().info("Skipping instrumentation due to missing directory: " + root);
              }
              return;
          } else if (!root.isDirectory()) {
              throw new MojoExecutionException("Not a directory: " + root);
          }
          ClassLoaderResolver classLoaderResolver = new ClassLoaderResolver(getLog(), repositorySystem, repositorySystemSession, remoteRepositories);
          try {
              List<Plugin.Factory> factories = new ArrayList<Plugin.Factory>(transformations.size());
              for (Transformation transformation : transformations) {
                  String plugin = transformation.getPlugin();
                  try {
                      factories.add(new Plugin.Factory.UsingReflection((Class<? extends Plugin>) Class.forName(plugin,
                              false,
                              classLoaderResolver.resolve(transformation.asCoordinate(groupId, artifactId, version, packaging))))
                              .with(transformation.makeArgumentResolvers())
                              .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(File.class, root),
                                      Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(Log.class, getLog()),
                                      Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(BuildLogger.class, new MavenBuildLogger(getLog()))));
                      getLog().info("Resolved plugin: " + transformation.getRawPlugin());
                  } catch (Throwable throwable) {
                      throw new MojoExecutionException("Cannot resolve plugin: " + transformation.getRawPlugin(), throwable);
                  }
              }
              EntryPoint entryPoint = (initialization == null
                      ? Initialization.makeDefault()
                      : initialization).getEntryPoint(classLoaderResolver, groupId, artifactId, version, packaging);
              getLog().info("Resolved entry point: " + entryPoint);
              List<ClassFileLocator> classFileLocators = new ArrayList<ClassFileLocator>(classPath.size());
              for (String target : classPath) {
                  File artifact = new File(target);
                  classFileLocators.add(artifact.isFile()
                          ? ClassFileLocator.ForJarFile.of(artifact)
                          : new ClassFileLocator.ForFolder(artifact));
              }
              ClassFileLocator classFileLocator = new ClassFileLocator.Compound(classFileLocators);
              Plugin.Engine.Summary summary;
              try {
                  getLog().info("Processing class files located in in: " + root);
                  Plugin.Engine pluginEngine;
                  try {
                      String javaVersionString = findJavaVersionString(project);
                      ClassFileVersion classFileVersion;
                      if (javaVersionString == null) {
                          classFileVersion = ClassFileVersion.ofThisVm();
                          getLog().warn("Could not locate Java target version, build is JDK dependant: " + classFileVersion.getMajorVersion());
                      } else {
                          classFileVersion = ClassFileVersion.ofJavaVersionString(javaVersionString);
                          getLog().debug("Java version detected: " + javaVersionString);
                      }
                      pluginEngine = Plugin.Engine.Default.of(entryPoint, classFileVersion, suffix == null || suffix.length() == 0
                              ? MethodNameTransformer.Suffixing.withRandomSuffix()
                              : new MethodNameTransformer.Suffixing(suffix));
                  } catch (Throwable throwable) {
                      throw new MojoExecutionException("Cannot create plugin engine", throwable);
                  }
                  try {
                      summary = pluginEngine
                              .with(extendedParsing
                                      ? Plugin.Engine.PoolStrategy.Default.EXTENDED
                                      : Plugin.Engine.PoolStrategy.Default.FAST)
                              .with(classFileLocator)
                              .with(new TransformationLogger(getLog()))
                              .withErrorHandlers(Plugin.Engine.ErrorHandler.Enforcing.ALL_TYPES_RESOLVED, failOnLiveInitializer
                                      ? Plugin.Engine.ErrorHandler.Enforcing.NO_LIVE_INITIALIZERS
                                      : Plugin.Engine.Listener.NoOp.INSTANCE, failFast
                                      ? Plugin.Engine.ErrorHandler.Failing.FAIL_FAST
                                      : Plugin.Engine.Listener.NoOp.INSTANCE)
                              .apply(new Plugin.Engine.Source.ForFolder(root), new Plugin.Engine.Target.ForFolder(root), factories);
                  } catch (Throwable throwable) {
                      throw new MojoExecutionException("Failed to transform class files in " + root, throwable);
                  }
              } finally {
                  classFileLocator.close();
              }
              if (!summary.getFailed().isEmpty()) {
                  throw new MojoExecutionException(summary.getFailed() + " type transformations have failed");
              } else if (summary.getTransformed().isEmpty()) {
                  getLog().warn("No types were transformed during plugin execution");
              } else {
                  getLog().info("Transformed " + summary.getTransformed().size() + " types");
              }
          } finally {
              classLoaderResolver.close();
          }
      }