// addMatcher adds a matcher to the route.
494971
func (r *Route) AddMatcher(m Matcher) *Route {
	if r.err == nil {
		r.matchers = append(r.matchers, m)
	}
	return r
}
712225
func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool {
	return m(r, match)
}
993832
func (t *RouteTrie) Add(route string, value interface{}) error {
	route = normalize(route)

	// If the end has been reached, save the value to the node.
	if route == "" {
		t.value = value
		return nil
	}

	// Split off the head path from the route.
	// For example: 'foo/bar/baz' => 'foo', 'bar/baz'.
	head, tail := split(route)

	var nextNode *RouteTrie
	if head[0] == ':' {
		paramChildName := head[1:]
		if t.paramChild == nil {
			t.paramChild = &paramChild{
				name: paramChildName,
				trie: NewRouteTrie(),
			}
		} else {
      // TODO(stevenle): Support different :param names at the same path.
			if t.paramChild.name != paramChildName {
				return errors.New("Cannot set two different :param names at the same path")
			}
		}
		nextNode = t.paramChild.trie
	} else if head[0] == '*' {
		t.wildcardChild = &wildcardChild{
			name:  head[1:],
			value: value,
		}
		return nil
	} else {
		nextNode = t.children[head]
		if nextNode == nil {
			nextNode = NewRouteTrie()
			t.children[head] = nextNode
		}
	}

	return nextNode.Add(tail, value)
}
588897
func NewMatcher(pattern string) Matcher {
	if pattern == "" {
		return nil
	}
	if ip := net.ParseIP(pattern); ip != nil {
		return IPMatcher(ip)
	}
	if _, inet, err := net.ParseCIDR(pattern); err == nil {
		return CIDRMatcher(inet)
	}
	return DomainMatcher(pattern)
}
533988
func (s *Selection) RemoveMatcher(m Matcher) *Selection {
	return s.FilterMatcher(m).Remove()
}
598528
func (bp *Bypass) AddMatchers(matchers ...Matcher) {
	bp.mux.Lock()
	defer bp.mux.Unlock()

	bp.matchers = append(bp.matchers, matchers...)
}
241884
func (s *Selection) WrapMatcher(m Matcher) *Selection {
	return s.wrapNodes(m.MatchAll(s.document.rootNode)...)
}
467586
func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
	if r.buildOnly || r.err != nil {
		return false
	}

	var matchErr error

	// Match everything.
	for _, m := range r.matchers {
		if matched := m.Match(req, match); !matched {
			if _, ok := m.(methodMatcher); ok {
				matchErr = ErrMethodMismatch
				continue
			}

			// Ignore ErrNotFound errors. These errors arise from match call
			// to Subrouters.
			//
			// This prevents subsequent matching subrouters from failing to
			// run middleware. If not ignored, the middleware would see a
			// non-nil MatchErr and be skipped, even when there was a
			// matching route.
			if match.MatchErr == ErrNotFound {
				match.MatchErr = nil
			}

			matchErr = nil
			return false
		}
	}

	if matchErr != nil {
		match.MatchErr = matchErr
		return false
	}

	if match.MatchErr == ErrMethodMismatch {
		// We found a route which matches request method, clear MatchErr
		match.MatchErr = nil
		// Then override the mis-matched handler
		match.Handler = r.handler
	}

	// Yay, we have a match. Let's collect some info about it.
	if match.Route == nil {
		match.Route = r
	}
	if match.Handler == nil {
		match.Handler = r.handler
	}
	if match.Vars == nil {
		match.Vars = make(map[string]string)
	}

	// Set variables.
	r.regexp.setMatch(req, match, r)
	return true
}
1261789
func (s *Selection) PrevMatcher(m Matcher) *Selection {
	return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil), m)
}
601036
func NewStringMatcher(dictionary []string) *Matcher {
	m := new(Matcher)

	var d [][]byte
	for _, s := range dictionary {
		d = append(d, []byte(s))
	}

	m.buildTrie(d)

	return m
}
493392
func (r *Request) AddMatcher(fn MatchFunc) *Request {
	r.Mock.AddMatcher(fn)
	return r
}
1080255
func NewMatcher(versions Map) context.Handler {
	constraintsHandlers, notFoundHandler := buildConstraints(versions)

	return func(ctx context.Context) {
		versionString := GetVersion(ctx)
		if versionString == NotFound {
			notFoundHandler(ctx)
			return
		}

		ver, err := version.NewVersion(versionString)
		if err != nil {
			notFoundHandler(ctx)
			return
		}

		for _, ch := range constraintsHandlers {
			if ch.constraints.Check(ver) {
				ctx.Header("X-API-Version", ver.String())
				ch.handler(ctx)
				return
			}
		}

		// pass the not matched version so the not found handler can have knowedge about it.
		// ctx.Values().Set(Key, versionString)
		// or let a manual cal of GetVersion(ctx) do that instead.
		notFoundHandler(ctx)
	}
}
761705
func (s *Server) Match(method string, route string, handler interface{}) {
	s.addRoute(route, method, handler)
}
660280
func (c Context) PathMatches(pattern string) bool {
	return Path(c.Req.URL.Path).Matches(pattern)
}
3183
func (m *MockMatcher) Add(fn MatchFunc) {
	m.Matchers = append(m.Matchers, fn)
}
903702
func NewMatcher(stack []MatchAttribute) Matcher {
	m := &matcher{stack: stack}
	m.init()

	return m
}
547381
func (m *RouteMux) AddRoute(method string, pattern string, handler http.HandlerFunc) {

	//split the url into sections
	parts := strings.Split(pattern, "/")

	//find params that start with ":"
	//replace with regular expressions
	j := 0
	params := make(map[int]string)
	for i, part := range parts {
		if strings.HasPrefix(part, ":") {
			expr := "([^/]+)"
			//a user may choose to override the defult expression
			// similar to expressjs: ‘/user/:id([0-9]+)’ 
			if index := strings.Index(part, "("); index != -1 {
				expr = part[index:]
				part = part[:index]
			}
			params[j] = part
			parts[i] = expr
			j++
		}
	}

	//recreate the url pattern, with parameters replaced
	//by regular expressions. then compile the regex
	pattern = strings.Join(parts, "/")
	regex, regexErr := regexp.Compile(pattern)
	if regexErr != nil {
		//TODO add error handling here to avoid panic
		panic(regexErr)
		return
	}

	//now create the Route
	route := &route{}
	route.method = method
	route.regex = regex
	route.handler = handler
	route.params = params

	//and finally append to the list of Routes
	m.routes = append(m.routes, route)
}