func (me *Value) FillByTag(key string, getter Getter) error {
	fields := me.FieldsByTag(key)
	keyFunc := func(field Field) string {
		return field.TagValue
	}
	fillFunc := func(value *Value, getter Getter) error {
		return value.FillByTag(key, getter)
	}
	return me.fill(getter, fields, keyFunc, fillFunc)
}
FillByTag is the same as Fill() except the argument passed to Getter is the value of the struct-tag.
package set
import (
	"fmt"
	"reflect"
	"github.com/nofeaturesonlybugs/errors"
)
func V(arg interface{}) *Value {
	rv := &Value{}
	rv.original = arg
	var v reflect.Value
	switch tt := arg.(type) {
	case reflect.Value:
		v = tt
	default:
		v = reflect.ValueOf(arg)
	}
	if v.IsValid() {
		rv.TypeInfo = TypeCache.StatType(v.Type())
	}
	rv.WriteValue, rv.CanWrite = Writable(v)
	rv.TopValue = v
	if rv.IsMap || rv.IsSlice {
		rv.ElemTypeInfo = TypeCache.StatType(rv.ElemType)
	}
	return rv
}
type Value struct {
	TypeInfo
	CanWrite bool
	TopValue reflect.Value
	WriteValue reflect.Value
	ElemTypeInfo TypeInfo
	original interface{}
}
func (me *Value) errorUnsupported(method string) string {
	return fmt.Sprintf("%v is unsupported for original type [%T]", method, me.original)
}
func (me *Value) Append(items ...interface{}) error {
	if me == nil {
		return errors.NilReceiver()
	} else if me.Kind != reflect.Slice {
		return errors.Errorf(me.errorUnsupported("Append"))
	}
	var err error
	func() {
		defer func() {
			if r := recover(); r != nil {
				err = errors.Errorf("%v", r)
			}
		}()
		zero := reflect.Zero(me.Type)
		for _, item := range items {
			elem := reflect.New(me.ElemType)
			elemAsValue := V(elem)
			if err = elemAsValue.To(item); err != nil {
				err = errors.Go(err)
				return
			}
			zero = reflect.Append(zero, reflect.Indirect(elemAsValue.TopValue))
		}
		me.WriteValue.Set(reflect.AppendSlice(me.WriteValue, zero))
	}()
	return err
}
func (me *Value) Copy() *Value {
	rv := &Value{
		TypeInfo:     me.TypeInfo,
		CanWrite:     me.CanWrite,
		TopValue:     me.TopValue,
		WriteValue:   me.WriteValue,
		ElemTypeInfo: me.ElemTypeInfo,
		original:     me.original,
	}
	return rv
}
func (me *Value) Fields() []Field {
	if me == nil || me.Kind != reflect.Struct {
		return nil
	}
	var rv []Field
	if me != nil && me.IsStruct {
		for k, max := 0, me.Type.NumField(); k < max; k++ {
			v, f := me.WriteValue.Field(k), me.Type.Field(k)
			rv = append(rv, Field{Value: V(v), Field: f})
		}
	}
	return rv
}
func (me *Value) FieldByIndex(index []int) (reflect.Value, error) {
	v := reflect.Value{}
	size := len(index)
	if me == nil {
		return v, errors.NilReceiver()
	} else if !me.CanWrite {
		return v, errors.Errorf(me.errorUnsupported("FieldByIndex"))
	} else if size == 0 {
		return v, errors.Errorf("Zero length index provided to FieldByIndex()")
	}
	v = me.WriteValue
	for k := 0; k < size; k++ {
		n := index[k]  
		if v.Kind() != reflect.Struct {
			return v, errors.Errorf("FieldByIndex requires type to be a struct; type is %v", v.Type())
		} else if n > v.NumField() {
			return v, errors.Errorf("Index out of bounds; field is len %v and index is %v", v.NumField(), n)
		}
		v = v.Field(n)
		t, k := v.Type(), v.Kind()
		if k == reflect.Ptr {
			for k == reflect.Ptr {
				if v.IsNil() && v.CanSet() {
					ptr := reflect.New(t.Elem())
					v.Set(ptr)
					v = ptr
				}
				v = v.Elem()
				t, k = v.Type(), v.Kind()
			}
		}
	}
	return v, nil
}
func (me *Value) FieldByIndexAsValue(index []int) (*Value, error) {
	var v reflect.Value
	var err error
	if v, err = me.FieldByIndex(index); err != nil {
		return nil, errors.Go(err)
	}
	return V(v), nil
}
func (me *Value) FieldsByTag(key string) []Field {
	if me == nil || me.Kind != reflect.Struct {
		return nil
	}
	var rv []Field
	all := me.Fields()
	for _, f := range all {
		if value, ok := f.Field.Tag.Lookup(key); ok {
			f.TagValue = value
			rv = append(rv, f)
		}
	}
	return rv
}
func (me *Value) fill(getter Getter, fields []Field, keyFunc func(Field) string, fillFunc func(*Value, Getter) error) error {
	var err error
	for _, field := range fields {
		getName := keyFunc(field)
		switch got := getter.Get(getName).(type) {
		case Getter:
			if field.Value.IsStruct {
				if err = fillFunc(field.Value, got); err != nil {
					return errors.Go(err)
				}
			} else if field.Value.IsSlice && field.Value.ElemTypeInfo.IsStruct {
				if err = field.Value.Zero(); err != nil {
					return errors.Go(err)
				}
				elem := V(reflect.New(field.Value.ElemTypeInfo.Type))
				if err = fillFunc(elem, got); err != nil {
					return errors.Go(err)
				}
				field.Value.Append(elem.WriteValue.Interface())  
			} else {
				return errors.Errorf("Getter.Get( %v ) returned a Getter for field %v and field is not fillable.", getName, field.Field.Name)
			}
		case []Getter:
			if field.Value.IsSlice && field.Value.ElemTypeInfo.IsStruct {
				if err = field.Value.Zero(); err != nil {
					return errors.Go(err)
				}
				for _, elemGetter := range got {
					elem := V(reflect.New(field.Value.ElemTypeInfo.Type))
					if err = fillFunc(elem, elemGetter); err != nil {
						return errors.Go(err)
					}
					field.Value.Append(elem.WriteValue.Interface())  
				}
			} else if field.Value.IsStruct {
				size := len(got)
				if size > 0 {
					if err = fillFunc(field.Value, got[size-1]); err != nil {
						return errors.Go(err)
					}
				}
			} else {
				return errors.Errorf("Getter.Get( %v ) returned a []Getter for field %v and field is not fillable.", getName, field.Field.Name)
			}
		default:
			if err = field.Value.To(got); err != nil {
				return errors.Go(err)
			}
		}
	}
	return nil
}
func (me *Value) Fill(getter Getter) error {
	fields := me.Fields()
	keyFunc := func(field Field) string {
		return field.Field.Name
	}
	fillFunc := func(value *Value, getter Getter) error {
		return value.Fill(getter)
	}
	return me.fill(getter, fields, keyFunc, fillFunc)
}