code:     private final void internalMapWrapper(ContextVersion contextVersion,
                                            CharChunk path,
                                            MappingData mappingData) throws IOException {
  
          int pathOffset = path.getOffset();
          int pathEnd = path.getEnd();
          int servletPath = pathOffset;
          boolean noServletPath = false;
  
          int length = contextVersion.path.length();
          if (length != (pathEnd - pathOffset)) {
              servletPath = pathOffset + length;
          } else {
              noServletPath = true;
              path.append('/');
              pathOffset = path.getOffset();
              pathEnd = path.getEnd();
              servletPath = pathOffset+length;
          }
  
          path.setOffset(servletPath);
  
          // Rule 1 -- Exact Match
          MappedWrapper[] exactWrappers = contextVersion.exactWrappers;
          internalMapExactWrapper(exactWrappers, path, mappingData);
  
          // Rule 2 -- Prefix Match
          boolean checkJspWelcomeFiles = false;
          MappedWrapper[] wildcardWrappers = contextVersion.wildcardWrappers;
          if (mappingData.wrapper == null) {
              internalMapWildcardWrapper(wildcardWrappers, contextVersion.nesting,
                                         path, mappingData);
              if (mappingData.wrapper != null && mappingData.jspWildCard) {
                  char[] buf = path.getBuffer();
                  if (buf[pathEnd - 1] == '/') {
                      /*
                       * Path ending in '/' was mapped to JSP servlet based on
                       * wildcard match (e.g., as specified in url-pattern of a
                       * jsp-property-group.
                       * Force the context's welcome files, which are interpreted
                       * as JSP files (since they match the url-pattern), to be
                       * considered. See Bugzilla 27664.
                       */
                      mappingData.wrapper = null;
                      checkJspWelcomeFiles = true;
                  } else {
                      // See Bugzilla 27704
                      mappingData.wrapperPath.setChars(buf, path.getStart(),
                                                       path.getLength());
                      mappingData.pathInfo.recycle();
                  }
              }
          }
  
          if(mappingData.wrapper == null && noServletPath) {
              // The path is empty, redirect to "/"
              mappingData.redirectPath.setChars
                  (path.getBuffer(), pathOffset, pathEnd-pathOffset);
              path.setEnd(pathEnd - 1);
              return;
          }
  
          // Rule 3 -- Extension Match
          MappedWrapper[] extensionWrappers = contextVersion.extensionWrappers;
          if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
              internalMapExtensionWrapper(extensionWrappers, path, mappingData,
                      true);
          }
  
          // Rule 4 -- Welcome resources processing for servlets
          if (mappingData.wrapper == null) {
              boolean checkWelcomeFiles = checkJspWelcomeFiles;
              if (!checkWelcomeFiles) {
                  char[] buf = path.getBuffer();
                  checkWelcomeFiles = (buf[pathEnd - 1] == '/');
              }
              if (checkWelcomeFiles) {
                  for (int i = 0; (i < contextVersion.welcomeResources.length)
                           && (mappingData.wrapper == null); i++) {
                      path.setOffset(pathOffset);
                      path.setEnd(pathEnd);
                      path.append(contextVersion.welcomeResources[i], 0,
                              contextVersion.welcomeResources[i].length());
                      path.setOffset(servletPath);
  
                      // Rule 4a -- Welcome resources processing for exact macth
                      internalMapExactWrapper(exactWrappers, path, mappingData);
  
                      // Rule 4b -- Welcome resources processing for prefix match
                      if (mappingData.wrapper == null) {
                          internalMapWildcardWrapper
                              (wildcardWrappers, contextVersion.nesting,
                               path, mappingData);
                      }
  
                      // Rule 4c -- Welcome resources processing
                      //            for physical folder
                      if (mappingData.wrapper == null
                          && contextVersion.resources != null) {
                          String pathStr = path.toString();
                          WebResource file =
                                  contextVersion.resources.getResource(pathStr);
                          if (file != null && file.isFile()) {
                              internalMapExtensionWrapper(extensionWrappers, path,
                                                          mappingData, true);
                              if (mappingData.wrapper == null
                                  && contextVersion.defaultWrapper != null) {
                                  mappingData.wrapper =
                                      contextVersion.defaultWrapper.object;
                                  mappingData.requestPath.setChars
                                      (path.getBuffer(), path.getStart(),
                                       path.getLength());
                                  mappingData.wrapperPath.setChars
                                      (path.getBuffer(), path.getStart(),
                                       path.getLength());
                                  mappingData.requestPath.setString(pathStr);
                                  mappingData.wrapperPath.setString(pathStr);
                              }
                          }
                      }
                  }
  
                  path.setOffset(servletPath);
                  path.setEnd(pathEnd);
              }
  
          }
  
          /* welcome file processing - take 2
           * Now that we have looked for welcome files with a physical
           * backing, now look for an extension mapping listed
           * but may not have a physical backing to it. This is for
           * the case of index.jsf, index.do, etc.
           * A watered down version of rule 4
           */
          if (mappingData.wrapper == null) {
              boolean checkWelcomeFiles = checkJspWelcomeFiles;
              if (!checkWelcomeFiles) {
                  char[] buf = path.getBuffer();
                  checkWelcomeFiles = (buf[pathEnd - 1] == '/');
              }
              if (checkWelcomeFiles) {
                  for (int i = 0; (i < contextVersion.welcomeResources.length)
                           && (mappingData.wrapper == null); i++) {
                      path.setOffset(pathOffset);
                      path.setEnd(pathEnd);
                      path.append(contextVersion.welcomeResources[i], 0,
                                  contextVersion.welcomeResources[i].length());
                      path.setOffset(servletPath);
                      internalMapExtensionWrapper(extensionWrappers, path,
                                                  mappingData, false);
                  }
  
                  path.setOffset(servletPath);
                  path.setEnd(pathEnd);
              }
          }
  
  
          // Rule 7 -- Default servlet
          if (mappingData.wrapper == null && !checkJspWelcomeFiles) {
              if (contextVersion.defaultWrapper != null) {
                  mappingData.wrapper = contextVersion.defaultWrapper.object;
                  mappingData.requestPath.setChars
                      (path.getBuffer(), path.getStart(), path.getLength());
                  mappingData.wrapperPath.setChars
                      (path.getBuffer(), path.getStart(), path.getLength());
              }
              // Redirection to a folder
              char[] buf = path.getBuffer();
              if (contextVersion.resources != null && buf[pathEnd -1 ] != '/') {
                  String pathStr = path.toString();
                  WebResource file =
                          contextVersion.resources.getResource(pathStr);
                  if (file != null && file.isDirectory()) {
                      // Note: this mutates the path: do not do any processing
                      // after this (since we set the redirectPath, there
                      // shouldn't be any)
                      path.setOffset(pathOffset);
                      path.append('/');
                      mappingData.redirectPath.setChars
                          (path.getBuffer(), path.getStart(), path.getLength());
                  } else {
                      mappingData.requestPath.setString(pathStr);
                      mappingData.wrapperPath.setString(pathStr);
                  }
              }
          }
  
          path.setOffset(pathOffset);
          path.setEnd(pathEnd);
  
      }
  
  
      /**
       * Exact mapping.
       */
  