/**
  * @return The last build number for snapshot version. 0 if maven-metadata not found for the path.
  */
 private int getLastBuildNumber(RepoPath repoPath) {
   int buildNumber = 0;
   try {
     // get the parent path which should contains the maven-metadata
     RepoPath parentRepoPath = repoPath.getParent();
     RepositoryService repoService = ContextHelper.get().getRepositoryService();
     RepoPathImpl mavenMetadataPath =
         new RepoPathImpl(parentRepoPath, MavenNaming.MAVEN_METADATA_NAME);
     if (repoService.exists(mavenMetadataPath)) {
       String mavenMetadataStr = repoService.getStringContent(mavenMetadataPath);
       Metadata metadata = MavenModelUtils.toMavenMetadata(mavenMetadataStr);
       Versioning versioning = metadata.getVersioning();
       if (versioning != null) {
         Snapshot snapshot = versioning.getSnapshot();
         if (snapshot != null) {
           buildNumber = snapshot.getBuildNumber();
         }
       }
     } else {
       // ok probably not found. just log
       log.debug("No maven metadata found for {}.", repoPath);
     }
   } catch (Exception e) {
     log.error("Cannot obtain build number from metadata.", e);
   }
   return buildNumber;
 }
  private static int getBuildNumber(Metadata metadata) {
    int number = 0;

    Versioning versioning = metadata.getVersioning();
    if (versioning != null) {
      Snapshot snapshot = versioning.getSnapshot();
      if (snapshot != null && snapshot.getBuildNumber() > 0) {
        number = snapshot.getBuildNumber();
      }
    }

    return number;
  }
  private boolean updateSnapshot(Metadata metadata) throws MetadataException {
    final Versioning vs = metadata.getVersioning();

    if (operand.getSnapshot() != null) {
      vs.setSnapshot(operand.getSnapshot());
    }

    List<SnapshotVersion> extras = operand.getSnapshotVersions();
    List<SnapshotVersion> currents = vs.getSnapshotVersions();

    if (extras != null && extras.size() > 0) {
      // fix/upgrade the version
      ModelVersionUtility.setModelVersion(metadata, ModelVersionUtility.LATEST_MODEL_VERSION);

      for (SnapshotVersion extra : extras) {
        SnapshotVersion current = MetadataUtil.searchForEquivalent(extra, currents);
        if (current == null) {
          currents.add(extra);
        } else {
          try {
            if (TimeUtil.compare(current.getUpdated(), extra.getUpdated()) < 0) {
              currents.remove(current);
              currents.add(extra);
            }
          } catch (ParseException e) {
            throw new MetadataException(
                "Invalid timetamp: " + current.getUpdated() + "-" + extra.getUpdated(), e);
          }
        }
      }
    } else if (Version.V100 == operand.getOriginModelVersion()) {
      for (SnapshotVersion current : currents) {
        current.setUpdated(operand.getTimestamp());
      }
    }

    vs.setLastUpdated(operand.getTimestamp());

    return true;
  }
  @Override
  protected void merge(Metadata recessive) {
    Snapshot snapshot;
    String lastUpdated;

    if (metadata.getVersioning() == null) {
      DateFormat utcDateFormatter = new SimpleDateFormat("yyyyMMdd.HHmmss");
      utcDateFormatter.setCalendar(new GregorianCalendar());
      utcDateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));

      snapshot = new Snapshot();
      snapshot.setBuildNumber(getBuildNumber(recessive) + 1);
      snapshot.setTimestamp(utcDateFormatter.format(new Date()));

      Versioning versioning = new Versioning();
      versioning.setSnapshot(snapshot);
      versioning.setLastUpdated(snapshot.getTimestamp().replace(".", ""));
      lastUpdated = versioning.getLastUpdated();

      metadata.setVersioning(versioning);
    } else {
      snapshot = metadata.getVersioning().getSnapshot();
      lastUpdated = metadata.getVersioning().getLastUpdated();
    }

    for (Artifact artifact : artifacts) {
      String version = artifact.getVersion();

      if (version.endsWith(SNAPSHOT)) {
        String qualifier = snapshot.getTimestamp() + '-' + snapshot.getBuildNumber();
        version = version.substring(0, version.length() - SNAPSHOT.length()) + qualifier;
      }

      SnapshotVersion sv = new SnapshotVersion();
      sv.setClassifier(artifact.getClassifier());
      sv.setExtension(artifact.getExtension());
      sv.setVersion(version);
      sv.setUpdated(lastUpdated);

      versions.put(getKey(sv.getClassifier(), sv.getExtension()), sv);
    }

    artifacts.clear();

    Versioning versioning = recessive.getVersioning();
    if (versioning != null) {
      for (SnapshotVersion sv : versioning.getSnapshotVersions()) {
        String key = getKey(sv.getClassifier(), sv.getExtension());
        if (!versions.containsKey(key)) {
          versions.put(key, sv);
        }
      }
    }

    if (!legacyFormat) {
      metadata.getVersioning().setSnapshotVersions(new ArrayList<>(versions.values()));
    }
  }
  @Override
  ConversionResult resolve(final Repository repository) throws LocalStorageException {
    final String requestPath = request.getRequestPath();
    try {
      final Versioning versioning =
          getVersioning(repository, metadataPath(groupArtifactPath + "/"));
      final String releaseVersion = versioning.getRelease();
      if (releaseVersion == null) {
        return new ConversionResult(requestPath);
      }

      final String selectedVersion = selectVersion(request, versioning, versionRange, false);

      final String releaseVersionDirectory = groupArtifactPath + "/" + selectedVersion + "/";

      final String pathUpToVersion =
          releaseVersionDirectory + artifactNameStart + "-" + selectedVersion;
      final String convertedPath = pathUpToVersion + artifactNameEnd;
      return new ConversionResult(requestPath, convertedPath, selectedVersion, pathUpToVersion);
    } catch (final ItemNotFoundException e) {
      return new ConversionResult(requestPath);
    }
  }