hunk.code_window: 		mockStore.Emoji().(*mocks.EmojiStore).AssertNumberOfCalls(t, "Get", 2)
   	})
   	t.Run("first call by name force no cached, second not cached, third cached", func(t *testing.T) {
   		mockStore := getMockStore()
   		cachedStore := NewLocalCacheLayer(mockStore, nil, nil)
  
hunk.labels: keep keep keep replace keep keep keep
hunk.after_edit: 	t.Run("first call by name force not cached, second not cached, third cached", func(t *testing.T) {
  
hunk.file_path: store/localcachelayer/emoji_layer_test.go
hunk.type: replace
file: // Copyright (c) 2012, 2013 Ugorji Nwoke. All rights reserved.
  // Use of this source code is governed by a BSD-style license found in the LICENSE file.
  
  package codec
  
  import (
  	"io"
  	"reflect"
  	// "runtime/debug"
  )
  
  // Some tagging information for error messages.
  const (
  	msgTagDec             = "codec.decoder"
  	msgBadDesc            = "Unrecognized descriptor byte"
  	msgDecCannotExpandArr = "cannot expand go array from %v to stream length: %v"
  )
  
  // decReader abstracts the reading source, allowing implementations that can
  // read from an io.Reader or directly off a byte slice with zero-copying.
  type decReader interface {
  	readn(n int) []byte
  	readb([]byte)
  	readn1() uint8
  	readUint16() uint16
  	readUint32() uint32
  	readUint64() uint64
  }
  
  type decDriver interface {
  	initReadNext()
  	tryDecodeAsNil() bool
  	currentEncodedType() valueType
  	isBuiltinType(rt uintptr) bool
  	decodeBuiltin(rt uintptr, v interface{})
  	//decodeNaked: Numbers are decoded as int64, uint64, float64 only (no smaller sized number types).
  	decodeNaked() (v interface{}, vt valueType, decodeFurther bool)
  	decodeInt(bitsize uint8) (i int64)
  	decodeUint(bitsize uint8) (ui uint64)
  	decodeFloat(chkOverflow32 bool) (f float64)
  	decodeBool() (b bool)
  	// decodeString can also decode symbols
  	decodeString() (s string)
  	decodeBytes(bs []byte) (bsOut []byte, changed bool)
  	decodeExt(verifyTag bool, tag byte) (xtag byte, xbs []byte)
  	readMapLen() int
  	readArrayLen() int
  }
  
  type DecodeOptions struct {
  	// An instance of MapType is used during schema-less decoding of a map in the stream.
  	// If nil, we use map[interface{}]interface{}
  	MapType reflect.Type
  	// An instance of SliceType is used during schema-less decoding of an array in the stream.
  	// If nil, we use []interface{}
  	SliceType reflect.Type
  	// ErrorIfNoField controls whether an error is returned when decoding a map
  	// from a codec stream into a struct, and no matching struct field is found.
  	ErrorIfNoField bool
  }
  
  // ------------------------------------
  
  // ioDecReader is a decReader that reads off an io.Reader
  type ioDecReader struct {
  	r  io.Reader
  	br io.ByteReader
  	x  [8]byte //temp byte array re-used internally for efficiency
  }
  
  func (z *ioDecReader) readn(n int) (bs []byte) {
  	if n <= 0 {
  		return
  	}
  	bs = make([]byte, n)
  	if _, err := io.ReadAtLeast(z.r, bs, n); err != nil {
  		panic(err)
  	}
  	return
  }
  
  func (z *ioDecReader) readb(bs []byte) {
  	if _, err := io.ReadAtLeast(z.r, bs, len(bs)); err != nil {
  		panic(err)
  	}
  }
  
  func (z *ioDecReader) readn1() uint8 {
  	if z.br != nil {
  		b, err := z.br.ReadByte()
  		if err != nil {
  			panic(err)
  		}
  		return b
  	}
  	z.readb(z.x[:1])
  	return z.x[0]
  }
  
  func (z *ioDecReader) readUint16() uint16 {
  	z.readb(z.x[:2])
  	return bigen.Uint16(z.x[:2])
  }
  
  func (z *ioDecReader) readUint32() uint32 {
  	z.readb(z.x[:4])
  	return bigen.Uint32(z.x[:4])
  }
  
  func (z *ioDecReader) readUint64() uint64 {
  	z.readb(z.x[:8])
  	return bigen.Uint64(z.x[:8])
  }
  
  // ------------------------------------
  
  // bytesDecReader is a decReader that reads off a byte slice with zero copying
  type bytesDecReader struct {
  	b []byte // data
  	c int    // cursor
  	a int    // available
  }
  
  func (z *bytesDecReader) consume(n int) (oldcursor int) {
  	if z.a == 0 {
  		panic(io.EOF)
  	}
  	if n > z.a {
  		decErr("Trying to read %v bytes. Only %v available", n, z.a)
  	}
  	// z.checkAvailable(n)
  	oldcursor = z.c
  	z.c = oldcursor + n
  	z.a = z.a - n
  	return
  }
  
  func (z *bytesDecReader) readn(n int) (bs []byte) {
  	if n <= 0 {
  		return
  	}
  	c0 := z.consume(n)
  	bs = z.b[c0:z.c]
  	return
  }
  
  func (z *bytesDecReader) readb(bs []byte) {
  	copy(bs, z.readn(len(bs)))
  }
  
  func (z *bytesDecReader) readn1() uint8 {
  	c0 := z.consume(1)
  	return z.b[c0]
  }
  
  // Use binaryEncoding helper for 4 and 8 bits, but inline it for 2 bits
  // creating temp slice variable and copying it to helper function is expensive
  // for just 2 bits.
  
  func (z *bytesDecReader) readUint16() uint16 {
  	c0 := z.consume(2)
  	return uint16(z.b[c0+1]) | uint16(z.b[c0])<<8
  }
  
  func (z *bytesDecReader) readUint32() uint32 {
  	c0 := z.consume(4)
  	return bigen.Uint32(z.b[c0:z.c])
  }
  
  func (z *bytesDecReader) readUint64() uint64 {
  	c0 := z.consume(8)
  	return bigen.Uint64(z.b[c0:z.c])
  }
  
  // ------------------------------------
  
  // decFnInfo has methods for registering handling decoding of a specific type
  // based on some characteristics (builtin, extension, reflect Kind, etc)
  type decFnInfo struct {
  	ti    *typeInfo
  	d     *Decoder
  	dd    decDriver
  	xfFn  func(reflect.Value, []byte) error
  	xfTag byte
  	array bool
  }
  
  func (f *decFnInfo) builtin(rv reflect.Value) {
  	f.dd.decodeBuiltin(f.ti.rtid, rv.Addr().Interface())
  }
  
  func (f *decFnInfo) rawExt(rv reflect.Value) {
  	xtag, xbs := f.dd.decodeExt(false, 0)
  	rv.Field(0).SetUint(uint64(xtag))
  	rv.Field(1).SetBytes(xbs)
  }
  
  func (f *decFnInfo) ext(rv reflect.Value) {
  	_, xbs := f.dd.decodeExt(true, f.xfTag)
  	if fnerr := f.xfFn(rv, xbs); fnerr != nil {
  		panic(fnerr)
  	}
  }
  
  func (f *decFnInfo) binaryMarshal(rv reflect.Value) {
  	var bm binaryUnmarshaler
  	if f.ti.unmIndir == -1 {
  		bm = rv.Addr().Interface().(binaryUnmarshaler)
  	} else if f.ti.unmIndir == 0 {
  		bm = rv.Interface().(binaryUnmarshaler)
  	} else {
  		for j, k := int8(0), f.ti.unmIndir; j < k; j++ {
  			if rv.IsNil() {
  				rv.Set(reflect.New(rv.Type().Elem()))
  			}
  			rv = rv.Elem()
  		}
  		bm = rv.Interface().(binaryUnmarshaler)
  	}
  	xbs, _ := f.dd.decodeBytes(nil)
  	if fnerr := bm.UnmarshalBinary(xbs); fnerr != nil {
  		panic(fnerr)
  	}
  }
  
  func (f *decFnInfo) kErr(rv reflect.Value) {
  	decErr("Unhandled value for kind: %v: %s", rv.Kind(), msgBadDesc)
  }
  
  func (f *decFnInfo) kString(rv reflect.Value) {
  	rv.SetString(f.dd.decodeString())
  }
  
  func (f *decFnInfo) kBool(rv reflect.Value) {
  	rv.SetBool(f.dd.decodeBool())
  }
  
  func (f *decFnInfo) kInt(rv reflect.Value) {
  	rv.SetInt(f.dd.decodeInt(intBitsize))
  }
  
  func (f *decFnInfo) kInt64(rv reflect.Value) {
  	rv.SetInt(f.dd.decodeInt(64))
  }
  
  func (f *decFnInfo) kInt32(rv reflect.Value) {
  	rv.SetInt(f.dd.decodeInt(32))
  }
  
  func (f *decFnInfo) kInt8(rv reflect.Value) {
  	rv.SetInt(f.dd.decodeInt(8))
  }
  
  func (f *decFnInfo) kInt16(rv reflect.Value) {
  	rv.SetInt(f.dd.decodeInt(16))
  }
  
  func (f *decFnInfo) kFloat32(rv reflect.Value) {
  	rv.SetFloat(f.dd.decodeFloat(true))
  }
  
  func (f *decFnInfo) kFloat64(rv reflect.Value) {
  	rv.SetFloat(f.dd.decodeFloat(false))
  }
  
  func (f *decFnInfo) kUint8(rv reflect.Value) {
  	rv.SetUint(f.dd.decodeUint(8))
  }
  
  func (f *decFnInfo) kUint64(rv reflect.Value) {
  	rv.SetUint(f.dd.decodeUint(64))
  }
  
  func (f *decFnInfo) kUint(rv reflect.Value) {
  	rv.SetUint(f.dd.decodeUint(uintBitsize))
  }
  
  func (f *decFnInfo) kUint32(rv reflect.Value) {
  	rv.SetUint(f.dd.decodeUint(32))
  }
  
  func (f *decFnInfo) kUint16(rv reflect.Value) {
  	rv.SetUint(f.dd.decodeUint(16))
  }
  
  // func (f *decFnInfo) kPtr(rv reflect.Value) {
  // 	debugf(">>>>>>> ??? decode kPtr called - shouldn't get called")
  // 	if rv.IsNil() {
  // 		rv.Set(reflect.New(rv.Type().Elem()))
  // 	}
  // 	f.d.decodeValue(rv.Elem())
  // }
  
  func (f *decFnInfo) kInterface(rv reflect.Value) {
  	// debugf("\t===> kInterface")
  	if !rv.IsNil() {
  		f.d.decodeValue(rv.Elem())
  		return
  	}
  	// nil interface:
  	// use some hieristics to set the nil interface to an
  	// appropriate value based on the first byte read (byte descriptor bd)
  	v, vt, decodeFurther := f.dd.decodeNaked()
  	if vt == valueTypeNil {
  		return
  	}
  	// Cannot decode into nil interface with methods (e.g. error, io.Reader, etc)
  	// if non-nil value in stream.
  	if num := f.ti.rt.NumMethod(); num > 0 {
  		decErr("decodeValue: Cannot decode non-nil codec value into nil %v (%v methods)",
  			f.ti.rt, num)
  	}
  	var rvn reflect.Value
  	var useRvn bool
  	switch vt {
  	case valueTypeMap:
  		if f.d.h.MapType == nil {
  			var m2 map[interface{}]interface{}
  			v = &m2
  		} else {
  			rvn = reflect.New(f.d.h.MapType).Elem()
  			useRvn = true
  		}
  	case valueTypeArray:
  		if f.d.h.SliceType == nil {
  			var m2 []interface{}
  			v = &m2
  		} else {
  			rvn = reflect.New(f.d.h.SliceType).Elem()
  			useRvn = true
  		}
  	case valueTypeExt:
  		re := v.(*RawExt)
  		var bfn func(reflect.Value, []byte) error
  		rvn, bfn = f.d.h.getDecodeExtForTag(re.Tag)
  		if bfn == nil {
  			rvn = reflect.ValueOf(*re)
  		} else if fnerr := bfn(rvn, re.Data); fnerr != nil {
  			panic(fnerr)
  		}
  		rv.Set(rvn)
  		return
  	}
  	if decodeFurther {
  		if useRvn {
  			f.d.decodeValue(rvn)
  		} else if v != nil {
  			// this v is a pointer, so we need to dereference it when done
  			f.d.decode(v)
  			rvn = reflect.ValueOf(v).Elem()
  			useRvn = true
  		}
  	}
  	if useRvn {
  		rv.Set(rvn)
  	} else if v != nil {
  		rv.Set(reflect.ValueOf(v))
  	}
  }
  
  func (f *decFnInfo) kStruct(rv reflect.Value) {
  	fti := f.ti
  	if currEncodedType := f.dd.currentEncodedType(); currEncodedType == valueTypeMap {
  		containerLen := f.dd.readMapLen()
  		if containerLen == 0 {
  			return
  		}
  		tisfi := fti.sfi
  		for j := 0; j < containerLen; j++ {
  			// var rvkencname string
  			// ddecode(&rvkencname)
  			f.dd.initReadNext()
  			rvkencname := f.dd.decodeString()
  			// rvksi := ti.getForEncName(rvkencname)
  			if k := fti.indexForEncName(rvkencname); k > -1 {
  				sfik := tisfi[k]
  				if sfik.i != -1 {
  					f.d.decodeValue(rv.Field(int(sfik.i)))
  				} else {
  					f.d.decEmbeddedField(rv, sfik.is)
  				}
  				// f.d.decodeValue(ti.field(k, rv))
  			} else {
  				if f.d.h.ErrorIfNoField {
  					decErr("No matching struct field found when decoding stream map with key: %v",
  						rvkencname)
  				} else {
  					var nilintf0 interface{}
  					f.d.decodeValue(reflect.ValueOf(&nilintf0).Elem())
  				}
  			}
  		}
  	} else if currEncodedType == valueTypeArray {
  		containerLen := f.dd.readArrayLen()
  		if containerLen == 0 {
  			return
  		}
  		for j, si := range fti.sfip {
  			if j == containerLen {
  				break
  			}
  			if si.i != -1 {
  				f.d.decodeValue(rv.Field(int(si.i)))
  			} else {
  				f.d.decEmbeddedField(rv, si.is)
  			}
  		}
  		if containerLen > len(fti.sfip) {
  			// read remaining values and throw away
  			for j := len(fti.sfip); j < containerLen; j++ {
  				var nilintf0 interface{}
  				f.d.decodeValue(reflect.ValueOf(&nilintf0).Elem())
  			}
  		}
  	} else {
  		decErr("Only encoded map or array can be decoded into a struct. (valueType: %x)",
  			currEncodedType)
  	}
  }
  
  func (f *decFnInfo) kSlice(rv reflect.Value) {
  	// A slice can be set from a map or array in stream.
  	currEncodedType := f.dd.currentEncodedType()
  
  	switch currEncodedType {
  	case valueTypeBytes, valueTypeString:
  		if f.ti.rtid == uint8SliceTypId || f.ti.rt.Elem().Kind() == reflect.Uint8 {
  			if bs2, changed2 := f.dd.decodeBytes(rv.Bytes()); changed2 {
  				rv.SetBytes(bs2)
  			}
  			return
  		}
  	}
  
  	if shortCircuitReflectToFastPath && rv.CanAddr() {
  		switch f.ti.rtid {
  		case intfSliceTypId:
  			f.d.decSliceIntf(rv.Addr().Interface().(*[]interface{}), currEncodedType, f.array)
  			return
  		case uint64SliceTypId:
  			f.d.decSliceUint64(rv.Addr().Interface().(*[]uint64), currEncodedType, f.array)
  			return
  		case int64SliceTypId:
  			f.d.decSliceInt64(rv.Addr().Interface().(*[]int64), currEncodedType, f.array)
  			return
  		case strSliceTypId:
  			f.d.decSliceStr(rv.Addr().Interface().(*[]string), currEncodedType, f.array)
  			return
  		}
  	}
  
  	containerLen, containerLenS := decContLens(f.dd, currEncodedType)
  
  	// an array can never return a nil slice. so no need to check f.array here.
  
  	if rv.IsNil() {
  		rv.Set(reflect.MakeSlice(f.ti.rt, containerLenS, containerLenS))
  	}
  
  	if containerLen == 0 {
  		return
  	}
  
  	if rvcap, rvlen := rv.Len(), rv.Cap(); containerLenS > rvcap {
  		if f.array { // !rv.CanSet()
  			decErr(msgDecCannotExpandArr, rvcap, containerLenS)
  		}
  		rvn := reflect.MakeSlice(f.ti.rt, containerLenS, containerLenS)
  		if rvlen > 0 {
  			reflect.Copy(rvn, rv)
  		}
  		rv.Set(rvn)
  	} else if containerLenS > rvlen {
  		rv.SetLen(containerLenS)
  	}
  
  	for j := 0; j < containerLenS; j++ {
  		f.d.decodeValue(rv.Index(j))
  	}
  }
  
  func (f *decFnInfo) kArray(rv reflect.Value) {
  	// f.d.decodeValue(rv.Slice(0, rv.Len()))
  	f.kSlice(rv.Slice(0, rv.Len()))
  }
  
  func (f *decFnInfo) kMap(rv reflect.Value) {
  	if shortCircuitReflectToFastPath && rv.CanAddr() {
  		switch f.ti.rtid {
  		case mapStrIntfTypId:
  			f.d.decMapStrIntf(rv.Addr().Interface().(*map[string]interface{}))
  			return
  		case mapIntfIntfTypId:
  			f.d.decMapIntfIntf(rv.Addr().Interface().(*map[interface{}]interface{}))
  			return
  		case mapInt64IntfTypId:
  			f.d.decMapInt64Intf(rv.Addr().Interface().(*map[int64]interface{}))
  			return
  		case mapUint64IntfTypId:
  			f.d.decMapUint64Intf(rv.Addr().Interface().(*map[uint64]interface{}))
  			return
  		}
  	}
  
  	containerLen := f.dd.readMapLen()
  
  	if rv.IsNil() {
  		rv.Set(reflect.MakeMap(f.ti.rt))
  	}
  
  	if containerLen == 0 {
  		return
  	}
  
  	ktype, vtype := f.ti.rt.Key(), f.ti.rt.Elem()
  	ktypeId := reflect.ValueOf(ktype).Pointer()
  	for j := 0; j < containerLen; j++ {
  		rvk := reflect.New(ktype).Elem()
  		f.d.decodeValue(rvk)
  
  		// special case if a byte array.
  		// if ktype == intfTyp {
  		if ktypeId == intfTypId {
  			rvk = rvk.Elem()
  			if rvk.Type() == uint8SliceTyp {
  				rvk = reflect.ValueOf(string(rvk.Bytes()))
  			}
  		}
  		rvv := rv.MapIndex(rvk)
  		if !rvv.IsValid() || !rvv.CanSet() {
  			rvv = reflect.New(vtype).Elem()
  		}
  
  		f.d.decodeValue(rvv)
  		rv.SetMapIndex(rvk, rvv)
  	}
  }
  
  // ----------------------------------------
  
  type decFn struct {
  	i *decFnInfo
  	f func(*decFnInfo, reflect.Value)
  }
  
  // A Decoder reads and decodes an object from an input stream in the codec format.
  type Decoder struct {
  	r decReader
  	d decDriver
  	h *BasicHandle
  	f map[uintptr]decFn
  	x []uintptr
  	s []decFn
  }
  
  // NewDecoder returns a Decoder for decoding a stream of bytes from an io.Reader.
  //
  // For efficiency, Users are encouraged to pass in a memory buffered writer
  // (eg bufio.Reader, bytes.Buffer).
  func NewDecoder(r io.Reader, h Handle) *Decoder {
  	z := ioDecReader{
  		r: r,
  	}
  	z.br, _ = r.(io.ByteReader)
  	return &Decoder{r: &z, d: h.newDecDriver(&z), h: h.getBasicHandle()}
  }
  
  // NewDecoderBytes returns a Decoder which efficiently decodes directly
  // from a byte slice with zero copying.
  func NewDecoderBytes(in []byte, h Handle) *Decoder {
  	z := bytesDecReader{
  		b: in,
  		a: len(in),
  	}
  	return &Decoder{r: &z, d: h.newDecDriver(&z), h: h.getBasicHandle()}
  }
  
  // Decode decodes the stream from reader and stores the result in the
  // value pointed to by v. v cannot be a nil pointer. v can also be
  // a reflect.Value of a pointer.
  //
  // Note that a pointer to a nil interface is not a nil pointer.
  // If you do not know what type of stream it is, pass in a pointer to a nil interface.
  // We will decode and store a value in that nil interface.
  //
  // Sample usages:
  //   // Decoding into a non-nil typed value
  //   var f float32
  //   err = codec.NewDecoder(r, handle).Decode(&f)
  //
  //   // Decoding into nil interface
  //   var v interface{}
  //   dec := codec.NewDecoder(r, handle)
  //   err = dec.Decode(&v)
  //
  // When decoding into a nil interface{}, we will decode into an appropriate value based
  // on the contents of the stream:
  //   - Numbers are decoded as float64, int64 or uint64.
  //   - Other values are decoded appropriately depending on the type:
  //     bool, string, []byte, time.Time, etc
  //   - Extensions are decoded as RawExt (if no ext function registered for the tag)
  // Configurations exist on the Handle to override defaults
  // (e.g. for MapType, SliceType and how to decode raw bytes).
  //
  // When decoding into a non-nil interface{} value, the mode of encoding is based on the
  // type of the value. When a value is seen:
  //   - If an extension is registered for it, call that extension function
  //   - If it implements BinaryUnmarshaler, call its UnmarshalBinary(data []byte) error
  //   - Else decode it based on its reflect.Kind
  //
  // There are some special rules when decoding into containers (slice/array/map/struct).
  // Decode will typically use the stream contents to UPDATE the container.
  //   - A map can be decoded from a stream map, by updating matching keys.
  //   - A slice can be decoded from a stream array,
  //     by updating the first n elements, where n is length of the stream.
  //   - A slice can be decoded from a stream map, by decoding as if
  //     it contains a sequence of key-value pairs.
  //   - A struct can be decoded from a stream map, by updating matching fields.
  //   - A struct can be decoded from a stream array,
  //     by updating fields as they occur in the struct (by index).
  //
  // When decoding a stream map or array with length of 0 into a nil map or slice,
  // we reset the destination map or slice to a zero-length value.
  //
  // However, when decoding a stream nil, we reset the destination container
  // to its "zero" value (e.g. nil for slice/map, etc).
  //
  func (d *Decoder) Decode(v interface{}) (err error) {
  	defer panicToErr(&err)
  	d.decode(v)
  	return
  }
  
  func (d *Decoder) decode(iv interface{}) {
  	d.d.initReadNext()
  
  	switch v := iv.(type) {
  	case nil:
  		decErr("Cannot decode into nil.")
  
  	case reflect.Value:
  		d.chkPtrValue(v)
  		d.decodeValue(v.Elem())
  
  	case *string:
  		*v = d.d.decodeString()
  	case *bool:
  		*v = d.d.decodeBool()
  	case *int:
  		*v = int(d.d.decodeInt(intBitsize))
  	case *int8:
  		*v = int8(d.d.decodeInt(8))
  	case *int16:
  		*v = int16(d.d.decodeInt(16))
  	case *int32:
  		*v = int32(d.d.decodeInt(32))
  	case *int64:
  		*v = d.d.decodeInt(64)
  	case *uint:
  		*v = uint(d.d.decodeUint(uintBitsize))
  	case *uint8:
  		*v = uint8(d.d.decodeUint(8))
  	case *uint16:
  		*v = uint16(d.d.decodeUint(16))
  	case *uint32:
  		*v = uint32(d.d.decodeUint(32))
  	case *uint64:
  		*v = d.d.decodeUint(64)
  	case *float32:
  		*v = float32(d.d.decodeFloat(true))
  	case *float64:
  		*v = d.d.decodeFloat(false)
  	case *[]byte:
  		*v, _ = d.d.decodeBytes(*v)
  
  	case *[]interface{}:
  		d.decSliceIntf(v, valueTypeInvalid, false)
  	case *[]uint64:
  		d.decSliceUint64(v, valueTypeInvalid, false)
  	case *[]int64:
  		d.decSliceInt64(v, valueTypeInvalid, false)
  	case *[]string:
  		d.decSliceStr(v, valueTypeInvalid, false)
  	case *map[string]interface{}:
  		d.decMapStrIntf(v)
  	case *map[interface{}]interface{}:
  		d.decMapIntfIntf(v)
  	case *map[uint64]interface{}:
  		d.decMapUint64Intf(v)
  	case *map[int64]interface{}:
  		d.decMapInt64Intf(v)
  
  	case *interface{}:
  		d.decodeValue(reflect.ValueOf(iv).Elem())
  
  	default:
  		rv := reflect.ValueOf(iv)
  		d.chkPtrValue(rv)
  		d.decodeValue(rv.Elem())
  	}
  }
  
  func (d *Decoder) decodeValue(rv reflect.Value) {
  	d.d.initReadNext()
  
  	if d.d.tryDecodeAsNil() {
  		// If value in stream is nil, set the dereferenced value to its "zero" value (if settable)
  		if rv.Kind() == reflect.Ptr {
  			if !rv.IsNil() {
  				rv.Set(reflect.Zero(rv.Type()))
  			}
  			return
  		}
  		// for rv.Kind() == reflect.Ptr {
  		// 	rv = rv.Elem()
  		// }
  		if rv.IsValid() { // rv.CanSet() // always settable, except it's invalid
  			rv.Set(reflect.Zero(rv.Type()))
  		}
  		return
  	}
  
  	// If stream is not containing a nil value, then we can deref to the base
  	// non-pointer value, and decode into that.
  	for rv.Kind() == reflect.Ptr {
  		if rv.IsNil() {
  			rv.Set(reflect.New(rv.Type().Elem()))
  		}
  		rv = rv.Elem()
  	}
  
  	rt := rv.Type()
  	rtid := reflect.ValueOf(rt).Pointer()
  
  	// retrieve or register a focus'ed function for this type
  	// to eliminate need to do the retrieval multiple times
  
  	// if d.f == nil && d.s == nil { debugf("---->Creating new dec f map for type: %v\n", rt) }
  	var fn decFn
  	var ok bool
  	if useMapForCodecCache {
  		fn, ok = d.f[rtid]
  	} else {
  		for i, v := range d.x {
  			if v == rtid {
  				fn, ok = d.s[i], true
  				break
  			}
  		}
  	}
  	if !ok {
  		// debugf("\tCreating new dec fn for type: %v\n", rt)
  		fi := decFnInfo{ti: getTypeInfo(rtid, rt), d: d, dd: d.d}
  		fn.i = &fi
  		// An extension can be registered for any type, regardless of the Kind
  		// (e.g. type BitSet int64, type MyStruct { / * unexported fields * / }, type X []int, etc.
  		//
  		// We can't check if it's an extension byte here first, because the user may have
  		// registered a pointer or non-pointer type, meaning we may have to recurse first
  		// before matching a mapped type, even though the extension byte is already detected.
  		//
  		// NOTE: if decoding into a nil interface{}, we return a non-nil
  		// value except even if the container registers a length of 0.
  		if rtid == rawExtTypId {
  			fn.f = (*decFnInfo).rawExt
  		} else if d.d.isBuiltinType(rtid) {
  			fn.f = (*decFnInfo).builtin
  		} else if xfTag, xfFn := d.h.getDecodeExt(rtid); xfFn != nil {
  			fi.xfTag, fi.xfFn = xfTag, xfFn
  			fn.f = (*decFnInfo).ext
  		} else if supportBinaryMarshal && fi.ti.unm {
  			fn.f = (*decFnInfo).binaryMarshal
  		} else {
  			switch rk := rt.Kind(); rk {
  			case reflect.String:
  				fn.f = (*decFnInfo).kString
  			case reflect.Bool:
  				fn.f = (*decFnInfo).kBool
  			case reflect.Int:
  				fn.f = (*decFnInfo).kInt
  			case reflect.Int64:
  				fn.f = (*decFnInfo).kInt64
  			case reflect.Int32:
  				fn.f = (*decFnInfo).kInt32
  			case reflect.Int8:
  				fn.f = (*decFnInfo).kInt8
  			case reflect.Int16:
  				fn.f = (*decFnInfo).kInt16
  			case reflect.Float32:
  				fn.f = (*decFnInfo).kFloat32
  			case reflect.Float64:
  				fn.f = (*decFnInfo).kFloat64
  			case reflect.Uint8:
  				fn.f = (*decFnInfo).kUint8
  			case reflect.Uint64:
  				fn.f = (*decFnInfo).kUint64
  			case reflect.Uint:
  				fn.f = (*decFnInfo).kUint
  			case reflect.Uint32:
  				fn.f = (*decFnInfo).kUint32
  			case reflect.Uint16:
  				fn.f = (*decFnInfo).kUint16
  			// case reflect.Ptr:
  			// 	fn.f = (*decFnInfo).kPtr
  			case reflect.Interface:
  				fn.f = (*decFnInfo).kInterface
  			case reflect.Struct:
  				fn.f = (*decFnInfo).kStruct
  			case reflect.Slice:
  				fn.f = (*decFnInfo).kSlice
  			case reflect.Array:
  				fi.array = true
  				fn.f = (*decFnInfo).kArray
  			case reflect.Map:
  				fn.f = (*decFnInfo).kMap
  			default:
  				fn.f = (*decFnInfo).kErr
  			}
  		}
  		if useMapForCodecCache {
  			if d.f == nil {
  				d.f = make(map[uintptr]decFn, 16)
  			}
  			d.f[rtid] = fn
  		} else {
  			d.s = append(d.s, fn)
  			d.x = append(d.x, rtid)
  		}
  	}
  
  	fn.f(fn.i, rv)
  
  	return
  }
  
  func (d *Decoder) chkPtrValue(rv reflect.Value) {
  	// We can only decode into a non-nil pointer
  	if rv.Kind() == reflect.Ptr && !rv.IsNil() {
  		return
  	}
  	if !rv.IsValid() {
  		decErr("Cannot decode into a zero (ie invalid) reflect.Value")
  	}
  	if !rv.CanInterface() {
  		decErr("Cannot decode into a value without an interface: %v", rv)
  	}
  	rvi := rv.Interface()
  	decErr("Cannot decode into non-pointer or nil pointer. Got: %v, %T, %v",
  		rv.Kind(), rvi, rvi)
  }
  
  func (d *Decoder) decEmbeddedField(rv reflect.Value, index []int) {
  	// d.decodeValue(rv.FieldByIndex(index))
  	// nil pointers may be here; so reproduce FieldByIndex logic + enhancements
  	for _, j := range index {
  		if rv.Kind() == reflect.Ptr {
  			if rv.IsNil() {
  				rv.Set(reflect.New(rv.Type().Elem()))
  			}
  			// If a pointer, it must be a pointer to struct (based on typeInfo contract)
  			rv = rv.Elem()
  		}
  		rv = rv.Field(j)
  	}
  	d.decodeValue(rv)
  }
  
  // --------------------------------------------------
  
  // short circuit functions for common maps and slices
  
  func (d *Decoder) decSliceIntf(v *[]interface{}, currEncodedType valueType, doNotReset bool) {
  	_, containerLenS := decContLens(d.d, currEncodedType)
  	s := *v
  	if s == nil {
  		s = make([]interface{}, containerLenS, containerLenS)
  	} else if containerLenS > cap(s) {
  		if doNotReset {
  			decErr(msgDecCannotExpandArr, cap(s), containerLenS)
  		}
  		s = make([]interface{}, containerLenS, containerLenS)
  		copy(s, *v)
  	} else if containerLenS > len(s) {
  		s = s[:containerLenS]
  	}
  	for j := 0; j < containerLenS; j++ {
  		d.decode(&s[j])
  	}
  	*v = s
  }
  
  func (d *Decoder) decSliceInt64(v *[]int64, currEncodedType valueType, doNotReset bool) {
  	_, containerLenS := decContLens(d.d, currEncodedType)
  	s := *v
  	if s == nil {
  		s = make([]int64, containerLenS, containerLenS)
  	} else if containerLenS > cap(s) {
  		if doNotReset {
  			decErr(msgDecCannotExpandArr, cap(s), containerLenS)
  		}
  		s = make([]int64, containerLenS, containerLenS)
  		copy(s, *v)
  	} else if containerLenS > len(s) {
  		s = s[:containerLenS]
  	}
  	for j := 0; j < containerLenS; j++ {
  		// d.decode(&s[j])
  		d.d.initReadNext()
  		s[j] = d.d.decodeInt(intBitsize)
  	}
  	*v = s
  }
  
  func (d *Decoder) decSliceUint64(v *[]uint64, currEncodedType valueType, doNotReset bool) {
  	_, containerLenS := decContLens(d.d, currEncodedType)
  	s := *v
  	if s == nil {
  		s = make([]uint64, containerLenS, containerLenS)
  	} else if containerLenS > cap(s) {
  		if doNotReset {
  			decErr(msgDecCannotExpandArr, cap(s), containerLenS)
  		}
  		s = make([]uint64, containerLenS, containerLenS)
  		copy(s, *v)
  	} else if containerLenS > len(s) {
  		s = s[:containerLenS]
  	}
  	for j := 0; j < containerLenS; j++ {
  		// d.decode(&s[j])
  		d.d.initReadNext()
  		s[j] = d.d.decodeUint(intBitsize)
  	}
  	*v = s
  }
  
  func (d *Decoder) decSliceStr(v *[]string, currEncodedType valueType, doNotReset bool) {
  	_, containerLenS := decContLens(d.d, currEncodedType)
  	s := *v
  	if s == nil {
  		s = make([]string, containerLenS, containerLenS)
  	} else if containerLenS > cap(s) {
  		if doNotReset {
  			decErr(msgDecCannotExpandArr, cap(s), containerLenS)
  		}
  		s = make([]string, containerLenS, containerLenS)
  		copy(s, *v)
  	} else if containerLenS > len(s) {
  		s = s[:containerLenS]
  	}
  	for j := 0; j < containerLenS; j++ {
  		// d.decode(&s[j])
  		d.d.initReadNext()
  		s[j] = d.d.decodeString()
  	}
  	*v = s
  }
  
  func (d *Decoder) decMapIntfIntf(v *map[interface{}]interface{}) {
  	containerLen := d.d.readMapLen()
  	m := *v
  	if m == nil {
  		m = make(map[interface{}]interface{}, containerLen)
  		*v = m
  	}
  	for j := 0; j < containerLen; j++ {
  		var mk interface{}
  		d.decode(&mk)
  		// special case if a byte array.
  		if bv, bok := mk.([]byte); bok {
  			mk = string(bv)
  		}
  		mv := m[mk]
  		d.decode(&mv)
  		m[mk] = mv
  	}
  }
  
  func (d *Decoder) decMapInt64Intf(v *map[int64]interface{}) {
  	containerLen := d.d.readMapLen()
  	m := *v
  	if m == nil {
  		m = make(map[int64]interface{}, containerLen)
  		*v = m
  	}
  	for j := 0; j < containerLen; j++ {
  		d.d.initReadNext()
  		mk := d.d.decodeInt(intBitsize)
  		mv := m[mk]
  		d.decode(&mv)
  		m[mk] = mv
  	}
  }
  
  func (d *Decoder) decMapUint64Intf(v *map[uint64]interface{}) {
  	containerLen := d.d.readMapLen()
  	m := *v
  	if m == nil {
  		m = make(map[uint64]interface{}, containerLen)
  		*v = m
  	}
  	for j := 0; j < containerLen; j++ {
  		d.d.initReadNext()
  		mk := d.d.decodeUint(intBitsize)
  		mv := m[mk]
  		d.decode(&mv)
  		m[mk] = mv
  	}
  }
  
  func (d *Decoder) decMapStrIntf(v *map[string]interface{}) {
  	containerLen := d.d.readMapLen()
  	m := *v
  	if m == nil {
  		m = make(map[string]interface{}, containerLen)
  		*v = m
  	}
  	for j := 0; j < containerLen; j++ {
  		d.d.initReadNext()
  		mk := d.d.decodeString()
  		mv := m[mk]
  		d.decode(&mv)
  		m[mk] = mv
  	}
  }
  
  // ----------------------------------------
  
  func decContLens(dd decDriver, currEncodedType valueType) (containerLen, containerLenS int) {
  	if currEncodedType == valueTypeInvalid {
  		currEncodedType = dd.currentEncodedType()
  	}
  	switch currEncodedType {
  	case valueTypeArray:
  		containerLen = dd.readArrayLen()
  		containerLenS = containerLen
  	case valueTypeMap:
  		containerLen = dd.readMapLen()
  		containerLenS = containerLen * 2
  	default:
  		decErr("Only encoded map or array can be decoded into a slice. (valueType: %0x)",
  			currEncodedType)
  	}
  	return
  }
  
  func decErr(format string, params ...interface{}) {
  	doPanic(msgTagDec, format, params...)
  }
  