@Nullable
  private String getLastMergedRevision(final SVNRevision rev2, final SVNURL svnURL2) {
    if (!rev2.isValid() || rev2.isLocal()) {
      return null;
    } else {
      final long number = rev2.getNumber();
      if (number > 0) {
        return String.valueOf(number);
      } else {

        SVNRepository repos = null;
        try {
          repos = myVcs.createRepository(svnURL2.toString());
          final long latestRev = repos.getLatestRevision();
          return String.valueOf(latestRev);
        } catch (SVNException e) {
          return null;
        } finally {
          if (repos != null) {
            repos.closeSession();
          }
        }
      }
    }
  }
 /** Cuts off any optional '@revisionnr' from the end of the url string. */
 public static String getUrlWithoutRevision(String remoteUrlPossiblyWithRevision) {
   int idx = remoteUrlPossiblyWithRevision.lastIndexOf('@');
   int slashIdx = remoteUrlPossiblyWithRevision.lastIndexOf('/');
   if (idx > 0 && idx > slashIdx) {
     String n = remoteUrlPossiblyWithRevision.substring(idx + 1);
     SVNRevision r = SVNRevision.parse(n);
     if ((r != null) && (r.isValid())) {
       return remoteUrlPossiblyWithRevision.substring(0, idx);
     }
   }
   return remoteUrlPossiblyWithRevision;
 }
  @Override
  public SVNRevision getRevision() {
    final SVNRevision revision = super.getRevision();
    if (revision != null && revision.isValid()) return revision;

    final SVNStatusType status = getContentsStatus();
    if (SVNStatusType.STATUS_NONE.equals(status)
        || SVNStatusType.STATUS_UNVERSIONED.equals(status)
        || SVNStatusType.STATUS_ADDED.equals(status)) return revision;

    final SVNInfo info = initInfo();
    return info == null ? revision : info.getRevision();
  }
 /**
  * Compares this object with another <b>SVNRevision</b> object.
  *
  * @param o an object to be compared with; if it's not an <b>SVNRevision</b> then this method
  *     certainly returns <span class="javakeyword">false</span>
  * @return <span class="javakeyword">true</span> if equal, otherwise <span
  *     class="javakeyword">false</span>
  */
 public boolean equals(Object o) {
   if (o == null || o.getClass() != SVNRevision.class) {
     return false;
   }
   SVNRevision r = (SVNRevision) o;
   if (myRevision >= 0) {
     return myRevision == r.getNumber();
   } else if (myDate != null) {
     return myDate.equals(r.getDate());
   } else if (myName != null) {
     return myName.equals(r.getName());
   }
   return !r.isValid();
 }
    /** validate the value for a remote (repository) location. */
    public FormValidation doCheckCredentialsId(
        StaplerRequest req,
        @AncestorInPath SCMSourceOwner context,
        @QueryParameter String remoteBase,
        @QueryParameter String value) {
      // TODO suspiciously similar to
      // SubversionSCM.ModuleLocation.DescriptorImpl.checkCredentialsId; refactor into shared
      // method?
      // Test the connection only if we may use the credentials
      if (context == null && !Jenkins.getActiveInstance().hasPermission(Jenkins.ADMINISTER)
          || context != null && !context.hasPermission(CredentialsProvider.USE_ITEM)) {
        return FormValidation.ok();
      }

      // if check remote is reporting an issue then we don't need to
      String url = Util.fixEmptyAndTrim(remoteBase);
      if (url == null) return FormValidation.ok();

      if (!URL_PATTERN.matcher(url).matches()) return FormValidation.ok();

      try {
        String urlWithoutRevision = SvnHelper.getUrlWithoutRevision(url);

        SVNURL repoURL = SVNURL.parseURIDecoded(urlWithoutRevision);

        StandardCredentials credentials =
            value == null
                ? null
                : CredentialsMatchers.firstOrNull(
                    CredentialsProvider.lookupCredentials(
                        StandardCredentials.class,
                        context,
                        ACL.SYSTEM,
                        URIRequirementBuilder.fromUri(repoURL.toString()).build()),
                    CredentialsMatchers.withId(value));
        if (checkRepositoryPath(context, repoURL, credentials) != SVNNodeKind.NONE) {
          // something exists; now check revision if any

          SVNRevision revision = getRevisionFromRemoteUrl(url);
          if (revision != null && !revision.isValid()) {
            return FormValidation.errorWithMarkup(
                hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_invalidRevision());
          }

          return FormValidation.ok();
        }

        SVNRepository repository = null;
        try {
          repository =
              getRepository(
                  context, repoURL, credentials, Collections.<String, Credentials>emptyMap(), null);
          long rev = repository.getLatestRevision();
          // now go back the tree and find if there's anything that exists
          String repoPath = getRelativePath(repoURL, repository);
          String p = repoPath;
          while (p.length() > 0) {
            p = SVNPathUtil.removeTail(p);
            if (repository.checkPath(p, rev) == SVNNodeKind.DIR) {
              // found a matching path
              List<SVNDirEntry> entries = new ArrayList<SVNDirEntry>();
              repository.getDir(p, rev, false, entries);

              // build up the name list
              List<String> paths = new ArrayList<String>();
              for (SVNDirEntry e : entries)
                if (e.getKind() == SVNNodeKind.DIR) paths.add(e.getName());

              String head = SVNPathUtil.head(repoPath.substring(p.length() + 1));
              String candidate = EditDistance.findNearest(head, paths);

              return FormValidation.error(
                  hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_badPathSuggest(
                      p, head, candidate != null ? "/" + candidate : ""));
            }
          }

          return FormValidation.error(
              hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_badPath(repoPath));
        } finally {
          if (repository != null) repository.closeSession();
        }
      } catch (SVNException e) {
        LOGGER.log(Level.INFO, "Failed to access subversion repository " + url, e);
        String message =
            hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_exceptionMsg1(
                    Util.escape(url),
                    Util.escape(e.getErrorMessage().getFullMessage()),
                    "javascript:document.getElementById('svnerror').style.display='block';"
                        + "document.getElementById('svnerrorlink').style.display='none';"
                        + "return false;")
                + "<br/><pre id=\"svnerror\" style=\"display:none\">"
                + Functions.printThrowable(e)
                + "</pre>";
        return FormValidation.errorWithMarkup(message);
      }
    }