docs: function traverseRoute(that, route, pathSegment, pathIndexOffset) {
  
          var handlerParameters = []
          var matchingRouteInfo;
          for(var i=0; i<route.routes.length; i++) {
              var info = route.routes[i]
  
              var transformedPathSegment = info.pathSegment//getPathSegmentFromInput(that.transform, info.pathSegment)
              if(!(transformedPathSegment instanceof Array))
                  transformedPathSegment = [transformedPathSegment]
  
              var matchConsumed = match(transformedPathSegment, pathSegment)
              if(matchConsumed !== undefined) {
                  matchingRouteInfo = {handler: info.handler, consumed: matchConsumed, pathSegment: pathSegment.slice(0,matchConsumed)}
                  for(var n=0; n<transformedPathSegment.length; n++) {
                      if(transformedPathSegment[n] === Router.param) {
                          handlerParameters.push(pathSegment[n])
                      }
                  }
                  break;
              }
          }
  
          var runningDefault = false
          if(matchingRouteInfo === undefined) {
              if(pathSegment.length === 0) {
                  return []; // done
              } else if(route.defaultHandler !== undefined) {
                  getMatchingInfoForDefault()
              } else {
                  return undefined // no default and no match!
              }
          }
  
          var consumed = matchingRouteInfo.consumed
          var subroute = new Route(matchingRouteInfo.pathSegment, that.transform, runningDefault)
          matchingRouteInfo.handler.apply(subroute, handlerParameters)
  
          if(runningDefault) { // if running a default handler
              var rest = []
          } else {
              var rest = traverseRoute(that, subroute, pathSegment.slice(consumed), pathIndexOffset+consumed)
          }
  
          if(rest === undefined) {
              // since there wasn't a full match in the child route, do the default route
  
              if(route.defaultHandler !== undefined) {
                  getMatchingInfoForDefault()
                  consumed = matchingRouteInfo.consumed
                  subroute = new Route(matchingRouteInfo.pathSegment, that.transform, true)
                  matchingRouteInfo.handler.apply(subroute, handlerParameters)
                  rest = []
              } else {
                  return undefined // no default and no match!
              }
          }
  
          var pathIndexEnd = pathIndexOffset+consumed
          if(consumed !== 0) {
              pathIndexEnd--
          }
          return [{route: subroute, pathIndexes: {start:pathIndexOffset, end: pathIndexEnd}}].concat(rest)
  
  
          function getMatchingInfoForDefault() {
              matchingRouteInfo = {handler: route.defaultHandler, consumed: pathSegment.length, pathSegment: pathSegment} // default handler consume the whole path - can't have subroutes
              runningDefault = true
              handlerParameters.push(getPathSegementToOutput(that.transform, pathSegment))
          }
      }