func (d *Decoder) findData(m map[string]interface{}, keys []string) interface{} {
	if len(keys) == 1 {
		if value, ok := m[keys[0]]; ok == true {
			return value
		}
		return nil
	}
	if value, ok := m[keys[0]]; ok == true {
		if m, ok := value.(map[string]interface{}); ok == true {
			return d.findData(m, keys[1:])
		}
	}
	return nil
}
findData locates the data by walking the keys down the map
package mapstructure
import (
	"errors"
	"fmt"
	"reflect"
	"sort"
	"strconv"
	"strings"
)
type DecodeHookFunc func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)
type DecoderConfig struct {
	DecodeHook DecodeHookFunc
	ErrorUnused bool
	WeaklyTypedInput bool
	Metadata *Metadata
	Result interface{}
	TagName string
}
type Decoder struct {
	config *DecoderConfig
}
type Metadata struct {
	Keys []string
	Unused []string
}
func Decode(m interface{}, rawVal interface{}) error {
	config := &DecoderConfig{
		Metadata: nil,
		Result:   rawVal,
	}
	decoder, err := NewDecoder(config)
	if err != nil {
		return err
	}
	return decoder.Decode(m)
}
func DecodePath(m map[string]interface{}, rawVal interface{}) error {
	config := &DecoderConfig{
		Metadata: nil,
		Result:   nil,
	}
	decoder, err := NewPathDecoder(config)
	if err != nil {
		return err
	}
	_, err = decoder.DecodePath(m, rawVal)
	return err
}
func DecodeSlicePath(ms []map[string]interface{}, rawSlice interface{}) error {
	reflectRawSlice := reflect.TypeOf(rawSlice)
	rawKind := reflectRawSlice.Kind()
	rawElement := reflectRawSlice.Elem()
	if (rawKind == reflect.Ptr && rawElement.Kind() != reflect.Slice) ||
		(rawKind != reflect.Ptr && rawKind != reflect.Slice) {
		return fmt.Errorf("Incompatible Value, Looking For Slice : %v : %v", rawKind, rawElement.Kind())
	}
	config := &DecoderConfig{
		Metadata: nil,
		Result:   nil,
	}
	decoder, err := NewPathDecoder(config)
	if err != nil {
		return err
	}
	valSlice := reflect.MakeSlice(rawElement, len(ms), len(ms))
	for index, m := range ms {
		sliceElementType := rawElement.Elem()
		if sliceElementType.Kind() != reflect.Ptr {
			obj := reflect.New(rawElement.Elem())
			decoder.DecodePath(m, reflect.Indirect(obj))
			indexVal := valSlice.Index(index)
			indexVal.Set(reflect.Indirect(obj))
		} else {
			obj := reflect.New(rawElement.Elem().Elem())
			decoder.DecodePath(m, reflect.Indirect(obj))
			indexVal := valSlice.Index(index)
			indexVal.Set(obj)
		}
	}
	reflect.ValueOf(rawSlice).Elem().Set(valSlice)
	return nil
}
func NewDecoder(config *DecoderConfig) (*Decoder, error) {
	val := reflect.ValueOf(config.Result)
	if val.Kind() != reflect.Ptr {
		return nil, errors.New("result must be a pointer")
	}
	val = val.Elem()
	if !val.CanAddr() {
		return nil, errors.New("result must be addressable (a pointer)")
	}
	if config.Metadata != nil {
		if config.Metadata.Keys == nil {
			config.Metadata.Keys = make([]string, 0)
		}
		if config.Metadata.Unused == nil {
			config.Metadata.Unused = make([]string, 0)
		}
	}
	if config.TagName == "" {
		config.TagName = "mapstructure"
	}
	result := &Decoder{
		config: config,
	}
	return result, nil
}
func NewPathDecoder(config *DecoderConfig) (*Decoder, error) {
	if config.Metadata != nil {
		if config.Metadata.Keys == nil {
			config.Metadata.Keys = make([]string, 0)
		}
		if config.Metadata.Unused == nil {
			config.Metadata.Unused = make([]string, 0)
		}
	}
	if config.TagName == "" {
		config.TagName = "mapstructure"
	}
	result := &Decoder{
		config: config,
	}
	return result, nil
}
func (d *Decoder) Decode(raw interface{}) error {
	return d.decode("", raw, reflect.ValueOf(d.config.Result).Elem())
}
func (d *Decoder) DecodePath(m map[string]interface{}, rawVal interface{}) (bool, error) {
	decoded := false
	var val reflect.Value
	reflectRawValue := reflect.ValueOf(rawVal)
	kind := reflectRawValue.Kind()
	switch kind {
	case reflect.Ptr:
		val = reflectRawValue.Elem()
		if val.Kind() != reflect.Struct {
			return decoded, fmt.Errorf("Incompatible Type : %v : Looking For Struct", kind)
		}
	case reflect.Struct:
		var ok bool
		val, ok = rawVal.(reflect.Value)
		if ok == false {
			return decoded, fmt.Errorf("Incompatible Type : %v : Looking For reflect.Value", kind)
		}
	default:
		return decoded, fmt.Errorf("Incompatible Type : %v", kind)
	}
	for i := 0; i < val.NumField(); i++ {
		valueField := val.Field(i)
		typeField := val.Type().Field(i)
		tag := typeField.Tag
		tagValue := tag.Get("jpath")
		if tagValue == "" {
			if valueField.Kind() == reflect.Struct {
				d.DecodePath(m, valueField)
				continue
			} else if valueField.Kind() == reflect.Ptr && reflect.TypeOf(valueField).Kind() == reflect.Struct {
				if valueField.IsNil() {
					valueField.Set(reflect.New(valueField.Type().Elem()))
					decoded, _ = d.DecodePath(m, valueField.Elem())
					if decoded == false {
						valueField.Set(reflect.NewAt(valueField.Type().Elem(), nil))
					}
					continue
				}
				d.DecodePath(m, valueField.Elem())
				continue
			}
		}
		keys := strings.Split(tagValue, ".")
		data := d.findData(m, keys)
		if data != nil {
			if valueField.Kind() == reflect.Slice {
				if strings.Contains(valueField.Type().String(), "map[") {
					goto normal_decode
				}
				mapSlice := data.([]interface{})
				if len(mapSlice) > 0 {
					_, ok := mapSlice[0].(map[string]interface{})
					if ok == false {
						goto normal_decode
					}
					ms := make([]map[string]interface{}, len(mapSlice))
					for index, m2 := range mapSlice {
						ms[index] = m2.(map[string]interface{})
					}
					DecodeSlicePath(ms, valueField.Addr().Interface())
					continue
				}
			}
		normal_decode:
			decoded = true
			err := d.decode("", data, valueField)
			if err != nil {
				return false, err
			}
		}
	}
	return decoded, nil
}
func (d *Decoder) decode(name string, data interface{}, val reflect.Value) error {
	if data == nil {
		return nil
	}
	dataVal := reflect.ValueOf(data)
	if !dataVal.IsValid() {
		val.Set(reflect.Zero(val.Type()))
		return nil
	}
	if d.config.DecodeHook != nil {
		var err error
		data, err = d.config.DecodeHook(d.getKind(dataVal), d.getKind(val), data)
		if err != nil {
			return err
		}
	}
	var err error
	dataKind := d.getKind(val)
	switch dataKind {
	case reflect.Bool:
		err = d.decodeBool(name, data, val)
	case reflect.Interface:
		err = d.decodeBasic(name, data, val)
	case reflect.String:
		err = d.decodeString(name, data, val)
	case reflect.Int:
		err = d.decodeInt(name, data, val)
	case reflect.Uint:
		err = d.decodeUint(name, data, val)
	case reflect.Float32:
		err = d.decodeFloat(name, data, val)
	case reflect.Struct:
		err = d.decodeStruct(name, data, val)
	case reflect.Map:
		err = d.decodeMap(name, data, val)
	case reflect.Slice:
		err = d.decodeSlice(name, data, val)
	default:
		return fmt.Errorf("%s: unsupported type: %s", name, dataKind)
	}
	if d.config.Metadata != nil && name != "" {
		d.config.Metadata.Keys = append(d.config.Metadata.Keys, name)
	}
	return err
}