docs: protected boolean doMatch(String pattern, String path, boolean fullMatch, Map<String, String> uriTemplateVariables) {
  
          if (path.startsWith(pathSeparator) != pattern.startsWith(pathSeparator)) {
              return false;
          }
  
          String[] pattDirs = tokenize(pattern);
          String[] pathDirs = tokenize(path);
  
          int pattIdxStart = 0;
          int pattIdxEnd = pattDirs.length - 1;
          int pathIdxStart = 0;
          int pathIdxEnd = pathDirs.length - 1;
  
          // Match all elements up to the first **
          while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) {
              String patDir = pattDirs[pattIdxStart];
              if ("**".equals(patDir)) {
                  break;
              }
              if (!matchStrings(patDir, pathDirs[pathIdxStart], uriTemplateVariables)) {
                  return false;
              }
              pattIdxStart++;
              pathIdxStart++;
          }
  
          if (pathIdxStart > pathIdxEnd) {
              // Path is exhausted, only match if rest of pattern is * or **'s
              if (pattIdxStart > pattIdxEnd) {
                  return (pattern.endsWith(pathSeparator) ? path.endsWith(pathSeparator) :
                      !path.endsWith(pathSeparator));
              }
              if (!fullMatch) {
                  return true;
              }
              if (pattIdxStart == pattIdxEnd && pattDirs[pattIdxStart].equals("*") && path.endsWith(pathSeparator)) {
                  return true;
              }
              for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
                  if (!pattDirs[i].equals("**")) {
                      return false;
                  }
              }
              return true;
          } else if (pattIdxStart > pattIdxEnd) {
              // String not exhausted, but pattern is. Failure.
              return false;
          } else if (!fullMatch && "**".equals(pattDirs[pattIdxStart])) {
              // Path start definitely matches due to "**" part in pattern.
              return true;
          }
  
          // up to last '**'
          while (pattIdxStart <= pattIdxEnd && pathIdxStart <= pathIdxEnd) {
              String patDir = pattDirs[pattIdxEnd];
              if (patDir.equals("**")) {
                  break;
              }
              if (!matchStrings(patDir, pathDirs[pathIdxEnd], uriTemplateVariables)) {
                  return false;
              }
              pattIdxEnd--;
              pathIdxEnd--;
          }
          if (pathIdxStart > pathIdxEnd) {
              // String is exhausted
              for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
                  if (!pattDirs[i].equals("**")) {
                      return false;
                  }
              }
              return true;
          }
  
          while (pattIdxStart != pattIdxEnd && pathIdxStart <= pathIdxEnd) {
              int patIdxTmp = -1;
              for (int i = pattIdxStart + 1; i <= pattIdxEnd; i++) {
                  if (pattDirs[i].equals("**")) {
                      patIdxTmp = i;
                      break;
                  }
              }
              if (patIdxTmp == pattIdxStart + 1) {
                  // '**/**' situation, so skip one
                  pattIdxStart++;
                  continue;
              }
              // Find the pattern between padIdxStart & padIdxTmp in str between
              // strIdxStart & strIdxEnd
              int patLength = (patIdxTmp - pattIdxStart - 1);
              int strLength = (pathIdxEnd - pathIdxStart + 1);
              int foundIdx = -1;
  
              strLoop:
              for (int i = 0; i <= strLength - patLength; i++) {
                  for (int j = 0; j < patLength; j++) {
                      String subPat = pattDirs[pattIdxStart + j + 1];
                      String subStr = pathDirs[pathIdxStart + i + j];
                      if (!matchStrings(subPat, subStr, uriTemplateVariables)) {
                          continue strLoop;
                      }
                  }
                  foundIdx = pathIdxStart + i;
                  break;
              }
  
              if (foundIdx == -1) {
                  return false;
              }
  
              pattIdxStart = patIdxTmp;
              pathIdxStart = foundIdx + patLength;
          }
  
          for (int i = pattIdxStart; i <= pattIdxEnd; i++) {
              if (!pattDirs[i].equals("**")) {
                  return false;
              }
          }
  
          return true;
      }