func (tp *TreePos) GetSubStructure(tree IModel) IModel {
	var res IModel
	indices := tp.Indices()  
	if len(indices) == 0 {
		res = tree
	} else {
		var idx int
		var it IIterator
		for idx, it = -1, tree.Children(); idx < indices[0] && it.Next(); idx++ {
		}
		if idx == indices[0] {
			res = NewPosExt(indices[1:]).GetSubStructure(it.Value())
		}
	}
	return res
}
Returns nil if the treepos is invalid, or a tree pointer if valid

GetSubStructure returns the (sub-)Tree at this position from the tree argument provided.
package tree
import (
	"fmt"
	"strings"
	"github.com/gcla/gowid"
	"github.com/gcla/gowid/gwutil"
	"github.com/gcla/gowid/widgets/list"
	lru "github.com/hashicorp/golang-lru"
)
type IModel interface {
	Leaf() string
	Children() IIterator
	fmt.Stringer
}
type IIterator interface {
	Value() IModel
	Next() bool
}
type IExpandedCallback interface {
	Expanded(app gowid.IApp)
}
type ExpandedFunction func(app gowid.IApp)
func (f ExpandedFunction) Expanded(app gowid.IApp) {
	f(app)
}
type ICollapsedCallback interface {
	Collapsed(app gowid.IApp)
}
type CollapsedFunction func(app gowid.IApp)
func (f CollapsedFunction) Collapsed(app gowid.IApp) {
	f(app)
}
type ICollapsible interface {
	IModel
	IsCollapsed() bool
	SetCollapsed(gowid.IApp, bool)
}
type Collapsed struct{}
type Expanded struct{}
type iterator struct {
	current int
	tree    *Tree
}
func (i *iterator) Value() IModel {
	return i.tree.theChildren[i.current]
}
func (i *iterator) Next() bool {
	i.current++
	return i.current < len(i.tree.theChildren)
}
type Tree struct {
	theLeaf     string
	theChildren []IModel
}
func NewTree(leaf string, children []IModel) *Tree {
	return &Tree{leaf, children}
}
func (t *Tree) Leaf() string {
	return t.theLeaf
}
func (t *Tree) SetLeaf(s string) {
	t.theLeaf = s
}
func (t *Tree) Children() IIterator {
	return &iterator{current: -1, tree: t}
}
func (t *Tree) GetChildren() []IModel {
	return t.theChildren
}
func (t *Tree) SetChildren(c []IModel) {
	newC := make([]IModel, len(c))
	copy(newC, c)
	t.theChildren = newC
}
func (t *Tree) String() string {
	res := t.theLeaf
	var idx int
	var i IIterator
	for idx, i = 0, t.Children(); i.Next(); idx++ {
	}
	if idx > 0 {
		res = res + "+["
		st := make([]string, idx)
		for idx, i = 0, t.Children(); i.Next(); idx++ {
			st[idx] = i.Value().String()
		}
		res = res + strings.Join(st, ",") + "]"
	}
	return res
}
type collapsibleIterator struct {
	sub  IIterator
	tree *Collapsible
}
func (i *collapsibleIterator) Value() IModel {
	return i.sub.Value()
}
func (i *collapsibleIterator) Next() bool {
	return !i.tree.IsCollapsed() && i.sub.Next()
}
type Collapsible struct {
	*Tree
	collapsed bool
	Callbacks *gowid.Callbacks
}
func NewCollapsible(leaf string, children []IModel) *Collapsible {
	t := NewTree(leaf, children)
	return &Collapsible{
		Tree:      t,
		Callbacks: gowid.NewCallbacks(),
	}
}
func (t *Collapsible) String() string {
	var res string
	if t.IsCollapsed() {
		res = "<C>"
	} else {
		res = "< >"
	}
	res = fmt.Sprintf("%s%s", res, t.Tree.String())
	return res
}
func (t *Collapsible) IsCollapsed() bool {
	return t.collapsed
}
func (t *Collapsible) SetCollapsed(app gowid.IApp, collapsed bool) {
	t.collapsed = collapsed
	if t.IsCollapsed() {
		t.Callbacks.RunCallbacks(Collapsed{}, app)
	} else {
		t.Callbacks.RunCallbacks(Expanded{}, app)
	}
}
func (t *Collapsible) AddOnCollapsed(name interface{}, cb ICollapsedCallback) {
	t.Callbacks.AddCallback(Collapsed{},
		gowid.Callback{name,
			gowid.CallbackFunction(
				func(args ...interface{}) {
					app := args[0].(gowid.IApp)
					cb.Collapsed(app)
				},
			),
		})
}
func (t *Collapsible) RemoveOnCollapsed(name interface{}) {
	t.Callbacks.RemoveCallback(Collapsed{}, gowid.CallbackID{Name: name})
}
func (t *Collapsible) AddOnExpanded(name interface{}, cb IExpandedCallback) {
	t.Callbacks.AddCallback(Expanded{},
		gowid.Callback{name,
			gowid.CallbackFunction(
				func(args ...interface{}) {
					app := args[0].(gowid.IApp)
					cb.Expanded(app)
				},
			),
		})
}
func (t *Collapsible) RemoveOnExpanded(name interface{}) {
	t.Callbacks.RemoveCallback(Expanded{}, gowid.CallbackID{Name: name})
}
func (t *Collapsible) Children() IIterator {
	return &collapsibleIterator{sub: t.Tree.Children(), tree: t}
}
type IPos interface {
	GetSubStructure(IModel) IModel
	Copy() IPos
	Indices() []int
	SetIndices([]int)
	Equal(list.IWalkerPosition) bool
	GreaterThan(list.IWalkerPosition) bool
	fmt.Stringer
}
func IsSubPosition(outer IPos, inner IPos) bool {
	oidc := outer.Indices()
	iidc := inner.Indices()
	if len(iidc) < len(oidc) {
		return false
	}
	for i := 0; i < len(oidc); i++ {
		if oidc[i] != iidc[i] {
			return false
		}
	}
	return true
}
type TreePos struct {
	Pos []int
}
func NewPos() *TreePos {
	res := TreePos{}
	res.Pos = make([]int, 0)
	return &res
}
func NewPosExt(pos []int) *TreePos {
	res := TreePos{
		Pos: pos,
	}
	return &res
}
func (tp *TreePos) Equal(other list.IWalkerPosition) bool {
	switch o := other.(type) {
	case *TreePos:
		if (tp.Pos == nil) || (o.Pos == nil) {
			panic(gowid.InvalidTypeToCompare{LHS: tp.Pos, RHS: o.Pos})
		}
		if len(tp.Pos) != len(o.Pos) {
			return false
		}
		for i := range tp.Pos {
			if tp.Pos[i] != o.Pos[i] {
				return false
			}
		}
		return true
	default:
		panic(gowid.InvalidTypeToCompare{LHS: tp, RHS: other})
	}
}
func (tp *TreePos) GreaterThan(other list.IWalkerPosition) bool {
	switch o := other.(type) {
	case *TreePos:
		if (tp.Pos == nil) || (o.Pos == nil) {
			panic(gowid.InvalidTypeToCompare{LHS: tp.Pos, RHS: o.Pos})
		}
		for i := 0; i < gwutil.Min(len(tp.Pos), len(o.Pos)); i++ {
			if tp.Pos[i] > o.Pos[i] {
				return true
			} else if tp.Pos[i] < o.Pos[i] {
				return false
			}
		}
		if len(tp.Pos) > len(o.Pos) {
			return true
		}
		return false
	default:
		panic(gowid.InvalidTypeToCompare{LHS: tp, RHS: other})
	}
}
func (tp *TreePos) Copy() IPos {
	tpCopy := *tp
	tpCopy.Pos = make([]int, len(tp.Pos))
	copy(tpCopy.Pos, tp.Pos)
	return &tpCopy
}
func (tp *TreePos) Indices() []int {
	return tp.Pos
}
func (tp *TreePos) SetIndices(indices []int) {
	tp.Pos = make([]int, len(indices))
	copy(tp.Pos, indices)
}
func (tp *TreePos) String() string {
	return fmt.Sprintf("%v", tp.Pos)
}