[gradle] Fix Gradle resolver to respect force_version and include runtime dependencies (#1516)

The Gradle resolver was incorrectly retaining aggregating dependencies (dependencies that exist solely to group platform-specific artifacts) in the graph. This occurred because the resolver checked the POM's `packaging` field; if it was `jar` (the default) or missing, the resolver assumed a main JAR artifact must exist, even if Gradle did not resolve one.

This change updates `GradleResolver` to:
1. Remove the logic that infers artifact existence from POM packaging. Instead, it now checks strictly for the presence of non-POM files in the resolved artifacts list.
2. Refine `collapseAggregatingDependencies` to explicitly ignore `javadoc` and `sources` classifiers when determining if a node is an aggregating parent. This ensures standard libraries with documentation or sources attached are not incorrectly identified as aggregating dependencies.

* Avoid creating detached configurations which lead to incorrect versions being fetched

* Use runtime resolution, not just api

* Correctly identify aggregating dependencies by ignoring POM packaging
diff --git a/gradle.BUILD.bazel b/gradle.BUILD.bazel
index 63eee22..bfd27a1 100644
--- a/gradle.BUILD.bazel
+++ b/gradle.BUILD.bazel
@@ -14,7 +14,7 @@
     name = "gradle-runtime-jars",
     # gradle distribution brings in a incompatible version of jansi (1.x) while we use 2.x
     # so exclude it
-    jars = glob(["gradle-bin/lib/*.jar"], exclude = ["gradle-bin/lib/jansi-1.18.jar"]),
+    jars = glob(["gradle-bin/lib/*.jar", "gradle-bin/lib/plugins/*.jar"], exclude = ["gradle-bin/lib/jansi-1.18.jar"]),
     visibility = ["//visibility:public"],
 )
 
diff --git a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/BUILD.bazel b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/BUILD.bazel
index de36652..12e3650 100644
--- a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/BUILD.bazel
+++ b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/BUILD.bazel
@@ -1,4 +1,4 @@
-load("@rules_java//java:defs.bzl", "java_library")
+load("@rules_java//java:defs.bzl", "java_binary", "java_library")
 load("@rules_jvm_external//:defs.bzl", "artifact")
 
 java_library(
diff --git a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleBuildScriptGenerator.java b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleBuildScriptGenerator.java
index 7f99253..02b0eb0 100644
--- a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleBuildScriptGenerator.java
+++ b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleBuildScriptGenerator.java
@@ -170,8 +170,18 @@
                   Map<String, Object> map = new HashMap<>();
                   map.put("group", dep.getGroup());
                   map.put("artifact", dep.getArtifact());
-                  if (dep.getVersion() != null && !dep.getVersion().isEmpty()) {
-                    map.put("version", ":" + dep.getVersion());
+
+                  String version = dep.getVersion();
+                  boolean isForceVersion = version != null && version.endsWith("!!");
+                  if (isForceVersion) {
+                    // Strip the !! suffix, we'll use version { strictly() } in template
+                    version = version.substring(0, version.length() - 2);
+                    map.put("forceVersion", true);
+                    map.put("versionOnly", version); // Version without : prefix for strictly()
+                  } else {
+                      if (version != null && !version.isEmpty()) {
+                          map.put("version", ":" + version);
+                      }
                   }
                   if (dep.getClassifier() != null && !dep.getClassifier().isEmpty()) {
                     map.put("classifier", ":" + dep.getClassifier());
diff --git a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolver.java b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolver.java
index deae5c4..daa3de1 100644
--- a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolver.java
+++ b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/GradleResolver.java
@@ -593,8 +593,9 @@
                   && successor.getArtifactId().equals(node.getArtifactId())
                   && successor.getVersion().equals(node.getVersion())
                   && successor.getClassifier() != null
-                  && !successor.getClassifier().isEmpty();
-
+                  && !successor.getClassifier().isEmpty()
+                  && !"javadoc".equals(successor.getClassifier())
+                  && !"sources".equals(successor.getClassifier());
           if (!isClassifiedVariant) {
             allSuccessorsAreClassifiedVariants = false;
             break;
@@ -609,7 +610,9 @@
               && other.getArtifactId().equals(node.getArtifactId())
               && other.getVersion().equals(node.getVersion())
               && other.getClassifier() != null
-              && !other.getClassifier().isEmpty()) {
+              && !other.getClassifier().isEmpty()
+              && !"javadoc".equals(other.getClassifier())
+              && !"sources".equals(other.getClassifier())) {
             isAggregating = true;
             break;
           }
diff --git a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/data/build.gradle.hbs b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/data/build.gradle.hbs
index 41f5d1b..1023044 100644
--- a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/data/build.gradle.hbs
+++ b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/data/build.gradle.hbs
@@ -1,46 +1,62 @@
 apply plugin: 'java'
 
 repositories {
-{{#if isUsingM2Local}}
+{{~#if isUsingM2Local}}
     mavenLocal()
-{{/if}}
+{{~/if}}
 {{~#each repositories}}
     maven {
         url "{{url}}"
         allowInsecureProtocol = {{allowInsecureProtocol}}
-        {{#if requiresAuth}}
+{{~#if requiresAuth}}
         credentials {
             def u = findProperty("{{usernameProperty}}")
             if (u == null) throw new GradleException("Missing {{usernameProperty}}")
             username = u
-
             def p = findProperty("{{passwordProperty}}")
             if (p == null) throw new GradleException("Missing {{passwordProperty}}")
             password = p
         }
-        {{/if}}
+{{~/if}}
     }
-{{/each~}}
+{{~/each}}
 }
 
 dependencies {
 {{~#each boms}}
-        implementation platform("{{group}}:{{artifact}}:{{version}}")
-{{/each~}}
-
+    implementation platform("{{group}}:{{artifact}}:{{version}}")
+{{~/each}}
 {{~#each dependencies}}
-    implementation("{{group}}:{{artifact}}{{version}}{{#if classifier}}{{classifier}}{{/if}}{{#if extension}}{{extension}}{{/if}}"){{#if exclusions}} {
-        {{~#each exclusions}}
+    implementation("{{group}}:{{artifact}}{{version}}{{~#if classifier}}{{classifier}}{{~/if}}{{~#if extension}}{{extension}}{{~/if}}"){{~#if exclusions}}{{~#if forceVersion}} {
+{{~#each exclusions}}
         exclude group: "{{group}}", module: "{{module}}"
-        {{/each~}}
-    }{{/if}}
-{{/each~}}
+{{~/each}}
+        version { strictly("{{versionOnly}}") }
+    }{{~else}} {
+{{~#each exclusions}}
+        exclude group: "{{group}}", module: "{{module}}"
+{{~/each}}
+    }{{~/if}}{{~else}}{{~#if forceVersion}} {
+        version { strictly("{{versionOnly}}") }
+    }{{~/if}}{{~/if}}
+{{~/each}}
 }
 
-{{#if globalExclusions}}
 configurations.all {
-    {{~#each globalExclusions}}
+{{~#if globalExclusions}}
+{{~#each globalExclusions}}
     exclude group: "{{group}}", module: "{{module}}"
-    {{/each~}}
+{{~/each}}
+{{~/if}}
+    resolutionStrategy {
+{{~#each dependencies}}
+{{~#if forceVersion}}
+        force("{{group}}:{{artifact}}:{{versionOnly}}")
+{{~/if}}
+{{~/each}}
+        eachDependency { details ->
+{{~#each dependencies}}
+{{~/each}}
+        }
+    }
 }
-{{/if}}
diff --git a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/plugin/GradleDependencyModelBuilder.java b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/plugin/GradleDependencyModelBuilder.java
index 024fd58..e299593 100644
--- a/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/plugin/GradleDependencyModelBuilder.java
+++ b/private/tools/java/com/github/bazelbuild/rules_jvm_external/resolver/gradle/plugin/GradleDependencyModelBuilder.java
@@ -31,7 +31,6 @@
 import com.google.common.io.Files;
 import java.io.File;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -48,6 +47,10 @@
 import org.gradle.api.artifacts.component.ComponentIdentifier;
 import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
 import org.gradle.api.artifacts.component.ModuleComponentSelector;
+import org.gradle.api.artifacts.query.ArtifactResolutionQuery;
+import org.gradle.api.artifacts.result.ArtifactResolutionResult;
+import org.gradle.api.artifacts.result.ArtifactResult;
+import org.gradle.api.artifacts.result.ComponentArtifactsResult;
 import org.gradle.api.artifacts.result.ComponentSelectionReason;
 import org.gradle.api.artifacts.result.DependencyResult;
 import org.gradle.api.artifacts.result.ResolutionResult;
@@ -58,6 +61,8 @@
 import org.gradle.api.attributes.Attribute;
 import org.gradle.api.attributes.LibraryElements;
 import org.gradle.api.attributes.Usage;
+import org.gradle.maven.MavenModule;
+import org.gradle.maven.MavenPomArtifact;
 import org.gradle.tooling.provider.model.ToolingModelBuilder;
 
 /**
@@ -106,10 +111,26 @@
 
     // Create a configuration to resolve android dependencies (it can be used for other platforms
     // in the future as well like Kotlin multiplatform).
+    List<Dependency> detachedDeps = new ArrayList<>(unresolvedDependencies);
+
+    // Add all declared dependencies to the detached configuration to ensure we have
+    // all necessary BOMs/platforms and constraints available for resolution.
+    // This is critical for dependencies that rely on BOMs for versioning.
+    detachedDeps.addAll(cfg.getAllDependencies());
+
     Configuration detachedCfg =
-        project
-            .getConfigurations()
-            .detachedConfiguration(unresolvedDependencies.toArray(new Dependency[0]));
+        project.getConfigurations().detachedConfiguration(detachedDeps.toArray(new Dependency[0]));
+    // Ensure the detached configuration respects the same exclude rules as the original
+    // configuration
+    if (!cfg.getExcludeRules().isEmpty()) {
+      // Ensure excludes are applied to the detached config
+      for (org.gradle.api.artifacts.ExcludeRule rule : cfg.getExcludeRules()) {
+        detachedCfg.exclude(
+            java.util.Map.of(
+                "group", rule.getGroup(),
+                "module", rule.getModule()));
+      }
+    }
 
     // build the updated dependency graph with the detached configuration for all the
     // dependencies that we couldn't resolve with the default configuration
@@ -145,16 +166,27 @@
     for (Dependency dependency : cfg.getAllDependencies()) {
       if (dependency instanceof ModuleDependency) {
         ModuleDependency externalDependency = (ModuleDependency) dependency;
-        for (DependencyArtifact artifact : externalDependency.getArtifacts()) {
-          GradleDependency dep =
+        if (externalDependency.getArtifacts().isEmpty()) {
+          dependencies.add(
               new GradleDependencyImpl(
                   externalDependency.getGroup(),
                   externalDependency.getName(),
                   externalDependency.getVersion(),
                   null,
-                  artifact.getClassifier(),
-                  artifact.getExtension());
-          dependencies.add(dep);
+                  null,
+                  null));
+        } else {
+          for (DependencyArtifact artifact : externalDependency.getArtifacts()) {
+            GradleDependency dep =
+                new GradleDependencyImpl(
+                    externalDependency.getGroup(),
+                    externalDependency.getName(),
+                    externalDependency.getVersion(),
+                    null,
+                    artifact.getClassifier(),
+                    artifact.getExtension());
+            dependencies.add(dep);
+          }
         }
       }
     }
@@ -186,6 +218,14 @@
     for (DependencyResult dep : root.getDependencies()) {
       if (dep instanceof ResolvedDependencyResult) {
         ResolvedDependencyResult rdep = (ResolvedDependencyResult) dep;
+        if (isVerbose()) {
+          System.err.println(
+              "  RESOLVED ROOT: "
+                  + rdep.getSelected().getId()
+                  + " (from "
+                  + rdep.getRequested()
+                  + ")");
+        }
         ResolvedComponentResult selected = rdep.getSelected();
         // we don't want to recurse through a BOM's artifacts
         // as they wil be explicitly specified
@@ -219,6 +259,20 @@
         ModuleComponentSelector selector = (ModuleComponentSelector) rdep.getAttempted();
         Throwable failure = rdep.getFailure();
 
+        if (isVerbose()) {
+          System.err.println(
+              "UNRESOLVED in "
+                  + cfg.getName()
+                  + ": "
+                  + selector.getGroup()
+                  + ":"
+                  + selector.getModule()
+                  + ":"
+                  + selector.getVersion()
+                  + " Reason: "
+                  + failure);
+        }
+
         GradleUnresolvedDependency.FailureReason reason =
             GradleUnresolvedDependency.FailureReason.INTERNAL;
         // This is an internal API, so we can't check for the type
@@ -327,8 +381,7 @@
   }
 
   // The ArtifactView api doesn't provide a way to obtain the classifier (the legacy API does but it
-  // doesn't provide a way to obtain additional artifacts
-  // like javadoc/sources from what I can tell
+  // doesn't provide a way to obtain additional artifacts like javadoc/sources from what I can tell
   // so we interpolate the classifier based on the artifact file
   private String extractClassifier(File file, ComponentIdentifier id) {
     if (!(id instanceof ModuleComponentIdentifier)) {
@@ -366,7 +419,10 @@
       Map<Coordinates, GradleResolvedDependency> coordinatesMap,
       List<GradleDependency> declaredDeps) {
 
-    ArtifactView jars =
+    // Collect JAR artifacts - we need to check both JAVA_API and JAVA_RUNTIME because some
+    // libraries (like resilience4j) only publish runtime variants, while others might only
+    // have API variants. We'll collect from both and merge them.
+    ArtifactView apiJars =
         runtimeClassPathCfg
             .getIncoming()
             .artifactView(
@@ -379,8 +435,22 @@
                               project.getObjects().named(Usage.class, Usage.JAVA_API)));
                 });
 
-    // collect JAR artifacts
-    collectArtifactsFromArtifactView(jars, coordinatesMap);
+    ArtifactView runtimeJars =
+        runtimeClassPathCfg
+            .getIncoming()
+            .artifactView(
+                spec -> {
+                  spec.setLenient(true);
+                  spec.attributes(
+                      attrs ->
+                          attrs.attribute(
+                              Usage.USAGE_ATTRIBUTE,
+                              project.getObjects().named(Usage.class, Usage.JAVA_RUNTIME)));
+                });
+
+    // collect JAR artifacts from both views
+    collectArtifactsFromArtifactView(apiJars, coordinatesMap);
+    collectArtifactsFromArtifactView(runtimeJars, coordinatesMap);
 
     ArtifactView aarView =
         detachedCfg
@@ -403,10 +473,41 @@
     // Collect Android artifacts  (AARs)
     collectArtifactsFromArtifactView(aarView, coordinatesMap);
 
+    // Also collect JARs from the detached configuration, as it contains resolved versions
+    // of dependencies that failed in the main runtimeClasspath (e.g. due to missing versions
+    // provided by BOMs)
+    ArtifactView detachedApiJars =
+        detachedCfg
+            .getIncoming()
+            .artifactView(
+                spec -> {
+                  spec.setLenient(true);
+                  spec.attributes(
+                      attrs ->
+                          attrs.attribute(
+                              Usage.USAGE_ATTRIBUTE,
+                              project.getObjects().named(Usage.class, Usage.JAVA_API)));
+                });
+    ArtifactView detachedRuntimeJars =
+        detachedCfg
+            .getIncoming()
+            .artifactView(
+                spec -> {
+                  spec.setLenient(true);
+                  spec.attributes(
+                      attrs ->
+                          attrs.attribute(
+                              Usage.USAGE_ATTRIBUTE,
+                              project.getObjects().named(Usage.class, Usage.JAVA_RUNTIME)));
+                });
+    collectArtifactsFromArtifactView(detachedApiJars, coordinatesMap);
+    collectArtifactsFromArtifactView(detachedRuntimeJars, coordinatesMap);
+
     // Collect POM files explicitly as gradle doesn't fetch them unless requested
     collectPOMsForAllComponents(project, resolvedRoots, coordinatesMap, declaredDeps);
-    // Request artifacts which have conflicts so asto record them in the graph
-    collectConflictingVersionArtifacts(project, coordinatesMap);
+    // Don't collect conflicting version artifacts - we only need artifacts for the resolved graph
+    // The conflicts are tracked for reporting purposes only, we don't need to download rejected
+    // versions
   }
 
   private void collectConflictingVersionArtifacts(
@@ -415,7 +516,15 @@
     for (Map.Entry<Coordinates, GradleResolvedDependency> entry :
         coordinatesGradleResolvedDependencyMap.entrySet()) {
       GradleResolvedDependency dependency = entry.getValue();
-      if (dependency.getRequestedVersions().size() > 1) {
+      // Skip if no conflicts, or if dependency already has artifacts from main resolution
+      // (collecting via detached config would bypass resolutionStrategy and override force_version)
+      if (dependency.getRequestedVersions().size() <= 1) {
+        continue;
+      }
+      if (!dependency.getArtifacts().isEmpty()) {
+        continue; // Already has artifacts, don't re-resolve in detached config
+      }
+      {
         dependency
             .getRequestedVersions()
             .forEach(
@@ -472,8 +581,10 @@
                 module.getGroup() + ":" + module.getModule() + ":" + module.getVersion());
         GradleResolvedDependency resolvedDependency =
             coordinatesGradleResolvedDependencyMap.get(coordinates);
-        synchronized (resolvedDependency) {
-          resolvedDependency.addArtifact(resolvedArtifact);
+        if (resolvedDependency != null) {
+          synchronized (resolvedDependency) {
+            resolvedDependency.addArtifact(resolvedArtifact);
+          }
         }
       }
     }
@@ -485,22 +596,20 @@
       Map<Coordinates, GradleResolvedDependency> coordinatesResolvedDependencyMap,
       List<GradleDependency> declaredDeps) {
 
-    List<Dependency> pomDependencies = new ArrayList<>();
-    Map<Coordinates, Coordinates> moduleToRequestedCoordinates = new HashMap<>();
+    ArtifactResolutionQuery query = project.getDependencies().createArtifactResolutionQuery();
+    query.withArtifacts(MavenModule.class, MavenPomArtifact.class);
 
-    // We need to request POMs for all deps including transitive deps when we request
-    // a coordinate with explicit extension, as transitive poms aren't fetched by default
+    boolean hasItems = false;
     for (GradleResolvedDependency dependency : coordinatesResolvedDependencyMap.values()) {
-      Coordinates coordinates =
-          new Coordinates(
-              dependency.getGroup() + ":" + dependency.getName() + ":" + dependency.getVersion());
-
       boolean isDeclaredWithExplicitExtension =
           declaredDeps.stream()
               .anyMatch(
                   declaredDep ->
-                      declaredDep.getGroup().equals(dependency.getGroup())
+                      declaredDep.getGroup() != null
+                          && declaredDep.getGroup().equals(dependency.getGroup())
+                          && declaredDep.getArtifact() != null
                           && declaredDep.getArtifact().equals(dependency.getName())
+                          && declaredDep.getVersion() != null
                           && declaredDep.getVersion().equals(dependency.getVersion())
                           && declaredDep.getExtension() != null);
 
@@ -508,56 +617,43 @@
         continue;
       }
 
-      Dependency dep = project.getDependencies().create(coordinates + "@pom");
-      pomDependencies.add(dep);
-      moduleToRequestedCoordinates.put(coordinates, coordinates);
+      query.forModule(dependency.getGroup(), dependency.getName(), dependency.getVersion());
+      hasItems = true;
     }
 
-    if (pomDependencies.isEmpty()) {
+    if (!hasItems) {
       return;
     }
 
-    Configuration batchedPomCfg =
-        project
-            .getConfigurations()
-            .detachedConfiguration(pomDependencies.toArray(new Dependency[0]));
+    ArtifactResolutionResult result = query.execute();
 
-    ArtifactView view =
-        batchedPomCfg
-            .getIncoming()
-            .artifactView(
-                spec -> {
-                  spec.setLenient(true); // tolerate missing POMs
-                });
-
-    for (ResolvedArtifactResult artifact : view.getArtifacts().getArtifacts()) {
-      ComponentIdentifier id = artifact.getId().getComponentIdentifier();
+    for (ComponentArtifactsResult component : result.getResolvedComponents()) {
+      ComponentIdentifier id = component.getId();
       if (!(id instanceof ModuleComponentIdentifier)) {
         continue;
       }
-
       ModuleComponentIdentifier module = (ModuleComponentIdentifier) id;
-      Coordinates moduleCoordinates =
+      Coordinates coordinates =
           new Coordinates(module.getGroup() + ":" + module.getModule() + ":" + module.getVersion());
 
-      Coordinates requestedKey = moduleToRequestedCoordinates.get(moduleCoordinates);
-      if (requestedKey == null) {
-        continue;
-      }
-
       GradleResolvedDependency resolvedDependency =
-          coordinatesResolvedDependencyMap.get(requestedKey);
+          coordinatesResolvedDependencyMap.get(coordinates);
       if (resolvedDependency == null) {
         continue;
       }
 
-      GradleResolvedArtifact resolvedArtifact = new GradleResolvedArtifactImpl();
-      resolvedArtifact.setFile(artifact.getFile());
-      if (artifact.getFile() != null) {
-        String packaging = PomUtil.extractPackagingFromPom(artifact.getFile());
-        resolvedArtifact.setExtension(mapPackagingToExtension(packaging));
+      for (ArtifactResult artifact : component.getArtifacts(MavenPomArtifact.class)) {
+        if (artifact instanceof ResolvedArtifactResult) {
+          ResolvedArtifactResult resolvedArtifactResult = (ResolvedArtifactResult) artifact;
+          if (resolvedArtifactResult.getFile() != null) {
+            GradleResolvedArtifact resolvedArtifact = new GradleResolvedArtifactImpl();
+            resolvedArtifact.setFile(resolvedArtifactResult.getFile());
+            String packaging = PomUtil.extractPackagingFromPom(resolvedArtifactResult.getFile());
+            resolvedArtifact.setExtension(mapPackagingToExtension(packaging));
+            resolvedDependency.addArtifact(resolvedArtifact);
+          }
+        }
       }
-      resolvedDependency.addArtifact(resolvedArtifact);
     }
   }
 
diff --git a/tests/com/github/bazelbuild/rules_jvm_external/resolver/ResolverTestBase.java b/tests/com/github/bazelbuild/rules_jvm_external/resolver/ResolverTestBase.java
index 14d97a5..ce117e4 100644
--- a/tests/com/github/bazelbuild/rules_jvm_external/resolver/ResolverTestBase.java
+++ b/tests/com/github/bazelbuild/rules_jvm_external/resolver/ResolverTestBase.java
@@ -31,6 +31,7 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.graph.Graph;
+import com.google.common.hash.Hashing;
 import com.google.gson.Gson;
 import com.sun.net.httpserver.BasicAuthenticator;
 import com.sun.net.httpserver.HttpContext;
@@ -831,7 +832,7 @@
   }
 
   @Test
-  public void shouldRespectForceVersionWhenResolvingConflicts() {
+  public void shouldRespectForceVersionWhenResolvingConflicts() throws IOException {
     // When force_version is set on a lower version, it should win over the higher version
     // that would normally be selected during version conflict resolution.
     Coordinates lowerVersion = new Coordinates("com.example:forced:1.0");
@@ -857,7 +858,8 @@
 
     // Without force_version implementation, this test will fail for Gradle resolver
     // because it will resolve to the higher version (2.0) instead of the forced lower version (1.0)
-    Graph<Coordinates> graph = resolver.resolve(request).getResolution();
+    ResolutionResult result = resolver.resolve(request);
+    Graph<Coordinates> graph = result.getResolution();
 
     Set<Coordinates> forcedNodes =
         graph.nodes().stream()
@@ -869,6 +871,53 @@
     assertTrue(
         "Should resolve to forced lower version when force_version is set",
         forcedNodes.contains(lowerVersion));
+
+    // Validate that the downloaded artifact has the correct SHA for the forced version.
+    // This catches bugs where the resolver fetches artifacts via detached configurations
+    // that bypass force_version, resulting in the wrong file being downloaded.
+    Map<Coordinates, Path> paths = result.getPaths();
+    if (paths.containsKey(lowerVersion)) {
+      Path downloadedArtifact = paths.get(lowerVersion);
+      Path expectedArtifact = repo.resolve(lowerVersion.toRepoPath());
+
+      // Compare SHA256 of downloaded file vs expected file in repo
+      byte[] downloadedBytes = Files.readAllBytes(downloadedArtifact);
+      byte[] expectedBytes = Files.readAllBytes(expectedArtifact);
+      String downloadedSha = Hashing.sha256().hashBytes(downloadedBytes).toString();
+      String expectedSha = Hashing.sha256().hashBytes(expectedBytes).toString();
+
+      assertEquals(
+          "Downloaded artifact SHA should match the forced version's artifact",
+          expectedSha,
+          downloadedSha);
+    }
+  }
+
+  @Test
+  public void shouldIncludeRuntimeScopedDependencies() throws IOException {
+    // Dependencies with runtime scope should be included in the resolution graph.
+    // This tests that the resolver uses runtime classpath, not just compile/api classpath.
+    Coordinates main = new Coordinates("com.example:main:1.0");
+    Coordinates runtimeDep = new Coordinates("com.example:runtime-only:1.0");
+
+    // Create a POM where main depends on runtime-only with runtime scope
+    Model mainModel = createModel(main);
+    Dependency dep = new Dependency();
+    dep.setGroupId(runtimeDep.getGroupId());
+    dep.setArtifactId(runtimeDep.getArtifactId());
+    dep.setVersion(runtimeDep.getVersion());
+    dep.setScope("runtime");
+    mainModel.addDependency(dep);
+
+    Path repo = MavenRepo.create().add(runtimeDep).add(mainModel, main).getPath();
+
+    Graph<Coordinates> resolved =
+        resolver.resolve(prepareRequestFor(repo.toUri(), main)).getResolution();
+
+    assertTrue(
+        "Runtime-scoped dependency should be included in resolution",
+        resolved.nodes().contains(runtimeDep));
+    assertTrue("Main artifact should be in resolution", resolved.nodes().contains(main));
   }
 
   protected ResolutionRequest prepareRequestFor(URI repo, Coordinates... coordinates) {
diff --git a/tests/custom_maven_install/regression_testing_gradle_index.json b/tests/custom_maven_install/regression_testing_gradle_index.json
index b3a634f..6c4961a 100644
--- a/tests/custom_maven_install/regression_testing_gradle_index.json
+++ b/tests/custom_maven_install/regression_testing_gradle_index.json
@@ -8,12 +8,12 @@
       "androidx.arch.core.internal",
       "androidx.arch.core.util"
     ],
-    "androidx.collection:collection": [
-      "androidx.collection"
-    ],
     "androidx.concurrent:concurrent-futures": [
       "androidx.concurrent.futures"
     ],
+    "androidx.lifecycle:lifecycle-common": [
+      "androidx.lifecycle"
+    ],
     "ch.qos.reload4j:reload4j": [
       "org.apache.log4j",
       "org.apache.log4j.chainsaw",
@@ -34,6 +34,9 @@
       "com.almworks.sqlite4java",
       "javolution.util.stripped"
     ],
+    "com.google.guava:listenablefuture": [
+      "com.google.common.util.concurrent"
+    ],
     "com.squareup.okhttp3:okhttp": [
       "okhttp3",
       "okhttp3.internal",
@@ -132,6 +135,30 @@
       "org.slf4j.reload4j"
     ]
   },
-  "split_package_classes": {},
+  "split_package_classes": {
+    "androidx.collection:collection": {
+      "androidx.collection": [
+        "ArrayMap",
+        "ArraySet",
+        "CircularArray",
+        "CircularIntArray",
+        "ContainerHelpers",
+        "LongSparseArray",
+        "LruCache",
+        "MapCollections",
+        "SimpleArrayMap",
+        "SparseArrayCompat"
+      ]
+    },
+    "androidx.collection:collection-ktx": {
+      "androidx.collection": [
+        "ArrayMapKt",
+        "ArraySetKt",
+        "LongSparseArrayKt",
+        "LruCacheKt",
+        "SparseArrayKt"
+      ]
+    }
+  },
   "version": 1
 }
diff --git a/tests/custom_maven_install/regression_testing_gradle_install.json b/tests/custom_maven_install/regression_testing_gradle_install.json
index 9ea4234..dbce79a 100644
--- a/tests/custom_maven_install/regression_testing_gradle_install.json
+++ b/tests/custom_maven_install/regression_testing_gradle_install.json
@@ -1,7 +1,7 @@
 {
   "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
   "__INPUT_ARTIFACTS_HASH": 1541018928,
-  "__RESOLVED_ARTIFACTS_HASH": 1117928925,
+  "__RESOLVED_ARTIFACTS_HASH": -212064862,
   "artifacts": {
     "androidx.activity:activity-ktx:aar": {
       "shasums": {
@@ -17,7 +17,7 @@
     },
     "androidx.annotation:annotation": {
       "shasums": {
-        "jar": "fbc64f5c44a7added8b6eab517cf7d70555e25153bf5d44a6ed9b0e5312f7de9"
+        "jar": "dd882b4c1945ad13121ecdf651eba664a9b226b55db84fa755392de5e10d1e5b"
       },
       "version": "1.6.0"
     },
@@ -53,13 +53,13 @@
     },
     "androidx.collection:collection": {
       "shasums": {
-        "jar": "9c8d117b5c2bc120a1cdfeb857e05b495b16c36013570372a708f7827e3ac9f9"
+        "jar": "632a0e5407461de774409352940e292a291037724207a787820c77daf7d33b72"
       },
-      "version": "1.0.0"
+      "version": "1.1.0"
     },
     "androidx.collection:collection-ktx": {
       "shasums": {
-        "jar": "721e76e74ee4158d3fe9759074b7eceed4ff7d84ed34a3faca5843fb874ac946"
+        "jar": "2bfc54475c047131913361f56d0f7f019c6e5bee53eeb0eb7d94a7c499a05227"
       },
       "version": "1.1.0"
     },
@@ -83,7 +83,7 @@
     },
     "androidx.compose.runtime:runtime": {
       "shasums": {
-        "jar": "1dd30ce8cca076140ed92ee748c1d35a4ac46b9da435406e353208a07267996d"
+        "jar": "b72dfdbb22399d36dacdfa96710f6c7dbf885123a63dc714c55e3b3836d684bb"
       },
       "version": "1.5.0-beta01"
     },
@@ -105,18 +105,6 @@
       },
       "version": "1.5.0-beta01"
     },
-    "androidx.compose.runtime:runtime-saveable:aar": {
-      "shasums": {
-        "jar": "b3bcd143e3cc60a121bd7eeeddceb1bbef6837867ce125f6843b1d73a137873d"
-      },
-      "version": "1.2.1"
-    },
-    "androidx.compose.runtime:runtime:aar": {
-      "shasums": {
-        "jar": "757cc64ccc3f75bb637f55b148ac60d00e8e035555cd5917b5871bb5934da649"
-      },
-      "version": "1.2.1"
-    },
     "androidx.compose.ui:ui": {
       "shasums": {
         "jar": "4e923a7b886a27d27fbcfa4eae33602ae6a719651371f656d923407046b31704"
@@ -141,12 +129,6 @@
       },
       "version": "1.5.0-beta01"
     },
-    "androidx.compose.ui:ui-geometry:aar": {
-      "shasums": {
-        "jar": "4a74924bd00b45cceb3f131b69e2e3c3c7106151767f2d166a1242715832c74b"
-      },
-      "version": "1.2.1"
-    },
     "androidx.compose.ui:ui-graphics": {
       "shasums": {
         "jar": "a72f34b560d1401dd3e9d3334d642e512314deedceebe30b223e015d923d25d3"
@@ -159,12 +141,6 @@
       },
       "version": "1.5.0-beta01"
     },
-    "androidx.compose.ui:ui-graphics:aar": {
-      "shasums": {
-        "jar": "d45cbc93e36933fb6a054887c0747a9f5cc5f6a536c678e3baa6b055d476010a"
-      },
-      "version": "1.2.1"
-    },
     "androidx.compose.ui:ui-text": {
       "shasums": {
         "jar": "f3abaefaefe83b1bc9b3b3351a0de57904495dbf9c55b872aa5e25f125befb2e"
@@ -177,12 +153,6 @@
       },
       "version": "1.5.0-beta01"
     },
-    "androidx.compose.ui:ui-text:aar": {
-      "shasums": {
-        "jar": "924bfcce2e62a14577babac4fd1b03750792ce5faa0d741e6cc185bc0b13b215"
-      },
-      "version": "1.2.1"
-    },
     "androidx.compose.ui:ui-unit": {
       "shasums": {
         "jar": "e6ae55913d92a1456a171caf65879ed890b30f2d32143dd8068c296a623017a2"
@@ -195,12 +165,6 @@
       },
       "version": "1.5.0-beta01"
     },
-    "androidx.compose.ui:ui-unit:aar": {
-      "shasums": {
-        "jar": "74da0a1fc6db7500e57b301c8a63d64105844ce029ee48c54253bfd132c6a5bb"
-      },
-      "version": "1.2.1"
-    },
     "androidx.compose.ui:ui-util": {
       "shasums": {
         "jar": "00d8f7cc0d5dce370b83e3a14cd468fa444fcb6b91ab0878117a2c3c82e9e0a1"
@@ -213,18 +177,6 @@
       },
       "version": "1.5.0-beta01"
     },
-    "androidx.compose.ui:ui-util:aar": {
-      "shasums": {
-        "jar": "e514b90356bc6aaf456de009d434f225494b788fab6a3681b6c3642c2e9257fa"
-      },
-      "version": "1.2.1"
-    },
-    "androidx.compose.ui:ui:aar": {
-      "shasums": {
-        "jar": "a6a91c7898c48d05ec1bcd8a7c4e1f54cbd094ac37e1d1a1387a04a8030acd36"
-      },
-      "version": "1.2.1"
-    },
     "androidx.concurrent:concurrent-futures": {
       "shasums": {
         "jar": "0ce067c514a0d1049d1bebdf709e344ed3266fe9744275682937cdcb13334e9e"
@@ -251,7 +203,7 @@
     },
     "androidx.customview:customview:aar": {
       "shasums": {
-        "jar": "ce9e47b87184f5bd5e139e9becd5b26476d42d78c31bf2fdedc37acb41b9ad49"
+        "jar": "20e5b8f6526a34595a604f56718da81167c0b40a7a94a57daa355663f2594df2"
       },
       "version": "1.0.0"
     },
@@ -275,19 +227,13 @@
     },
     "androidx.interpolator:interpolator:aar": {
       "shasums": {
-        "jar": "0ddc07cc39699f48ecd9ec894b5830c0f09e22e82959294edf37217224c88b7b"
+        "jar": "33193135a64fe21fa2c35eec6688f1a76e512606c0fc83dc1b689e37add7732a"
       },
       "version": "1.0.0"
     },
     "androidx.lifecycle:lifecycle-common": {
       "shasums": {
-        "jar": "3e66830d59fae52e1030b4be724b1e577ac814d27335fdf81a71283dc0829f1a"
-      },
-      "version": "2.6.1"
-    },
-    "androidx.lifecycle:lifecycle-common-java8": {
-      "shasums": {
-        "jar": "c6deada2fac53b8ea6523dbda77597b128006674616f140f04df23264c6d1aa3"
+        "jar": "f34831b6c71cd844e1d35d1be49d5e79447c5ab856346531b1e8676fda7374b1"
       },
       "version": "2.6.1"
     },
@@ -305,7 +251,7 @@
     },
     "androidx.lifecycle:lifecycle-livedata:aar": {
       "shasums": {
-        "jar": "33c731db91a120ad6eae8f0da72f094017bc3862e3677dbf588af17896a924a9"
+        "jar": "67359f609dfc2bf65da1270b23033f856064ec279f058e0a70c715f7c9003031"
       },
       "version": "2.6.1"
     },
@@ -347,7 +293,7 @@
     },
     "androidx.loader:loader:aar": {
       "shasums": {
-        "jar": "c978d550808b47434aa49a63164110a50b55b0bcc6160a93a2e37d5110df8c5e"
+        "jar": "11f735cb3b55c458d470bed9e25254375b518b4b1bad6926783a7026db0f5025"
       },
       "version": "1.0.0"
     },
@@ -383,13 +329,13 @@
     },
     "androidx.versionedparcelable:versionedparcelable:aar": {
       "shasums": {
-        "jar": "5f51e65873ca612de3838fa90d2ee95b8d040efd31b9c390a19bf94d615cdb2f"
+        "jar": "57e8d93260d18d5b9007c9eed3c64ad159de90c8609ebfc74a347cbd514535a4"
       },
       "version": "1.1.1"
     },
     "androidx.viewpager:viewpager:aar": {
       "shasums": {
-        "jar": "1f72f836339d03c6eb013f65075e76ca87075a577578eb4f95f74a3a5d253128"
+        "jar": "147af4e14a1984010d8f155e5e19d781f03c1d70dfed02a8e0d18428b8fc8682"
       },
       "version": "1.0.0"
     },
@@ -413,7 +359,7 @@
     },
     "com.google.guava:listenablefuture": {
       "shasums": {
-        "jar": "53873caf26bc1ed8a567ea6c939ab2aaa3f47a5e32d5cade95ddf5080d23238a"
+        "jar": "e4ad7607e5c0477c6f890ef26a49cb8d1bb4dffb650bab4502afee64644e3069"
       },
       "version": "1.0"
     },
@@ -473,7 +419,7 @@
     },
     "org.jetbrains.kotlinx:kotlinx-coroutines-core": {
       "shasums": {
-        "jar": "778851e73851b502e8366434bc9ec58371431890fb12b89e7edbf1732962c030"
+        "jar": "136b4edb87a47e15251f0842f3189fa31979eb4ab51acfb4239b4bf8d16d4588"
       },
       "version": "1.6.4"
     },
@@ -509,25 +455,20 @@
     "androidx.arch.core:core-runtime:aar:2.1.0": "androidx.arch.core:core-runtime:aar:2.2.0",
     "androidx.collection:collection:1.0.0": "androidx.collection:collection:1.1.0",
     "androidx.compose.runtime:runtime:1.2.1": "androidx.compose.runtime:runtime:1.5.0-beta01",
-    "androidx.compose.runtime:runtime:aar:1.1.1": "androidx.compose.runtime:runtime:aar:1.2.1",
-    "androidx.compose.ui:ui-unit:aar:1.0.0": "androidx.compose.ui:ui-unit:aar:1.2.1",
-    "androidx.compose.ui:ui-util:aar:1.0.0": "androidx.compose.ui:ui-util:aar:1.2.1",
+    "androidx.compose.ui:ui-unit:1.0.0": "androidx.compose.ui:ui-unit:1.5.0-beta01",
+    "androidx.compose.ui:ui-util:1.0.0": "androidx.compose.ui:ui-util:1.5.0-beta01",
+    "androidx.compose.ui:ui:1.2.1": "androidx.compose.ui:ui:1.5.0-beta01",
     "androidx.concurrent:concurrent-futures:1.0.0": "androidx.concurrent:concurrent-futures:1.1.0",
     "androidx.core:core-ktx:aar:1.5.0": "androidx.core:core-ktx:aar:1.11.0-beta01",
     "androidx.core:core:aar:1.3.0": "androidx.core:core:aar:1.11.0-beta01",
-    "androidx.lifecycle:lifecycle-common-java8:2.3.0": "androidx.lifecycle:lifecycle-common-java8:2.6.1",
     "androidx.lifecycle:lifecycle-livedata:aar:2.0.0": "androidx.lifecycle:lifecycle-livedata:aar:2.6.1",
     "androidx.lifecycle:lifecycle-process:aar:2.4.1": "androidx.lifecycle:lifecycle-process:aar:2.6.1",
     "androidx.lifecycle:lifecycle-runtime:aar:2.3.1": "androidx.lifecycle:lifecycle-runtime:aar:2.6.1",
     "androidx.lifecycle:lifecycle-viewmodel:aar:2.0.0": "androidx.lifecycle:lifecycle-viewmodel:aar:2.6.1",
-    "androidx.profileinstaller:profileinstaller:aar:1.2.0": "androidx.profileinstaller:profileinstaller:aar:1.3.0",
-    "androidx.savedstate:savedstate-ktx:aar:1.2.0": "androidx.savedstate:savedstate-ktx:aar:1.2.1",
     "androidx.startup:startup-runtime:aar:1.0.0": "androidx.startup:startup-runtime:aar:1.1.1",
-    "org.jetbrains.kotlin:kotlin-stdlib-common:1.6.21": "org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21",
     "org.jetbrains.kotlin:kotlin-stdlib-common:1.8.21": "org.jetbrains.kotlin:kotlin-stdlib-common:1.9.10",
     "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.21": "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10",
     "org.jetbrains.kotlin:kotlin-stdlib:1.8.0": "org.jetbrains.kotlin:kotlin-stdlib:1.9.10",
-    "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1": "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4",
     "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1": "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4"
   },
   "dependencies": {
@@ -579,10 +520,10 @@
     ],
     "androidx.compose.animation:animation-core:aar": [
       "androidx.annotation:annotation",
-      "androidx.compose.runtime:runtime:aar",
-      "androidx.compose.ui:ui-unit:aar",
-      "androidx.compose.ui:ui-util:aar",
-      "androidx.compose.ui:ui:aar",
+      "androidx.compose.runtime:runtime",
+      "androidx.compose.ui:ui",
+      "androidx.compose.ui:ui-unit",
+      "androidx.compose.ui:ui-util",
       "org.jetbrains.kotlin:kotlin-stdlib",
       "org.jetbrains.kotlinx:kotlinx-coroutines-core"
     ],
@@ -591,9 +532,11 @@
     ],
     "androidx.compose.foundation:foundation-layout-android:aar": [
       "androidx.annotation:annotation",
+      "androidx.compose.animation:animation-core:aar",
       "androidx.compose.runtime:runtime",
       "androidx.compose.ui:ui",
       "androidx.compose.ui:ui-util",
+      "androidx.core:core:aar",
       "org.jetbrains.kotlin:kotlin-stdlib-common"
     ],
     "androidx.compose.runtime:runtime": [
@@ -602,6 +545,7 @@
     "androidx.compose.runtime:runtime-android:aar": [
       "androidx.annotation:annotation",
       "org.jetbrains.kotlin:kotlin-stdlib",
+      "org.jetbrains.kotlin:kotlin-stdlib-common",
       "org.jetbrains.kotlinx:kotlinx-coroutines-android",
       "org.jetbrains.kotlinx:kotlinx-coroutines-core"
     ],
@@ -613,20 +557,11 @@
       "androidx.compose.runtime:runtime",
       "org.jetbrains.kotlin:kotlin-stdlib"
     ],
-    "androidx.compose.runtime:runtime-saveable:aar": [
-      "androidx.annotation:annotation",
-      "androidx.compose.runtime:runtime:aar",
-      "org.jetbrains.kotlin:kotlin-stdlib"
-    ],
-    "androidx.compose.runtime:runtime:aar": [
-      "androidx.annotation:annotation",
-      "org.jetbrains.kotlin:kotlin-stdlib",
-      "org.jetbrains.kotlinx:kotlinx-coroutines-android"
-    ],
     "androidx.compose.ui:ui": [
       "androidx.compose.ui:ui-android:aar"
     ],
     "androidx.compose.ui:ui-android:aar": [
+      "androidx.activity:activity-ktx:aar",
       "androidx.annotation:annotation",
       "androidx.autofill:autofill:aar",
       "androidx.collection:collection",
@@ -637,7 +572,15 @@
       "androidx.compose.ui:ui-text",
       "androidx.compose.ui:ui-unit",
       "androidx.compose.ui:ui-util",
+      "androidx.core:core:aar",
+      "androidx.customview:customview-poolingcontainer:aar",
+      "androidx.emoji2:emoji2:aar",
+      "androidx.lifecycle:lifecycle-runtime:aar",
+      "androidx.lifecycle:lifecycle-viewmodel:aar",
+      "androidx.profileinstaller:profileinstaller:aar",
+      "androidx.savedstate:savedstate-ktx:aar",
       "org.jetbrains.kotlin:kotlin-stdlib",
+      "org.jetbrains.kotlin:kotlin-stdlib-common",
       "org.jetbrains.kotlinx:kotlinx-coroutines-android",
       "org.jetbrains.kotlinx:kotlinx-coroutines-core"
     ],
@@ -650,12 +593,6 @@
       "androidx.compose.ui:ui-util",
       "org.jetbrains.kotlin:kotlin-stdlib"
     ],
-    "androidx.compose.ui:ui-geometry:aar": [
-      "androidx.annotation:annotation",
-      "androidx.compose.runtime:runtime:aar",
-      "androidx.compose.ui:ui-util:aar",
-      "org.jetbrains.kotlin:kotlin-stdlib"
-    ],
     "androidx.compose.ui:ui-graphics": [
       "androidx.compose.ui:ui-graphics-android:aar"
     ],
@@ -665,13 +602,6 @@
       "androidx.compose.ui:ui-unit",
       "androidx.compose.ui:ui-util"
     ],
-    "androidx.compose.ui:ui-graphics:aar": [
-      "androidx.annotation:annotation",
-      "androidx.compose.runtime:runtime:aar",
-      "androidx.compose.ui:ui-unit:aar",
-      "androidx.compose.ui:ui-util:aar",
-      "org.jetbrains.kotlin:kotlin-stdlib-common"
-    ],
     "androidx.compose.ui:ui-text": [
       "androidx.compose.ui:ui-text-android:aar"
     ],
@@ -683,20 +613,9 @@
       "androidx.compose.ui:ui-graphics",
       "androidx.compose.ui:ui-unit",
       "androidx.compose.ui:ui-util",
-      "org.jetbrains.kotlin:kotlin-stdlib",
-      "org.jetbrains.kotlinx:kotlinx-coroutines-core"
-    ],
-    "androidx.compose.ui:ui-text:aar": [
-      "androidx.annotation:annotation",
-      "androidx.collection:collection",
-      "androidx.compose.runtime:runtime-saveable:aar",
-      "androidx.compose.runtime:runtime:aar",
-      "androidx.compose.ui:ui-graphics:aar",
-      "androidx.compose.ui:ui-unit:aar",
-      "androidx.compose.ui:ui-util:aar",
       "androidx.core:core:aar",
+      "androidx.emoji2:emoji2:aar",
       "org.jetbrains.kotlin:kotlin-stdlib",
-      "org.jetbrains.kotlin:kotlin-stdlib-common",
       "org.jetbrains.kotlinx:kotlinx-coroutines-core"
     ],
     "androidx.compose.ui:ui-unit": [
@@ -707,46 +626,15 @@
       "androidx.compose.runtime:runtime",
       "androidx.compose.ui:ui-geometry",
       "androidx.compose.ui:ui-util",
-      "org.jetbrains.kotlin:kotlin-stdlib"
-    ],
-    "androidx.compose.ui:ui-unit:aar": [
-      "androidx.annotation:annotation",
-      "androidx.compose.runtime:runtime:aar",
-      "androidx.compose.ui:ui-geometry:aar",
-      "androidx.compose.ui:ui-util:aar",
-      "org.jetbrains.kotlin:kotlin-stdlib"
+      "org.jetbrains.kotlin:kotlin-stdlib",
+      "org.jetbrains.kotlin:kotlin-stdlib-common"
     ],
     "androidx.compose.ui:ui-util": [
       "androidx.compose.ui:ui-util-android:aar"
     ],
     "androidx.compose.ui:ui-util-android:aar": [
-      "org.jetbrains.kotlin:kotlin-stdlib"
-    ],
-    "androidx.compose.ui:ui-util:aar": [
-      "org.jetbrains.kotlin:kotlin-stdlib"
-    ],
-    "androidx.compose.ui:ui:aar": [
-      "androidx.annotation:annotation",
-      "androidx.autofill:autofill:aar",
-      "androidx.collection:collection",
-      "androidx.compose.runtime:runtime-saveable:aar",
-      "androidx.compose.runtime:runtime:aar",
-      "androidx.compose.ui:ui-geometry:aar",
-      "androidx.compose.ui:ui-graphics:aar",
-      "androidx.compose.ui:ui-text:aar",
-      "androidx.compose.ui:ui-unit:aar",
-      "androidx.compose.ui:ui-util:aar",
-      "androidx.core:core:aar",
-      "androidx.customview:customview-poolingcontainer:aar",
-      "androidx.lifecycle:lifecycle-common-java8",
-      "androidx.lifecycle:lifecycle-runtime:aar",
-      "androidx.lifecycle:lifecycle-viewmodel:aar",
-      "androidx.profileinstaller:profileinstaller:aar",
-      "androidx.savedstate:savedstate-ktx:aar",
       "org.jetbrains.kotlin:kotlin-stdlib",
-      "org.jetbrains.kotlin:kotlin-stdlib-common",
-      "org.jetbrains.kotlinx:kotlinx-coroutines-android",
-      "org.jetbrains.kotlinx:kotlinx-coroutines-core"
+      "org.jetbrains.kotlin:kotlin-stdlib-common"
     ],
     "androidx.concurrent:concurrent-futures": [
       "androidx.annotation:annotation",
@@ -815,10 +703,6 @@
       "org.jetbrains.kotlin:kotlin-stdlib",
       "org.jetbrains.kotlinx:kotlinx-coroutines-android"
     ],
-    "androidx.lifecycle:lifecycle-common-java8": [
-      "androidx.annotation:annotation",
-      "androidx.lifecycle:lifecycle-common"
-    ],
     "androidx.lifecycle:lifecycle-livedata-core-ktx:aar": [
       "androidx.lifecycle:lifecycle-livedata-core:aar",
       "org.jetbrains.kotlin:kotlin-stdlib"
@@ -937,6 +821,7 @@
       "org.jetbrains.kotlin:kotlin-stdlib-jdk7"
     ],
     "org.jetbrains.kotlinx:kotlinx-coroutines-android": [
+      "org.jetbrains.kotlin:kotlin-stdlib-jdk8",
       "org.jetbrains.kotlinx:kotlinx-coroutines-bom",
       "org.jetbrains.kotlinx:kotlinx-coroutines-core"
     ],
@@ -944,7 +829,7 @@
       "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm"
     ],
     "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm": [
-      "org.jetbrains.kotlin:kotlin-stdlib-common",
+      "org.jetbrains.kotlin:kotlin-stdlib-jdk8",
       "org.jetbrains.kotlinx:kotlinx-coroutines-bom"
     ],
     "org.slf4j:slf4j-reload4j": [
@@ -991,26 +876,18 @@
       "androidx.compose.runtime:runtime-android:aar",
       "androidx.compose.runtime:runtime-saveable",
       "androidx.compose.runtime:runtime-saveable-android:aar",
-      "androidx.compose.runtime:runtime-saveable:aar",
-      "androidx.compose.runtime:runtime:aar",
       "androidx.compose.ui:ui",
       "androidx.compose.ui:ui-android:aar",
       "androidx.compose.ui:ui-geometry",
       "androidx.compose.ui:ui-geometry-android:aar",
-      "androidx.compose.ui:ui-geometry:aar",
       "androidx.compose.ui:ui-graphics",
       "androidx.compose.ui:ui-graphics-android:aar",
-      "androidx.compose.ui:ui-graphics:aar",
       "androidx.compose.ui:ui-text",
       "androidx.compose.ui:ui-text-android:aar",
-      "androidx.compose.ui:ui-text:aar",
       "androidx.compose.ui:ui-unit",
       "androidx.compose.ui:ui-unit-android:aar",
-      "androidx.compose.ui:ui-unit:aar",
       "androidx.compose.ui:ui-util",
       "androidx.compose.ui:ui-util-android:aar",
-      "androidx.compose.ui:ui-util:aar",
-      "androidx.compose.ui:ui:aar",
       "androidx.concurrent:concurrent-futures",
       "androidx.core:core-ktx:aar",
       "androidx.core:core:aar",
@@ -1021,7 +898,6 @@
       "androidx.fragment:fragment:aar",
       "androidx.interpolator:interpolator:aar",
       "androidx.lifecycle:lifecycle-common",
-      "androidx.lifecycle:lifecycle-common-java8",
       "androidx.lifecycle:lifecycle-livedata-core-ktx:aar",
       "androidx.lifecycle:lifecycle-livedata-core:aar",
       "androidx.lifecycle:lifecycle-livedata:aar",