func (r *Route) Name(name string) *Route {
	router := r.router.root()
	if router.NamedRoutes == nil {
		router.NamedRoutes = make(map[string]*Route)
	}
	r.name = name
	router.NamedRoutes[name] = r
	return r
}
Name sets the route name, used to build URLs.

A name must be unique for a router. If the name was registered already
it will be overwritten.
package mux
import (
	"bytes"
	"errors"
	"fmt"
	"http"
	"path"
	"regexp"
	"strings"
	"url"
	"gorilla.googlecode.com/hg/gorilla/context"
)
const (
	errRouteName string = "Duplicated route name: %q."
	errVarName   string = "Duplicated route variable name: %q."
	errUnbalancedBraces string = "Unbalanced curly braces in route template: %q."
	errBadTemplatePart  string = "Missing name or pattern in route template: %q."
	errMissingRouteVar string = "Missing route variable: %q."
	errBadRouteVar     string = "Route variable doesn't match: got %q, expected %q."
	errMissingHost     string = "Route doesn't have a host."
	errMissingPath     string = "Route doesn't have a path."
	errEmptyHost       string = "Host() requires a non-zero string, got %q."
	errEmptyPath       string = "Path() requires a non-zero string that starts with a slash, got %q."
	errEmptyPathPrefix string = "PathPrefix() requires a non-zero string that starts with a slash, got %q."
	errEmptyHeaders string = "Headers() requires at least a pair of parameters."
	errEmptyMethods string = "Methods() requires at least one parameter."
	errEmptyQueries string = "Queries() requires at least a pair of parameters."
	errEmptySchemes string = "Schemes() requires at least one parameter."
	errOddHeaders   string = "Headers() requires an even number of parameters, got %v."
	errOddQueries   string = "Queries() requires an even number of parameters, got %v."
	errOddURLPairs  string = "URL() requires an even number of parameters, got %v."
)
type RouteVars map[string]string
var ctx = new(context.Namespace)
func Vars(request *http.Request) RouteVars {
	rv := ctx.Get(request)
	if rv != nil {
		return rv.(RouteVars)
	}
	return nil
}
var routeCtx = new(context.Namespace)
func CurrentRoute(request *http.Request) *Route {
	rv := routeCtx.Get(request)
	if rv != nil {
		return rv.(*Route)
	}
	return nil
}
type Router struct {
	Routes []*Route
	NamedRoutes map[string]*Route
	rootRouter *Router
	NotFoundHandler http.Handler
	redirectSlash bool
}
func (r *Router) root() *Router {
	if r.rootRouter == nil {
		return r
	}
	return r.rootRouter
}
func (r *Router) Match(request *http.Request) (match *RouteMatch, ok bool) {
	for _, route := range r.Routes {
		if match, ok = route.Match(request); ok {
			return
		}
	}
	return
}
func (r *Router) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	if p := cleanPath(request.URL.Path); p != request.URL.Path {
		writer.Header().Set("Location", p)
		writer.WriteHeader(http.StatusMovedPermanently)
		return
	}
	var handler http.Handler
	if match, ok := r.Match(request); ok {
		handler = match.Handler
	}
	if handler == nil {
		if r.NotFoundHandler == nil {
			r.NotFoundHandler = http.NotFoundHandler()
		}
		handler = r.NotFoundHandler
	}
	defer context.DefaultContext.Clear(request)
	handler.ServeHTTP(writer, request)
}
func (r *Router) AddRoute(route *Route) *Router {
	if r.Routes == nil {
		r.Routes = make([]*Route, 0)
	}
	route.router = r
	r.Routes = append(r.Routes, route)
	return r
}
func (r *Router) RedirectSlash(value bool) *Router {
	r.redirectSlash = value
	return r
}
func (r *Router) NewRoute() *Route {
	route := newRoute()
	route.redirectSlash = r.redirectSlash
	r.AddRoute(route)
	return route
}
func (r *Router) Handle(path string, handler http.Handler) *Route {
	return r.NewRoute().Handle(path, handler)
}
func (r *Router) HandleFunc(path string, handler func(http.ResponseWriter,
	*http.Request)) *Route {
	return r.NewRoute().HandleFunc(path, handler)
}
type Route struct {
	router *Router
	handler http.Handler
	matchers []*routeMatcher
	hostTemplate *parsedTemplate
	pathTemplate *parsedTemplate
	redirectSlash bool
	name string
}
func newRoute() *Route {
	return &Route{
		matchers: make([]*routeMatcher, 0),
	}
}
func (r *Route) Clone() *Route {
	matchers := make([]*routeMatcher, len(r.matchers))
	copy(matchers, r.matchers)
	return &Route{
		router:        r.router,
		handler:       r.handler,
		matchers:      matchers,
		hostTemplate:  r.hostTemplate,
		pathTemplate:  r.pathTemplate,
		redirectSlash: r.redirectSlash,
	}
}
func (r *Route) Match(req *http.Request) (*RouteMatch, bool) {
	var hostMatches, pathMatches []string
	if r.hostTemplate != nil {
		hostMatches = r.hostTemplate.Regexp.FindStringSubmatch(req.URL.Host)
		if hostMatches == nil {
			return nil, false
		}
	}
	var redirectURL string
	if r.pathTemplate != nil {
		pathMatches = r.pathTemplate.Regexp.FindStringSubmatch(req.URL.Path)
		if pathMatches == nil {
			return nil, false
		} else if r.redirectSlash {
			p1 := strings.HasSuffix(req.URL.Path, "/")
			p2 := strings.HasSuffix(r.pathTemplate.Template, "/")
			if p1 != p2 {
				ru, _ := url.Parse(req.URL.String())
				if p1 {
					ru.Path = ru.Path[:len(ru.Path)-1]
				} else {
					ru.Path = ru.Path + "/"
				}
				redirectURL = ru.String()
			}
		}
	}
	var match *RouteMatch
	if r.matchers != nil {
		for _, matcher := range r.matchers {
			if rv, ok := (*matcher).Match(req); !ok {
				return nil, false
			} else if rv != nil {
				match = rv
				break
			}
		}
	}
	vars := make(RouteVars)
	if hostMatches != nil {
		for k, v := range r.hostTemplate.VarsN {
			vars[v] = hostMatches[k+1]
		}
	}
	if pathMatches != nil {
		for k, v := range r.pathTemplate.VarsN {
			vars[v] = pathMatches[k+1]
		}
	}
	if match == nil {
		match = &RouteMatch{Route: r, Handler: r.handler}
	}
	if redirectURL != "" {
		match.Handler = http.RedirectHandler(redirectURL, 301)
	}
	ctx.Set(req, vars)
	routeCtx.Set(req, match.Route)
	return match, true
}
func (r *Route) NewRouter() *Router {
	router := &Router{
		Routes:     make([]*Route, 0),
		rootRouter: r.router.root(),
	}
	r.addMatcher(router)
	return router
}
func (r *Route) URL(pairs ...string) (rv *url.URL) {
	rv, _ = r.URLDebug(pairs...)
	return
}
func (r *Route) URLDebug(pairs ...string) (rv *url.URL, err error) {
	var scheme, host, path string
	values := stringMapFromPairs(errOddURLPairs, pairs...)
	if r.hostTemplate != nil {
		scheme = "http"
		if host, err = reverseRoute(r.hostTemplate, values); err != nil {
			return
		}
	}
	if r.pathTemplate != nil {
		if path, err = reverseRoute(r.pathTemplate, values); err != nil {
			return
		}
	}
	rv = &url.URL{
		Scheme: scheme,
		Host:   host,
		Path:   path,
	}
	return
}
func (r *Route) URLHost(pairs ...string) (rv *url.URL) {
	rv, _ = r.URLHostDebug(pairs...)
	return
}
func (r *Route) URLHostDebug(pairs ...string) (rv *url.URL, err error) {
	if r.hostTemplate == nil {
		err = muxError(errMissingHost)
		return
	}
	var host string
	values := stringMapFromPairs(errOddURLPairs, pairs...)
	if host, err = reverseRoute(r.hostTemplate, values); err != nil {
		return
	} else {
		rv = &url.URL{
			Scheme: "http",
			Host:   host,
		}
	}
	return
}
func (r *Route) URLPath(pairs ...string) (rv *url.URL) {
	rv, _ = r.URLPathDebug(pairs...)
	return
}
func (r *Route) URLPathDebug(pairs ...string) (rv *url.URL, err error) {
	if r.pathTemplate == nil {
		err = muxError(errMissingPath)
		return
	}
	var path string
	values := stringMapFromPairs(errOddURLPairs, pairs...)
	if path, err = reverseRoute(r.pathTemplate, values); err != nil {
		return
	} else {
		rv = &url.URL{
			Path: path,
		}
	}
	return
}
func reverseRoute(tpl *parsedTemplate, values map[string]string) (rv string, err error) {
	var value string
	var ok bool
	urlValues := make([]interface{}, len(tpl.VarsN))
	for k, v := range tpl.VarsN {
		if value, ok = values[v]; !ok {
			err = muxError(errMissingRouteVar, v)
			return
		}
		urlValues[k] = value
	}
	rv = fmt.Sprintf(tpl.Reverse, urlValues...)
	if !tpl.Regexp.MatchString(rv) {
		for k, v := range tpl.VarsN {
			if !tpl.VarsR[k].MatchString(values[v]) {
				err = muxError(errBadRouteVar, values[v],
					tpl.VarsR[k].String())
				return
			}
		}
	}
	return
}
func (r *Route) Handler(handler http.Handler) *Route {
	r.handler = handler
	return r
}
func (r *Route) HandlerFunc(handler func(http.ResponseWriter,
	*http.Request)) *Route {
	return r.Handler(http.HandlerFunc(handler))
}
func (r *Route) Handle(path string, handler http.Handler) *Route {
	return r.Path(path).Handler(handler)
}
func (r *Route) HandleFunc(path string, handler func(http.ResponseWriter,
	*http.Request)) *Route {
	return r.Path(path).Handler(http.HandlerFunc(handler))
}