class LinkageMonitor {

  @VisibleForTesting
  static Model buildModelWithSnapshotBom(
      RepositorySystem repositorySystem,
      RepositorySystemSession session,
      String bomCoordinates,
      Map<String, String> localArtifacts)
      throws ModelBuildingException, ArtifactResolutionException {

    // BOM Coordinates might not have extension.
    String[] elements = bomCoordinates.split(":");
    DefaultArtifact bom;
    if (elements.length >= 4) {
      bom = new DefaultArtifact(bomCoordinates); // This may throw InvalidArgumentException
    } else if (elements.length == 3) {
      // When extension is not specified, use "pom"
      bom = new DefaultArtifact(elements[0], elements[1], "pom", elements[2]);
    } else {
      throw new IllegalArgumentException(
          "BOM coordinates do not have valid format: " + bomCoordinates);
    }

    ArtifactResult bomResult =
        repositorySystem.resolveArtifact(
            session, new ArtifactRequest(bom, ImmutableList.of(CENTRAL), null));

    ModelBuildingRequest modelRequest = new DefaultModelBuildingRequest();
    modelRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
    modelRequest.setProcessPlugins(false);
    modelRequest.setTwoPhaseBuilding(true); // This forces the builder stop after phase 1
    modelRequest.setPomFile(bomResult.getArtifact().getFile());
    modelRequest.setModelResolver(
        new VersionSubstitutingModelResolver(
            session,
            null,
            repositorySystem,
            new DefaultRemoteRepositoryManager(),
            ImmutableList.of(CENTRAL), // Needed when parent pom is not locally available
            localArtifacts));
    // Profile activation needs JDK version through system properties
    // https://github.com/GoogleCloudPlatform/cloud-opensource-java/issues/923
    modelRequest.setSystemProperties(System.getProperties());

    // Phase 1 done. Now variables are interpolated.
    ModelBuildingResult resultPhase1 = modelBuilder.build(modelRequest);
    DependencyManagement dependencyManagement =
        resultPhase1.getEffectiveModel().getDependencyManagement();

    for (org.apache.maven.model.Dependency dependency : dependencyManagement.getDependencies()) {
      // Replaces the versions of imported BOMs
      if ("import".equals(dependency.getScope())) {
        String version =
            localArtifacts.getOrDefault(
                dependency.getGroupId() + ":" + dependency.getArtifactId(),
                dependency.getVersion());
        dependency.setVersion(version);
      }
    }

    // Phase 2 resolves dependency management imports
    ModelBuildingResult resultPhase2 = modelBuilder.build(modelRequest, resultPhase1);
    return resultPhase2.getEffectiveModel();
  }

}