func (r *Response) End() Result {
	apiTest := r.apiTest
	defer func() {
		if apiTest.debugEnabled {
			apiTest.finished = time.Now()
			fmt.Println(fmt.Sprintf("Duration: %s\n", apiTest.finished.Sub(apiTest.started)))
		}
	}()
	if apiTest.handler == nil && !apiTest.networkingEnabled {
		apiTest.t.Fatal("either define a http.Handler or enable networking")
	}
	apiTest.started = time.Now()
	var res *http.Response
	if apiTest.reporter != nil {
		res = apiTest.report()
	} else {
		res = r.runTest()
	}
	var unmatchedMocks []UnmatchedMock
	for _, m := range r.apiTest.mocks {
		if m.isUsed == false {
			unmatchedMocks = append(unmatchedMocks, UnmatchedMock{
				URL: *m.request.url,
			})
			break
		}
	}
	return Result{
		Response:       res,
		unmatchedMocks: unmatchedMocks,
	}
}
End runs the test returning the result to the caller
package apitest
import (
	"bytes"
	"encoding/json"
	"fmt"
	"hash/fnv"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"net/http/httputil"
	"net/textproto"
	"net/url"
	"runtime/debug"
	"sort"
	"strings"
	"time"
)
const SystemUnderTestDefaultName = "sut"
const ConsumerDefaultName = "cli"
var divider = strings.Repeat("-", 10)
var requestDebugPrefix = fmt.Sprintf("%s>", divider)
var responseDebugPrefix = fmt.Sprintf("<%s", divider)
type APITest struct {
	debugEnabled             bool
	mockResponseDelayEnabled bool
	networkingEnabled        bool
	networkingHTTPClient     *http.Client
	reporter                 ReportFormatter
	verifier                 Verifier
	recorder                 *Recorder
	handler                  http.Handler
	name                     string
	request                  *Request
	response                 *Response
	observers                []Observe
	mocksObservers           []Observe
	recorderHook             RecorderHook
	mocks                    []*Mock
	t                        TestingT
	httpClient               *http.Client
	httpRequest              *http.Request
	transport                *Transport
	meta                     map[string]interface{}
	started                  time.Time
	finished                 time.Time
}
type InboundRequest struct {
	request   *http.Request
	timestamp time.Time
}
type FinalResponse struct {
	response  *http.Response
	timestamp time.Time
}
type Observe func(*http.Response, *http.Request, *APITest)
type RecorderHook func(*Recorder)
func New(name ...string) *APITest {
	apiTest := &APITest{
		meta: map[string]interface{}{},
	}
	request := &Request{
		apiTest:  apiTest,
		headers:  map[string][]string{},
		query:    map[string][]string{},
		formData: map[string][]string{},
	}
	response := &Response{
		apiTest: apiTest,
		headers: map[string][]string{},
	}
	apiTest.request = request
	apiTest.response = response
	if len(name) > 0 {
		apiTest.name = name[0]
	}
	return apiTest
}
func Handler(handler http.Handler) *APITest {
	return New().Handler(handler)
}
func HandlerFunc(handlerFunc http.HandlerFunc) *APITest {
	return New().HandlerFunc(handlerFunc)
}
func (a *APITest) EnableNetworking(cli ...*http.Client) *APITest {
	a.networkingEnabled = true
	if len(cli) == 1 {
		a.networkingHTTPClient = cli[0]
		return a
	}
	a.networkingHTTPClient = http.DefaultClient
	return a
}
func (a *APITest) EnableMockResponseDelay() *APITest {
	a.mockResponseDelayEnabled = true
	return a
}
func (a *APITest) Debug() *APITest {
	a.debugEnabled = true
	return a
}
func (a *APITest) Report(reporter ReportFormatter) *APITest {
	a.reporter = reporter
	return a
}
func (a *APITest) Recorder(recorder *Recorder) *APITest {
	a.recorder = recorder
	return a
}
func (a *APITest) Meta(meta map[string]interface{}) *APITest {
	a.meta = meta
	return a
}
func (a *APITest) Handler(handler http.Handler) *APITest {
	a.handler = handler
	return a
}
func (a *APITest) HandlerFunc(handlerFunc http.HandlerFunc) *APITest {
	a.handler = handlerFunc
	return a
}
func (a *APITest) Mocks(mocks ...*Mock) *APITest {
	var m []*Mock
	for i := range mocks {
		times := mocks[i].response.mock.times
		for j := 1; j <= times; j++ {
			mockCpy := mocks[i].copy()
			mockCpy.times = 1
			m = append(m, mockCpy)
		}
	}
	a.mocks = m
	return a
}
func (a *APITest) HttpClient(cli *http.Client) *APITest {
	a.httpClient = cli
	return a
}
func (a *APITest) Observe(observers ...Observe) *APITest {
	a.observers = observers
	return a
}
func (a *APITest) ObserveMocks(observer Observe) *APITest {
	a.mocksObservers = append(a.mocksObservers, observer)
	return a
}
func (a *APITest) RecorderHook(hook RecorderHook) *APITest {
	a.recorderHook = hook
	return a
}
func (a *APITest) Request() *Request {
	return a.request
}
func (a *APITest) Response() *Response {
	return a.response
}
type Request struct {
	interceptor     Intercept
	method          string
	url             string
	body            string
	query           map[string][]string
	queryCollection map[string][]string
	headers         map[string][]string
	formData        map[string][]string
	cookies         []*Cookie
	basicAuth       string
	apiTest         *APITest
}
type Intercept func(*http.Request)
type pair struct {
	l string
	r string
}
func (a *APITest) Intercept(interceptor Intercept) *APITest {
	a.request.interceptor = interceptor
	return a
}
func (a *APITest) Verifier(v Verifier) *APITest {
	a.verifier = v
	return a
}
func (a *APITest) Method(method string) *Request {
	a.request.method = method
	return a.request
}
func (a *APITest) HttpRequest(req *http.Request) *Request {
	a.httpRequest = req
	return a.request
}
func (a *APITest) Get(url string) *Request {
	a.request.method = http.MethodGet
	a.request.url = url
	return a.request
}
func (a *APITest) Getf(format string, args ...interface{}) *Request {
	return a.Get(fmt.Sprintf(format, args...))
}
func (a *APITest) Post(url string) *Request {
	r := a.request
	r.method = http.MethodPost
	r.url = url
	return r
}
func (a *APITest) Postf(format string, args ...interface{}) *Request {
	return a.Post(fmt.Sprintf(format, args...))
}
func (a *APITest) Put(url string) *Request {
	r := a.request
	r.method = http.MethodPut
	r.url = url
	return r
}
func (a *APITest) Putf(format string, args ...interface{}) *Request {
	return a.Put(fmt.Sprintf(format, args...))
}
func (a *APITest) Delete(url string) *Request {
	a.request.method = http.MethodDelete
	a.request.url = url
	return a.request
}
func (a *APITest) Deletef(format string, args ...interface{}) *Request {
	return a.Delete(fmt.Sprintf(format, args...))
}
func (a *APITest) Patch(url string) *Request {
	a.request.method = http.MethodPatch
	a.request.url = url
	return a.request
}
func (a *APITest) Patchf(format string, args ...interface{}) *Request {
	return a.Patch(fmt.Sprintf(format, args...))
}
func (r *Request) URL(url string) *Request {
	r.url = url
	return r
}
func (r *Request) URLf(format string, args ...interface{}) *Request {
	r.url = fmt.Sprintf(format, args...)
	return r
}
func (r *Request) Body(b string) *Request {
	r.body = b
	return r
}
func (r *Request) Bodyf(format string, args ...interface{}) *Request {
	r.body = fmt.Sprintf(format, args...)
	return r
}
func (r *Request) BodyFromFile(f string) *Request {
	b, err := ioutil.ReadFile(f)
	if err != nil {
		r.apiTest.t.Fatal(err)
	}
	r.body = string(b)
	return r
}
func (r *Request) JSON(v interface{}) *Request {
	switch x := v.(type) {
	case string:
		r.body = x
	case []byte:
		r.body = string(x)
	default:
		asJSON, err := json.Marshal(x)
		if err != nil {
			r.apiTest.t.Fatal(err)
			return nil
		}
		r.body = string(asJSON)
	}
	r.ContentType("application/json")
	return r
}
func (r *Request) JSONFromFile(f string) *Request {
	r.BodyFromFile(f)
	r.ContentType("application/json")
	return r
}
func (r *Request) GraphQLQuery(query string, variables ...map[string]interface{}) *Request {
	q := GraphQLRequestBody{
		Query: query,
	}
	if len(variables) > 0 {
		q.Variables = variables[0]
	}
	return r.GraphQLRequest(q)
}
func (r *Request) GraphQLRequest(body GraphQLRequestBody) *Request {
	r.ContentType("application/json")
	data, err := json.Marshal(body)
	if err != nil {
		r.apiTest.t.Fatal(err)
	}
	r.body = string(data)
	return r
}
type GraphQLRequestBody struct {
	Query         string                 `json:"query"`
	Variables     map[string]interface{} `json:"variables,omitempty"`
	OperationName string                 `json:"operationName,omitempty"`
}
func (r *Request) Query(key, value string) *Request {
	r.query[key] = append(r.query[key], value)
	return r
}
func (r *Request) QueryParams(params map[string]string) *Request {
	for k, v := range params {
		r.query[k] = append(r.query[k], v)
	}
	return r
}
func (r *Request) QueryCollection(q map[string][]string) *Request {
	r.queryCollection = q
	return r
}
func (r *Request) Header(key, value string) *Request {
	normalizedKey := textproto.CanonicalMIMEHeaderKey(key)
	r.headers[normalizedKey] = append(r.headers[normalizedKey], value)
	return r
}
func (r *Request) Headers(headers map[string]string) *Request {
	for k, v := range headers {
		normalizedKey := textproto.CanonicalMIMEHeaderKey(k)
		r.headers[normalizedKey] = append(r.headers[normalizedKey], v)
	}
	return r
}
func (r *Request) ContentType(contentType string) *Request {
	normalizedKey := textproto.CanonicalMIMEHeaderKey("Content-Type")
	r.headers[normalizedKey] = []string{contentType}
	return r
}
func (r *Request) Cookie(name, value string) *Request {
	r.cookies = append(r.cookies, &Cookie{name: &name, value: &value})
	return r
}
func (r *Request) Cookies(c ...*Cookie) *Request {
	r.cookies = append(r.cookies, c...)
	return r
}
func (r *Request) BasicAuth(username, password string) *Request {
	r.basicAuth = fmt.Sprintf("%s:%s", username, password)
	return r
}
func (r *Request) FormData(name string, values ...string) *Request {
	r.ContentType("application/x-www-form-urlencoded")
	r.formData[name] = append(r.formData[name], values...)
	return r
}
func (r *Request) Expect(t TestingT) *Response {
	r.apiTest.t = t
	return r.apiTest.response
}
type Response struct {
	status            int
	body              string
	headers           map[string][]string
	headersPresent    []string
	headersNotPresent []string
	cookies           []*Cookie
	cookiesPresent    []string
	cookiesNotPresent []string
	apiTest           *APITest
	assert            []Assert
}
type Assert func(*http.Response, *http.Request) error
func (r *Response) Body(b string) *Response {
	r.body = b
	return r
}
func (r *Response) Bodyf(format string, args ...interface{}) *Response {
	r.body = fmt.Sprintf(format, args...)
	return r
}
func (r *Response) BodyFromFile(f string) *Response {
	b, err := ioutil.ReadFile(f)
	if err != nil {
		r.apiTest.t.Fatal(err)
	}
	r.body = string(b)
	return r
}
func (r *Response) Cookies(cookies ...*Cookie) *Response {
	r.cookies = append(r.cookies, cookies...)
	return r
}
func (r *Response) Cookie(name, value string) *Response {
	r.cookies = append(r.cookies, NewCookie(name).Value(value))
	return r
}
func (r *Response) CookiePresent(cookieName string) *Response {
	r.cookiesPresent = append(r.cookiesPresent, cookieName)
	return r
}
func (r *Response) CookieNotPresent(cookieName string) *Response {
	r.cookiesNotPresent = append(r.cookiesNotPresent, cookieName)
	return r
}
func (r *Response) Header(key, value string) *Response {
	normalizedName := textproto.CanonicalMIMEHeaderKey(key)
	r.headers[normalizedName] = append(r.headers[normalizedName], value)
	return r
}
func (r *Response) HeaderPresent(name string) *Response {
	normalizedName := textproto.CanonicalMIMEHeaderKey(name)
	r.headersPresent = append(r.headersPresent, normalizedName)
	return r
}
func (r *Response) HeaderNotPresent(name string) *Response {
	normalizedName := textproto.CanonicalMIMEHeaderKey(name)
	r.headersNotPresent = append(r.headersNotPresent, normalizedName)
	return r
}
func (r *Response) Headers(headers map[string]string) *Response {
	for name, value := range headers {
		normalizedName := textproto.CanonicalMIMEHeaderKey(name)
		r.headers[normalizedName] = append(r.headers[textproto.CanonicalMIMEHeaderKey(normalizedName)], value)
	}
	return r
}
func (r *Response) Status(s int) *Response {
	r.status = s
	return r
}
func (r *Response) Assert(fn func(*http.Response, *http.Request) error) *Response {
	r.assert = append(r.assert, fn)
	return r.apiTest.response
}