func (me *boundMapping) Copy() BoundMapping {
	return &boundMapping{
		value: me.value.Copy(),
		err:   me.err,
		mapping: me.mapping,
	}
}
Copy creates an exact copy of the BoundMapping.  Since a BoundMapping is implicitly tied to a single
value sometimes it may be useful to create and cache a BoundMapping early in a program's initialization and
then call Copy() to work with multiple instances of bound values simultaneously.
package set
import (
	"fmt"
	"reflect"
	"sort"
	"strings"
	"sync"
	"time"
	"github.com/nofeaturesonlybugs/errors"
)
var mapperTreatAsScalar = map[reflect.Type]struct{}{
	reflect.TypeOf(time.Time{}):  {},
	reflect.TypeOf(&time.Time{}): {},
}
type Mapping struct {
	Keys []string
	Indeces map[string][]int
	StructFields map[string]reflect.StructField
}
type Mapper struct {
	Ignored TypeList
	Elevated TypeList
	TreatAsScalar TypeList
	Tags []string
	Join string
	Transform func(string) string
	known sync.Map
}
type BoundMapping interface {
	Assignables(fields []string, rv []interface{}) ([]interface{}, error)
	Copy() BoundMapping
	Err() error
	Field(field string) (*Value, error)
	Fields(fields []string, rv []interface{}) ([]interface{}, error)
	Rebind(I interface{})
	Set(field string, value interface{}) error
}
var DefaultMapper = &Mapper{
	Join: "_",
}
func (me *Mapper) Bind(I interface{}) BoundMapping {
	var v *Value
	if tv, ok := I.(*Value); ok {
		v = tv
	} else {
		v = V(I)
	}
	rv := newBoundMapping(v, me.Map(v))
	return rv
}
func (me *Mapper) Map(T interface{}) *Mapping {
	var typeInfo TypeInfo
	switch tt := T.(type) {
	case *Value:
		typeInfo = tt.TypeInfo
	case reflect.Type:
		typeInfo = TypeCache.StatType(tt)
	default:
		typeInfo = TypeCache.Stat(T)
	}
	if rv, ok := me.known.Load(typeInfo.Type); ok {
		return rv.(*Mapping)
	}
	rv := &Mapping{
		Keys:         []string{},
		Indeces:      map[string][]int{},
		StructFields: map[string]reflect.StructField{},
	}
	var scan func(typeInfo TypeInfo, indeces []int, prefix string)
	scan = func(typeInfo TypeInfo, indeces []int, prefix string) {
		for k, field := range typeInfo.StructFields {
			if field.PkgPath != "" {
				continue
			}
			fieldTypeInfo := TypeCache.StatType(field.Type)
			if me.Ignored.Has(fieldTypeInfo.Type) {
				continue
			}
			name := ""
			if !me.Elevated.Has(fieldTypeInfo.Type) {
				for _, tagName := range append(me.Tags, "") {
					if tagValue, ok := field.Tag.Lookup(tagName); ok {
						name = tagValue
						break
					} else if tagName == "" {
						name = field.Name
						if me.Transform != nil {
							name = me.Transform(name)
						}
						break
					}
				}
			}
			if prefix != "" && name != "" {
				name = prefix + me.Join + name
			} else if prefix != "" {
				name = prefix
			}
			nameIndeces := append(indeces, k)
			if _, ok := mapperTreatAsScalar[fieldTypeInfo.Type]; ok {
				rv.Keys, rv.Indeces[name], rv.StructFields[name] = append(rv.Keys, name), nameIndeces, field
			} else if _, ok = me.TreatAsScalar[fieldTypeInfo.Type]; ok {
				rv.Keys, rv.Indeces[name], rv.StructFields[name] = append(rv.Keys, name), nameIndeces, field
			} else if fieldTypeInfo.IsStruct {
				scan(fieldTypeInfo, nameIndeces, name)
			} else if fieldTypeInfo.IsScalar {
				rv.Keys, rv.Indeces[name], rv.StructFields[name] = append(rv.Keys, name), nameIndeces, field
			}
		}
	}
	scan(typeInfo, []int{}, "")
	me.known.Store(typeInfo.Type, rv)
	return rv
}
func (me *Mapping) Copy() *Mapping {
	rv := &Mapping{
		Keys:         append([]string{}, me.Keys...),
		Indeces:      map[string][]int{},
		StructFields: map[string]reflect.StructField{},
	}
	for _, key := range me.Keys {
		rv.Indeces[key] = append([]int{}, me.Indeces[key]...)
		rv.StructFields[key] = me.StructFields[key]
	}
	return rv
}
func (me *Mapping) Get(key string) []int {
	v, _ := me.Lookup(key)
	return v
}
func (me *Mapping) Lookup(key string) (indeces []int, ok bool) {
	if me == nil || me.Indeces == nil {
		return nil, false
	}
	indeces, ok = me.Indeces[key]
	return indeces, ok
}
func (me *Mapping) String() string {
	if me == nil {
		return ""
	}
	parts := []string{}
	for str, indeces := range me.Indeces {
		parts = append(parts, fmt.Sprintf("%v\t\t%v", indeces, str))
	}
	sort.Strings(parts)
	return strings.Join(parts, "\n")
}
type boundMapping struct {
	value *Value
	err   error
	mapping *Mapping
}
func newBoundMapping(value *Value, mapping *Mapping) *boundMapping {
	return &boundMapping{
		value:   value,
		mapping: mapping,
	}
}
func (me *boundMapping) Assignables(fields []string, rv []interface{}) ([]interface{}, error) {
	if !me.value.CanWrite {
		return nil, errors.Errorf("Value in BoundMapping is not writable; pass the address of your destination value when binding.")
	}
	if rv == nil {
		rv = make([]interface{}, len(fields))
	}
	for fieldnum, name := range fields {
		indeces := me.mapping.Get(name)
		if len(indeces) == 0 {
			return nil, errors.Errorf("No mapping for field [%v]", name)
		}
		v := me.value.WriteValue
		for k, size := 0, len(indeces); k < size; k++ {
			n := indeces[k]  
			if k < size-1 {
				v, _ = Writable(v.Field(n))
			} else {
				rv[fieldnum] = v.Field(n).Addr().Interface()
			}
		}
	}
	return rv, nil
}