func UnpatchAll() {
	lock.Lock()
	defer lock.Unlock()
	for target, p := range patches {
		unpatch(target, p)
		delete(patches, target)
	}
}
UnpatchAll removes all applied monkeypatches
package monkey
import (
	"fmt"
	"reflect"
	"sync"
	"unsafe"
)
type patch struct {
	originalBytes []byte
	replacement   *reflect.Value
}
var (
	lock = sync.Mutex{}
	patches = make(map[reflect.Value]patch)
)
type value struct {
	_   uintptr
	ptr unsafe.Pointer
}
func getPtr(v reflect.Value) unsafe.Pointer {
	return (*value)(unsafe.Pointer(&v)).ptr
}
type PatchGuard struct {
	target      reflect.Value
	replacement reflect.Value
}
func (g *PatchGuard) Unpatch() {
	unpatchValue(g.target)
}
func (g *PatchGuard) Restore() {
	patchValue(g.target, g.replacement)
}
func Patch(target, replacement interface{}) *PatchGuard {
	t := reflect.ValueOf(target)
	r := reflect.ValueOf(replacement)
	patchValue(t, r)
	return &PatchGuard{t, r}
}
func PatchInstanceMethod(target reflect.Type, methodName string, replacement interface{}) *PatchGuard {
	m, ok := target.MethodByName(methodName)
	if !ok {
		panic(fmt.Sprintf("unknown method %s", methodName))
	}
	r := reflect.ValueOf(replacement)
	patchValue(m.Func, r)
	return &PatchGuard{m.Func, r}
}
func patchValue(target, replacement reflect.Value) {
	lock.Lock()
	defer lock.Unlock()
	if target.Kind() != reflect.Func {
		panic("target has to be a Func")
	}
	if replacement.Kind() != reflect.Func {
		panic("replacement has to be a Func")
	}
	if target.Type() != replacement.Type() {
		panic(fmt.Sprintf("target and replacement have to have the same type %s != %s", target.Type(), replacement.Type()))
	}
	if patch, ok := patches[target]; ok {
		unpatch(target, patch)
	}
	bytes := replaceFunction(*(*uintptr)(getPtr(target)), uintptr(getPtr(replacement)))
	patches[target] = patch{bytes, &replacement}
}
func Unpatch(target interface{}) bool {
	return unpatchValue(reflect.ValueOf(target))
}
func UnpatchInstanceMethod(target reflect.Type, methodName string) bool {
	m, ok := target.MethodByName(methodName)
	if !ok {
		panic(fmt.Sprintf("unknown method %s", methodName))
	}
	return unpatchValue(m.Func)
}