func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value {
	pathparts := strings.Split(path, "||")
	if len(pathparts) > 1 {
		for _, pathpart := range pathparts {
			vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm)
			if len(vals) > 0 {
				return vals
			}
		}
		return nil
	}
	values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))}
	components := strings.Split(path, ".")
	for len(values) > 0 && len(components) > 0 {
		var index *int64
		var indexStar bool
		c := strings.TrimSpace(components[0])
		if c == "" {  
			return nil
		} else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] {
			return nil  
		}
		if m := indexRe.FindStringSubmatch(c); m != nil {
			c = m[1]
			if m[2] == "" {
				index = nil
				indexStar = true
			} else {
				i, _ := strconv.ParseInt(m[2], 10, 32)
				index = &i
				indexStar = false
			}
		}
		nextvals := []reflect.Value{}
		for _, value := range values {
			if value.Kind() != reflect.Struct {
				continue
			}
			if c == "*" {  
				for i := 0; i < value.NumField(); i++ {
					if f := reflect.Indirect(value.Field(i)); f.IsValid() {
						nextvals = append(nextvals, f)
					}
				}
				continue
			}
			value = value.FieldByNameFunc(func(name string) bool {
				if c == name {
					return true
				} else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) {
					return true
				}
				return false
			})
			if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 {
				if !value.IsNil() {
					value.Set(reflect.Zero(value.Type()))
				}
				return []reflect.Value{value}
			}
			if createPath && value.Kind() == reflect.Ptr && value.IsNil() {
				value.Set(reflect.New(value.Type().Elem()))
				value = value.Elem()
			} else {
				value = reflect.Indirect(value)
			}
			if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
				if !createPath && value.IsNil() {
					value = reflect.ValueOf(nil)
				}
			}
			if value.IsValid() {
				nextvals = append(nextvals, value)
			}
		}
		values = nextvals
		if indexStar || index != nil {
			nextvals = []reflect.Value{}
			for _, value := range values {
				value := reflect.Indirect(value)
				if value.Kind() != reflect.Slice {
					continue
				}
				if indexStar {  
					for i := 0; i < value.Len(); i++ {
						idx := reflect.Indirect(value.Index(i))
						if idx.IsValid() {
							nextvals = append(nextvals, idx)
						}
					}
					continue
				}
				i := int(*index)
				if i >= value.Len() {  
					if createPath {
					} else {
						continue
					}
				} else if i < 0 {  
					i = value.Len() + i
				}
				value = reflect.Indirect(value.Index(i))
				if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
					if !createPath && value.IsNil() {
						value = reflect.ValueOf(nil)
					}
				}
				if value.IsValid() {
					nextvals = append(nextvals, value)
				}
			}
			values = nextvals
		}
		components = components[1:]
	}
	return values
}
rValuesAtPath returns a slice of values found in value v. The values
in v are explored recursively so all nested values are collected.
package awsutil
import (
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"github.com/jmespath/go-jmespath"
)
var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`)