func (t *keyValueTree) At(keys ...string) KeyValueChanger {
	var path []nodeContent
	for _, key := range keys {
		path = append(path, keyValue{key, nil})
	}
	n, err := t.container.root.at(path...)
	return &keyValueChanger{n, err}
}
At implements the KeyValueTree interface.
package collections
import (
	"fmt"
	"github.com/tideland/golib/errors"
)
type nodeContent interface {
	key() interface{}
	value() interface{}
	deepCopy() nodeContent
}
type justValue struct {
	v interface{}
}
func (v justValue) key() interface{} {
	return v.v
}
func (v justValue) value() interface{} {
	return v.v
}
func (v justValue) deepCopy() nodeContent {
	return justValue{v.v}
}
func (v justValue) String() string {
	return fmt.Sprintf("%v", v.v)
}
type keyValue struct {
	k interface{}
	v interface{}
}
func (v keyValue) key() interface{} {
	return v.k
}
func (v keyValue) value() interface{} {
	return v.v
}
func (v keyValue) deepCopy() nodeContent {
	return keyValue{v.k, v.v}
}
func (v keyValue) String() string {
	return fmt.Sprintf("%v = '%v'", v.k, v.v)
}
type nodeContainer struct {
	root       *node
	duplicates bool
}
func newNodeContainer(c nodeContent, duplicates bool) *nodeContainer {
	nc := &nodeContainer{
		root: &node{
			content: c,
		},
		duplicates: duplicates,
	}
	nc.root.container = nc
	return nc
}
func (nc *nodeContainer) deepCopy() *nodeContainer {
	cnc := &nodeContainer{
		duplicates: nc.duplicates,
	}
	cnc.root = nc.root.deepCopy(cnc, nil)
	return cnc
}
type node struct {
	container *nodeContainer
	parent    *node
	content   nodeContent
	children  []*node
}
func (n *node) isAllowed(c nodeContent, here bool) bool {
	if n.container.duplicates {
		return true
	}
	checkNode := n
	if here {
		checkNode = n.parent
	}
	for _, child := range checkNode.children {
		if child.content.key() == c.key() {
			return false
		}
	}
	return true
}
func (n *node) hasDuplicateSibling(key interface{}) bool {
	if n.parent == nil {
		return false
	}
	for _, sibling := range n.parent.children {
		if sibling == n {
			continue
		}
		if sibling.content.key() == key {
			return true
		}
	}
	return false
}
func (n *node) addChild(c nodeContent) (*node, error) {
	if !n.isAllowed(c, false) {
		return nil, errors.New(ErrDuplicate, errorMessages)
	}
	child := &node{
		container: n.container,
		parent:    n,
		content:   c,
	}
	n.children = append(n.children, child)
	return child, nil
}
func (n *node) remove() error {
	if n.parent == nil {
		return errors.New(ErrCannotRemoveRoot, errorMessages)
	}
	for i, child := range n.parent.children {
		if child == n {
			n.parent.children = append(n.parent.children[:i], n.parent.children[i+1:]...)
			return nil
		}
	}
	panic("cannot find node to remove at parent")
}
func (n *node) at(path ...nodeContent) (*node, error) {
	if len(path) == 0 || path[0].key() != n.content.key() {
		return nil, errors.New(ErrNodeNotFound, errorMessages)
	}
	if len(path) == 1 {
		return n, nil
	}
	for _, child := range n.children {
		found, err := child.at(path[1:]...)
		if err != nil && !IsNodeNotFoundError(err) {
			return nil, errors.Annotate(err, ErrIllegalPath, errorMessages)
		}
		if found != nil {
			return found, nil
		}
	}
	return nil, errors.New(ErrNodeNotFound, errorMessages)
}
func (n *node) create(path ...nodeContent) (*node, error) {
	if len(path) == 0 || path[0].key() != n.content.key() {
		return nil, errors.New(ErrNodeNotFound, errorMessages)
	}
	if len(path) == 1 {
		return n, nil
	}
	var found *node
	for _, child := range n.children {
		if path[1].key() == child.content.key() {
			found = child
			break
		}
	}
	if found == nil {
		child, err := n.addChild(path[1])
		if err != nil {
			return nil, errors.Annotate(err, ErrNodeAddChild, errorMessages)
		}
		return child.create(path[1:]...)
	}
	return found.create(path[1:]...)
}
func (n *node) findFirst(f func(fn *node) (bool, error)) (*node, error) {
	hasFound, err := f(n)
	if err != nil {
		return nil, errors.Annotate(err, ErrNodeFindFirst, errorMessages)
	}
	if hasFound {
		return n, nil
	}
	for _, child := range n.children {
		found, err := child.findFirst(f)
		if err != nil && !IsNodeNotFoundError(err) {
			return nil, errors.Annotate(err, ErrNodeFindFirst, errorMessages)
		}
		if found != nil {
			return found, nil
		}
	}
	return nil, errors.New(ErrNodeNotFound, errorMessages)
}
func (n *node) findAll(f func(fn *node) (bool, error)) ([]*node, error) {
	var allFound []*node
	hasFound, err := f(n)
	if err != nil {
		return nil, errors.Annotate(err, ErrNodeFindAll, errorMessages)
	}
	if hasFound {
		allFound = append(allFound, n)
	}
	for _, child := range n.children {
		found, err := child.findAll(f)
		if err != nil {
			return nil, errors.Annotate(err, ErrNodeFindAll, errorMessages)
		}
		if found != nil {
			allFound = append(allFound, found...)
		}
	}
	return allFound, nil
}
func (n *node) doAll(f func(dn *node) error) error {
	if err := f(n); err != nil {
		return errors.Annotate(err, ErrNodeDoAll, errorMessages)
	}
	for _, child := range n.children {
		if err := child.doAll(f); err != nil {
			return errors.Annotate(err, ErrNodeDoAll, errorMessages)
		}
	}
	return nil
}
func (n *node) doChildren(f func(cn *node) error) error {
	for _, child := range n.children {
		if err := f(child); err != nil {
			return errors.Annotate(err, ErrNodeDoChildren, errorMessages)
		}
	}
	return nil
}
func (n *node) size() int {
	l := 1
	for _, child := range n.children {
		l += child.size()
	}
	return l
}
func (n *node) deepCopy(c *nodeContainer, p *node) *node {
	cn := &node{
		container: c,
		parent:    p,
		content:   n.content.deepCopy(),
		children:  make([]*node, len(n.children)),
	}
	for i, child := range n.children {
		cn.children[i] = child.deepCopy(c, cn)
	}
	return cn
}
func (n *node) String() string {
	out := fmt.Sprintf("[%v", n.content)
	if len(n.children) > 0 {
		out += " "
		for _, child := range n.children {
			out += child.String()
		}
	}
	out += "]"
	return out
}
type tree struct {
	container *nodeContainer
}
func NewTree(v interface{}, duplicates bool) Tree {
	return &tree{
		container: newNodeContainer(justValue{v}, duplicates),
	}
}
func (t *tree) At(values ...interface{}) Changer {
	var path []nodeContent
	for _, value := range values {
		path = append(path, justValue{value})
	}
	n, err := t.container.root.at(path...)
	return &changer{n, err}
}
func (t *tree) Root() Changer {
	return &changer{t.container.root, nil}
}
func (t *tree) Create(values ...interface{}) Changer {
	var path []nodeContent
	for _, value := range values {
		path = append(path, justValue{value})
	}
	n, err := t.container.root.create(path...)
	return &changer{n, err}
}
func (t *tree) FindFirst(f func(v interface{}) (bool, error)) Changer {
	n, err := t.container.root.findFirst(func(fn *node) (bool, error) {
		return f(fn.content.value())
	})
	return &changer{n, err}
}
func (t *tree) FindAll(f func(v interface{}) (bool, error)) []Changer {
	ns, err := t.container.root.findAll(func(fn *node) (bool, error) {
		return f(fn.content.value())
	})
	if err != nil {
		return []Changer{&changer{nil, err}}
	}
	var cs []Changer
	for _, n := range ns {
		cs = append(cs, &changer{n, nil})
	}
	return cs
}
func (t *tree) DoAll(f func(v interface{}) error) error {
	return t.container.root.doAll(func(dn *node) error {
		return f(dn.content.value())
	})
}
func (t *tree) DoAllDeep(f func(vs []interface{}) error) error {
	return t.container.root.doAll(func(dn *node) error {
		values := []interface{}{}
		cn := dn
		for cn != nil {
			values = append([]interface{}{cn.content.value()}, values...)
			cn = cn.parent
		}
		return f(values)
	})
}
func (t *tree) Len() int {
	return t.container.root.size()
}
func (t *tree) Copy() Tree {
	return &tree{
		container: t.container.deepCopy(),
	}
}
func (t *tree) Deflate(v interface{}) {
	t.container.root = &node{
		content: justValue{v},
	}
}
func (t *tree) String() string {
	return t.container.root.String()
}
type stringTree struct {
	container *nodeContainer
}
func NewStringTree(v string, duplicates bool) StringTree {
	return &stringTree{
		container: newNodeContainer(justValue{v}, duplicates),
	}
}
func (t *stringTree) At(values ...string) StringChanger {
	var path []nodeContent
	for _, value := range values {
		path = append(path, justValue{value})
	}
	n, err := t.container.root.at(path...)
	return &stringChanger{n, err}
}
func (t *stringTree) Root() StringChanger {
	return &stringChanger{t.container.root, nil}
}
func (t *stringTree) Create(values ...string) StringChanger {
	var path []nodeContent
	for _, value := range values {
		path = append(path, justValue{value})
	}
	n, err := t.container.root.create(path...)
	return &stringChanger{n, err}
}
func (t *stringTree) FindFirst(f func(v string) (bool, error)) StringChanger {
	n, err := t.container.root.findFirst(func(fn *node) (bool, error) {
		return f(fn.content.value().(string))
	})
	return &stringChanger{n, err}
}
func (t *stringTree) FindAll(f func(v string) (bool, error)) []StringChanger {
	ns, err := t.container.root.findAll(func(fn *node) (bool, error) {
		return f(fn.content.value().(string))
	})
	if err != nil {
		return []StringChanger{&stringChanger{nil, err}}
	}
	var cs []StringChanger
	for _, n := range ns {
		cs = append(cs, &stringChanger{n, nil})
	}
	return cs
}
func (t *stringTree) DoAll(f func(v string) error) error {
	return t.container.root.doAll(func(dn *node) error {
		return f(dn.content.value().(string))
	})
}
func (t *stringTree) DoAllDeep(f func(vs []string) error) error {
	return t.container.root.doAll(func(dn *node) error {
		values := []string{}
		cn := dn
		for cn != nil {
			values = append([]string{cn.content.value().(string)}, values...)
			cn = cn.parent
		}
		return f(values)
	})
}
func (t *stringTree) Len() int {
	return t.container.root.size()
}
func (t *stringTree) Copy() StringTree {
	return &stringTree{
		container: t.container.deepCopy(),
	}
}
func (t *stringTree) Deflate(v string) {
	t.container.root = &node{
		content: justValue{v},
	}
}
func (t *stringTree) String() string {
	return t.container.root.String()
}
type keyValueTree struct {
	container *nodeContainer
}
func NewKeyValueTree(k string, v interface{}, duplicates bool) KeyValueTree {
	return &keyValueTree{
		container: newNodeContainer(keyValue{k, v}, duplicates),
	}
}