func addNodeValueAt(value interface{}, head string, tail []string) (interface{}, error) {
	if head == "" {
		return value, nil
	}
	index, err := strconv.Atoi(head)
	if err != nil {
		o := map[string]interface{}{}
		if len(tail) == 0 {
			o[head] = value
			return o, nil
		}
		h, t := ht(tail)
		subnode, err := addNodeValueAt(value, h, t)
		if err != nil {
			return nil, err
		}
		o[head] = subnode
		return o, nil
	}
	a := ensureArray([]interface{}{}, index+1)
	if len(tail) == 0 {
		a[index] = value
		return a, nil
	}
	h, t := ht(tail)
	subnode, err := addNodeValueAt(value, h, t)
	if err != nil {
		return nil, err
	}
	a[index] = subnode
	return a, nil
}
addNodeValueAt is used recursively by setValueAt().
package gjp
import (
	"strconv"
	"strings"
	"github.com/tideland/golib/errors"
	"github.com/tideland/golib/stringex"
)
func splitPath(path, separator string) []string {
	return stringex.SplitFilter(path, separator, func(part string) bool {
		return part != ""
	})
}
func isValue(raw interface{}) (interface{}, bool) {
	if raw == nil {
		return raw, true
	}
	_, ook := isObject(raw)
	_, aok := isArray(raw)
	if ook || aok {
		return nil, false
	}
	return raw, true
}
func isObject(raw interface{}) (map[string]interface{}, bool) {
	o, ok := raw.(map[string]interface{})
	return o, ok
}
func isArray(raw interface{}) ([]interface{}, bool) {
	a, ok := raw.([]interface{})
	return a, ok
}
func valueAt(node interface{}, parts []string) (interface{}, error) {
	length := len(parts)
	if length == 0 {
		return node, nil
	}
	head, tail := ht(parts)
	if head == "" {
		return node, nil
	}
	if o, ok := isObject(node); ok {
		field, ok := o[head]
		if !ok {
			return nil, errors.New(ErrInvalidPart, errorMessages, head)
		}
		return valueAt(field, tail)
	}
	if a, ok := isArray(node); ok {
		index, err := strconv.Atoi(head)
		if err != nil || index >= len(a) {
			return nil, errors.Annotate(err, ErrInvalidPart, errorMessages, head)
		}
		return valueAt(a[index], tail)
	}
	return nil, errors.New(ErrPathTooLong, errorMessages)
}
func setValueAt(root, value interface{}, parts []string) (interface{}, error) {
	h, t := ht(parts)
	return setNodeValueAt(root, value, h, t)
}
func ht(parts []string) (string, []string) {
	switch len(parts) {
	case 0:
		return "", []string{}
	case 1:
		return parts[0], []string{}
	default:
		return parts[0], parts[1:]
	}
}
func setNodeValueAt(node, value interface{}, head string, tail []string) (interface{}, error) {
	if node == nil {
		return addNodeValueAt(value, head, tail)
	}
	if o, ok := isObject(node); ok {
		_, ok := isValue(o[head])
		switch {
		case !ok && len(tail) == 0:
			return nil, errors.New(ErrCorruptingDocument, errorMessages)
		case ok && o[head] != nil && len(tail) > 0:
			return nil, errors.New(ErrCorruptingDocument, errorMessages)
		case ok && len(tail) == 0:
			o[head] = value
		default:
			h, t := ht(tail)
			subnode, err := setNodeValueAt(o[head], value, h, t)
			if err != nil {
				return nil, err
			}
			o[head] = subnode
		}
		return o, nil
	}
	if a, ok := isArray(node); ok {
		index, err := strconv.Atoi(head)
		if err != nil {
			return nil, errors.New(ErrInvalidPart, errorMessages, head)
		}
		a = ensureArray(a, index+1)
		_, ok := isValue(a[index])
		switch {
		case !ok && len(tail) == 0:
			return nil, errors.New(ErrCorruptingDocument, errorMessages)
		case ok && a[index] != nil && len(tail) > 0:
			return nil, errors.New(ErrCorruptingDocument, errorMessages)
		case ok && len(tail) == 0:
			a[index] = value
		default:
			h, t := ht(tail)
			subnode, err := setNodeValueAt(a[index], value, h, t)
			if err != nil {
				return nil, err
			}
			a[index] = subnode
		}
		return a, nil
	}
	return nil, errors.New(ErrInvalidPath, errorMessages, head)
}