/**
  * Check if specified checkout rules are supported
  *
  * @param root root for which rules are checked
  * @param rules rules to check
  * @throws VcsException rules are not supported
  */
 private void validateCheckoutRules(
     @NotNull final VcsRoot root, @NotNull final CheckoutRules rules) throws VcsException {
   if (rules.getExcludeRules().size() != 0) {
     throw new VcsException(
         "Exclude rules are not supported for agent checkout for the git ("
             + rules.getExcludeRules().size()
             + " rule(s) detected) for VCS Root '"
             + root.getName()
             + "'");
   }
   if (rules.getIncludeRules().size() > 1) {
     throw new VcsException(
         "At most one include rule is supported for agent checkout for the git ("
             + rules.getIncludeRules().size()
             + " rule(s) detected) for VCS Root '"
             + root.getName()
             + "'");
   }
   if (rules.getIncludeRules().size() == 1) {
     IncludeRule ir = rules.getIncludeRules().get(0);
     if (!".".equals(ir.getFrom()) && ir.getFrom().length() != 0) {
       throw new VcsException(
           "Agent checkout for the git supports only include rule of form '. => subdir', rule '"
               + ir.toDescriptiveString()
               + "' for VCS Root '"
               + root.getName()
               + "' is not supported");
     }
   }
 }
 @Nullable
 private String getSingleTargetDir(@NotNull CheckoutRules rules) {
   Set<String> targetDirs = new HashSet<String>();
   for (IncludeRule rule : rules.getRootIncludeRules()) {
     String from = rule.getFrom();
     String to = rule.getTo();
     if (from.equals("")) {
       targetDirs.add(to);
       continue;
     }
     if (from.equals(to)) {
       targetDirs.add("");
       continue;
     }
     int prefixEnd = to.lastIndexOf(from);
     if (prefixEnd == -1) // rule of form +:a=>b, but we don't support such mapping
     return null;
     String prefix = to.substring(0, prefixEnd);
     if (!prefix.endsWith("/")) // rule of form +:a=>ab, but we don't support such mapping
     return null;
     prefix = prefix.substring(0, prefix.length() - 1);
     targetDirs.add(prefix);
   }
   if (targetDirs.isEmpty()) return "";
   if (targetDirs.size() > 1) // no single target dir
   return null;
   return targetDirs.iterator().next();
 }
 public Collection<VcsClientMapping> getClientMapping(
     final @NotNull VcsRoot root, final @NotNull IncludeRule rule) throws VcsException {
   final OperationContext context = createContext(root, "client-mapping");
   try {
     GitVcsRoot gitRoot = context.getGitRoot();
     URIish uri = gitRoot.getRepositoryFetchURL();
     return Collections.singletonList(
         new VcsClientMapping(
             String.format("|%s|%s", uri.toString(), rule.getFrom()), rule.getTo()));
   } finally {
     context.close();
   }
 }