router: auto wrapping of http.Handler and http.HandlerFunc
diff --git a/router.go b/router.go
index f18a678..1d70c66 100644
--- a/router.go
+++ b/router.go
@@ -85,6 +85,32 @@
 // wildcards (variables).
 type Handle func(http.ResponseWriter, *http.Request, Params)
 
+// Wrap is the default wrap function to wrap handle types to Handle.
+// Currently Handle, http.Handler and http.HandlerFunc are supported.
+// Opther handle types can be used by setting a custom wrap function.
+func Wrap(handle interface{}) Handle {
+	switch h := handle.(type) {
+	case Handle:
+		return h
+	case func(http.ResponseWriter, *http.Request, Params):
+		return h
+	case http.HandlerFunc:
+		return func(w http.ResponseWriter, req *http.Request, _ Params) {
+			h(w, req)
+		}
+	case func(http.ResponseWriter, *http.Request):
+		return func(w http.ResponseWriter, req *http.Request, _ Params) {
+			h(w, req)
+		}
+	case http.Handler:
+		return func(w http.ResponseWriter, req *http.Request, _ Params) {
+			h.ServeHTTP(w, req)
+		}
+	default:
+		panic("unknown handle type")
+	}
+}
+
 // Param is a single URL parameter, consisting of a key and a value.
 type Param struct {
 	Key   string
@@ -159,6 +185,11 @@
 	// The handler can be used to keep your server from crashing because of
 	// unrecovered panics.
 	PanicHandler func(http.ResponseWriter, *http.Request, interface{})
+
+	// Function to wrap handle types to Handle. The default function is Wrap.
+	// Custom functions can be used to allow other handle types or apply pre- /
+	// postprocessing of the request.
+	Wrap func(interface{}) Handle
 }
 
 // Make sure the Router conforms with the http.Handler interface
@@ -172,41 +203,42 @@
 		RedirectFixedPath:      true,
 		HandleMethodNotAllowed: true,
 		HandleOPTIONS:          true,
+		Wrap:                   Wrap,
 	}
 }
 
 // GET is a shortcut for router.Handle("GET", path, handle)
-func (r *Router) GET(path string, handle Handle) {
+func (r *Router) GET(path string, handle interface{}) {
 	r.Handle("GET", path, handle)
 }
 
 // HEAD is a shortcut for router.Handle("HEAD", path, handle)
-func (r *Router) HEAD(path string, handle Handle) {
+func (r *Router) HEAD(path string, handle interface{}) {
 	r.Handle("HEAD", path, handle)
 }
 
 // OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle)
-func (r *Router) OPTIONS(path string, handle Handle) {
+func (r *Router) OPTIONS(path string, handle interface{}) {
 	r.Handle("OPTIONS", path, handle)
 }
 
 // POST is a shortcut for router.Handle("POST", path, handle)
-func (r *Router) POST(path string, handle Handle) {
+func (r *Router) POST(path string, handle interface{}) {
 	r.Handle("POST", path, handle)
 }
 
 // PUT is a shortcut for router.Handle("PUT", path, handle)
-func (r *Router) PUT(path string, handle Handle) {
+func (r *Router) PUT(path string, handle interface{}) {
 	r.Handle("PUT", path, handle)
 }
 
 // PATCH is a shortcut for router.Handle("PATCH", path, handle)
-func (r *Router) PATCH(path string, handle Handle) {
+func (r *Router) PATCH(path string, handle interface{}) {
 	r.Handle("PATCH", path, handle)
 }
 
 // DELETE is a shortcut for router.Handle("DELETE", path, handle)
-func (r *Router) DELETE(path string, handle Handle) {
+func (r *Router) DELETE(path string, handle interface{}) {
 	r.Handle("DELETE", path, handle)
 }
 
@@ -218,11 +250,16 @@
 // This function is intended for bulk loading and to allow the usage of less
 // frequently used, non-standardized or custom methods (e.g. for internal
 // communication with a proxy).
-func (r *Router) Handle(method, path string, handle Handle) {
+func (r *Router) Handle(method, path string, handle interface{}) {
 	if path[0] != '/' {
 		panic("path must begin with '/' in path '" + path + "'")
 	}
 
+	if r.Wrap == nil {
+		r.Wrap = Wrap
+	}
+	h := r.Wrap(handle)
+
 	if r.trees == nil {
 		r.trees = make(map[string]*node)
 	}
@@ -233,23 +270,7 @@
 		r.trees[method] = root
 	}
 
-	root.addRoute(path, handle)
-}
-
-// Handler is an adapter which allows the usage of an http.Handler as a
-// request handle.
-func (r *Router) Handler(method, path string, handler http.Handler) {
-	r.Handle(method, path,
-		func(w http.ResponseWriter, req *http.Request, _ Params) {
-			handler.ServeHTTP(w, req)
-		},
-	)
-}
-
-// HandlerFunc is an adapter which allows the usage of an http.HandlerFunc as a
-// request handle.
-func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc) {
-	r.Handler(method, path, handler)
+	root.addRoute(path, h)
 }
 
 // ServeFiles serves files from the given file system root.
diff --git a/router_test.go b/router_test.go
index db57740..300fbd1 100644
--- a/router_test.go
+++ b/router_test.go
@@ -76,7 +76,8 @@
 }
 
 func TestRouterAPI(t *testing.T) {
-	var get, head, options, post, put, patch, delete, handler, handlerFunc bool
+	var get, head, options, post, put, patch, delete bool
+	var handle, handler, handlerFunc1, handlerFunc2 bool
 
 	httpHandler := handlerStruct{&handler}
 
@@ -102,10 +103,16 @@
 	router.DELETE("/DELETE", func(w http.ResponseWriter, r *http.Request, _ Params) {
 		delete = true
 	})
-	router.Handler("GET", "/Handler", httpHandler)
-	router.HandlerFunc("GET", "/HandlerFunc", func(w http.ResponseWriter, r *http.Request) {
-		handlerFunc = true
+	router.Handle("GET", "/Handle", Handle(func(w http.ResponseWriter, r *http.Request, _ Params) {
+		handle = true
+	}))
+	router.Handle("GET", "/Handler", httpHandler)
+	router.Handle("GET", "/HandlerFunc1", func(w http.ResponseWriter, r *http.Request) {
+		handlerFunc1 = true
 	})
+	router.Handle("GET", "/HandlerFunc2", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		handlerFunc2 = true
+	}))
 
 	w := new(mockResponseWriter)
 
@@ -151,16 +158,57 @@
 		t.Error("routing DELETE failed")
 	}
 
+	r, _ = http.NewRequest("GET", "/Handle", nil)
+	router.ServeHTTP(w, r)
+	if !handle {
+		t.Error("routing Handle failed")
+	}
+
 	r, _ = http.NewRequest("GET", "/Handler", nil)
 	router.ServeHTTP(w, r)
 	if !handler {
 		t.Error("routing Handler failed")
 	}
 
-	r, _ = http.NewRequest("GET", "/HandlerFunc", nil)
+	r, _ = http.NewRequest("GET", "/HandlerFunc1", nil)
 	router.ServeHTTP(w, r)
-	if !handlerFunc {
-		t.Error("routing HandlerFunc failed")
+	if !handlerFunc1 {
+		t.Error("routing HandlerFunc1 failed")
+	}
+
+	r, _ = http.NewRequest("GET", "/HandlerFunc2", nil)
+	router.ServeHTTP(w, r)
+	if !handlerFunc2 {
+		t.Error("routing HandlerFunc2 failed")
+	}
+}
+
+func TestRouterInvalidWrap(t *testing.T) {
+	r := New()
+
+	// nil handle
+	recv := catchPanic(func() {
+		r.Handle("GET", "/nil", nil)
+	})
+	if recv == nil {
+		t.Errorf("no panic when inserting nil handle")
+	}
+
+	// handle which can not be wrapped
+	recv = catchPanic(func() {
+		r.Handle("GET", "/unknown", mockResponseWriter{})
+	})
+	if recv == nil {
+		t.Errorf("no panic when inserting unknown handle")
+	}
+
+	// no wrap func. Router should fall back to default
+	r.Wrap = nil
+	recv = catchPanic(func() {
+		r.Handle("GET", "/wrap", func(w http.ResponseWriter, r *http.Request, _ Params) {})
+	})
+	if recv != nil {
+		t.Errorf("panic when inserting without wrap func")
 	}
 }