docs: public Matcher matcher( String absolutePath ) {
          PathExpression.Matcher inputMatcher = selectExpression.matcher(absolutePath);
          String outputPath = null;
          WorkspacePath wsPath = null;
          if (inputMatcher.matches()) {
              // Grab the named groups ...
              Map<Integer, String> replacements = new HashMap<Integer, String>();
              for (int i = 0, count = inputMatcher.groupCount(); i <= count; ++i) {
                  replacements.put(i, inputMatcher.group(i));
              }
  
              // Grab the selected path ...
              String selectedPath = inputMatcher.getSelectedNodePath();
  
              // Find the output path using the groups from the match pattern ...
              wsPath = PathExpression.parsePathInWorkspace(this.outputExpression);
              if (wsPath != null) {
                  if (wsPath.workspaceName == null) wsPath = wsPath.withWorkspaceName(inputMatcher.getSelectedWorkspaceName());
                  outputPath = wsPath.path;
                  if (!DEFAULT_OUTPUT_EXPRESSION.equals(outputPath)) {
                      java.util.regex.Matcher replacementMatcher = REPLACEMENT_VARIABLE_PATTERN.matcher(outputPath);
                      // CHECKSTYLE IGNORE check FOR NEXT 1 LINES
                      StringBuffer sb = new StringBuffer();
                      if (replacementMatcher.find()) {
                          do {
                              String variable = replacementMatcher.group(1);
                              String replacement = replacements.get(Integer.valueOf(variable));
                              if (replacement == null) replacement = replacementMatcher.group(0);
                              replacementMatcher.appendReplacement(sb, replacement);
                          } while (replacementMatcher.find());
                          replacementMatcher.appendTail(sb);
                          outputPath = sb.toString();
                      }
                      // Make sure there is a trailing '/' ...
                      if (!outputPath.endsWith("/")) outputPath = outputPath + "/";
  
                      // Replace all references to "/./" with "/" ...
                      outputPath = outputPath.replaceAll("/\\./", "/");
  
                      // Remove any path segment followed by a parent reference ...
                      java.util.regex.Matcher parentMatcher = PARENT_PATTERN.matcher(outputPath);
                      while (parentMatcher.find()) {
                          outputPath = parentMatcher.replaceAll("");
                          // Make sure there is a trailing '/' ...
                          if (!outputPath.endsWith("/")) outputPath = outputPath + "/";
                          parentMatcher = PARENT_PATTERN.matcher(outputPath);
                      }
  
                      // Remove all multiple occurrences of '/' ...
                      outputPath = outputPath.replaceAll("/{2,}", "/");
  
                      // Remove the trailing '/@property' ...
                      outputPath = outputPath.replaceAll("/@[^/\\[\\]]+$", "");
  
                      // Remove a trailing '/' ...
                      outputPath = outputPath.replaceAll("/$", "");
  
                      // If the output path is blank, then use the default output expression ...
                      if (outputPath.length() == 0) outputPath = DEFAULT_OUTPUT_EXPRESSION;
  
                  }
                  if (DEFAULT_OUTPUT_EXPRESSION.equals(outputPath)) {
                      // The output path is the default expression, so use the selected path ...
                      outputPath = selectedPath;
                  }
                  wsPath = wsPath.withPath(outputPath);
              }
          }
  
          return new Matcher(inputMatcher, wsPath);
      }