func nameOfFunction(f interface{}) string {
	fun := runtime.FuncForPC(reflect.ValueOf(f).Pointer())
	tokenized := strings.Split(fun.Name(), ".")
	last := tokenized[len(tokenized)-1]
	last = strings.TrimSuffix(last, ")·fm")  
	last = strings.TrimSuffix(last, ")-fm")  
	last = strings.TrimSuffix(last, "·fm")   
	last = strings.TrimSuffix(last, "-fm")   
	if last == "func1" {                     
		val := atomic.AddInt32(&anonymousFuncCount, 1)
		last = "func" + fmt.Sprintf("%d", val)
		atomic.StoreInt32(&anonymousFuncCount, val)
	}
	return last
}
nameOfFunction returns the short name of the function f for documentation.
It uses a runtime feature for debugging ; its value may change for later Go versions.
package restful
import (
	"fmt"
	"os"
	"reflect"
	"runtime"
	"strings"
	"sync/atomic"
	"github.com/emicklei/go-restful/log"
)
type RouteBuilder struct {
	rootPath    string
	currentPath string
	produces    []string
	consumes    []string
	httpMethod  string         
	function    RouteFunction  
	filters     []FilterFunction
	conditions  []RouteSelectionConditionFunction
	typeNameHandleFunc TypeNameHandleFunction  
	doc                     string
	notes                   string
	operation               string
	readSample, writeSample interface{}
	parameters              []*Parameter
	errorMap                map[int]ResponseError
	defaultResponse         *ResponseError
	metadata                map[string]interface{}
	deprecated              bool
	contentEncodingEnabled  *bool
}
func (b *RouteBuilder) Do(oneArgBlocks ...func(*RouteBuilder)) *RouteBuilder {
	for _, each := range oneArgBlocks {
		each(b)
	}
	return b
}
func (b *RouteBuilder) To(function RouteFunction) *RouteBuilder {
	b.function = function
	return b
}
func (b *RouteBuilder) Method(method string) *RouteBuilder {
	b.httpMethod = method
	return b
}
func (b *RouteBuilder) Produces(mimeTypes ...string) *RouteBuilder {
	b.produces = mimeTypes
	return b
}
func (b *RouteBuilder) Consumes(mimeTypes ...string) *RouteBuilder {
	b.consumes = mimeTypes
	return b
}
func (b *RouteBuilder) Path(subPath string) *RouteBuilder {
	b.currentPath = subPath
	return b
}
func (b *RouteBuilder) Doc(documentation string) *RouteBuilder {
	b.doc = documentation
	return b
}
func (b *RouteBuilder) Notes(notes string) *RouteBuilder {
	b.notes = notes
	return b
}
func (b *RouteBuilder) Reads(sample interface{}, optionalDescription ...string) *RouteBuilder {
	fn := b.typeNameHandleFunc
	if fn == nil {
		fn = reflectTypeName
	}
	typeAsName := fn(sample)
	description := ""
	if len(optionalDescription) > 0 {
		description = optionalDescription[0]
	}
	b.readSample = sample
	bodyParameter := &Parameter{&ParameterData{Name: "body", Description: description}}
	bodyParameter.beBody()
	bodyParameter.Required(true)
	bodyParameter.DataType(typeAsName)
	b.Param(bodyParameter)
	return b
}
func (b RouteBuilder) ParameterNamed(name string) (p *Parameter) {
	for _, each := range b.parameters {
		if each.Data().Name == name {
			return each
		}
	}
	return p
}
func (b *RouteBuilder) Writes(sample interface{}) *RouteBuilder {
	b.writeSample = sample
	return b
}
func (b *RouteBuilder) Param(parameter *Parameter) *RouteBuilder {
	if b.parameters == nil {
		b.parameters = []*Parameter{}
	}
	b.parameters = append(b.parameters, parameter)
	return b
}
func (b *RouteBuilder) Operation(name string) *RouteBuilder {
	b.operation = name
	return b
}
func (b *RouteBuilder) ReturnsError(code int, message string, model interface{}) *RouteBuilder {
	log.Print("ReturnsError is deprecated, use Returns instead.")
	return b.Returns(code, message, model)
}
func (b *RouteBuilder) Returns(code int, message string, model interface{}) *RouteBuilder {
	err := ResponseError{
		Code:      code,
		Message:   message,
		Model:     model,
		IsDefault: false,  
	}
	if b.errorMap == nil {
		b.errorMap = map[int]ResponseError{}
	}
	b.errorMap[code] = err
	return b
}
func (b *RouteBuilder) DefaultReturns(message string, model interface{}) *RouteBuilder {
	b.defaultResponse = &ResponseError{
		Message: message,
		Model:   model,
	}
	return b
}
func (b *RouteBuilder) Metadata(key string, value interface{}) *RouteBuilder {
	if b.metadata == nil {
		b.metadata = map[string]interface{}{}
	}
	b.metadata[key] = value
	return b
}
func (b *RouteBuilder) Deprecate() *RouteBuilder {
	b.deprecated = true
	return b
}
type ResponseError struct {
	Code      int
	Message   string
	Model     interface{}
	IsDefault bool
}
func (b *RouteBuilder) servicePath(path string) *RouteBuilder {
	b.rootPath = path
	return b
}
func (b *RouteBuilder) Filter(filter FilterFunction) *RouteBuilder {
	b.filters = append(b.filters, filter)
	return b
}
func (b *RouteBuilder) If(condition RouteSelectionConditionFunction) *RouteBuilder {
	b.conditions = append(b.conditions, condition)
	return b
}
func (b *RouteBuilder) ContentEncodingEnabled(enabled bool) *RouteBuilder {
	b.contentEncodingEnabled = &enabled
	return b
}
func (b *RouteBuilder) copyDefaults(rootProduces, rootConsumes []string) {
	if len(b.produces) == 0 {
		b.produces = rootProduces
	}
	if len(b.consumes) == 0 {
		b.consumes = rootConsumes
	}
}
func (b *RouteBuilder) typeNameHandler(handler TypeNameHandleFunction) *RouteBuilder {
	b.typeNameHandleFunc = handler
	return b
}
func (b *RouteBuilder) Build() Route {
	pathExpr, err := newPathExpression(b.currentPath)
	if err != nil {
		log.Printf("Invalid path:%s because:%v", b.currentPath, err)
		os.Exit(1)
	}
	if b.function == nil {
		log.Printf("No function specified for route:" + b.currentPath)
		os.Exit(1)
	}
	operationName := b.operation
	if len(operationName) == 0 && b.function != nil {
		operationName = nameOfFunction(b.function)
	}
	route := Route{
		Method:                 b.httpMethod,
		Path:                   concatPath(b.rootPath, b.currentPath),
		Produces:               b.produces,
		Consumes:               b.consumes,
		Function:               b.function,
		Filters:                b.filters,
		If:                     b.conditions,
		relativePath:           b.currentPath,
		pathExpr:               pathExpr,
		Doc:                    b.doc,
		Notes:                  b.notes,
		Operation:              operationName,
		ParameterDocs:          b.parameters,
		ResponseErrors:         b.errorMap,
		DefaultResponse:        b.defaultResponse,
		ReadSample:             b.readSample,
		WriteSample:            b.writeSample,
		Metadata:               b.metadata,
		Deprecated:             b.deprecated,
		contentEncodingEnabled: b.contentEncodingEnabled,
	}
	route.postBuild()
	return route
}
func concatPath(path1, path2 string) string {
	return strings.TrimRight(path1, "/") + "/" + strings.TrimLeft(path2, "/")
}
var anonymousFuncCount int32