diff --git a/db/model/root.go b/db/model/root.go
new file mode 100644
index 0000000..722fc94
--- /dev/null
+++ b/db/model/root.go
@@ -0,0 +1,213 @@
+package model
+
+import (
+	"encoding/hex"
+	"encoding/json"
+	"fmt"
+	"github.com/google/uuid"
+	"reflect"
+)
+
+type Root struct {
+	*Node
+	DirtyNodes            map[string]*Node
+	KvStore               *Backend
+	Loading               bool
+	RevisionClass         interface{}
+	Callbacks             []func() interface{}
+	NotificationCallbacks []func() interface{}
+}
+
+func NewRoot(initialData interface{}, kvStore *Backend, revisionClass interface{}) *Root {
+	root := &Root{}
+	root.KvStore = kvStore
+	root.DirtyNodes = make(map[string]*Node)
+	root.Loading = false
+	if kvStore != nil /*&& FIXME: RevisionClass is a subclass of PersistedConfigRevision */ {
+		revisionClass = reflect.TypeOf(PersistedRevision{})
+	}
+	root.RevisionClass = revisionClass
+	root.Callbacks = []func() interface{}{}
+	root.NotificationCallbacks = []func() interface{}{}
+
+	root.Node = NewNode(root, initialData, false, "")
+
+	return root
+}
+
+func (r *Root) makeRevision(branch *Branch, data interface{}, children map[string][]*Revision) *Revision {
+
+	return &Revision{}
+}
+
+func (r *Root) makeTxBranch() string {
+	txid_bin, _ := uuid.New().MarshalBinary()
+	txid := hex.EncodeToString(txid_bin)[:12]
+	r.DirtyNodes[txid] = r.Node
+	r.Node.makeTxBranch(txid)
+	return txid
+}
+
+func (r *Root) deleteTxBranch(txid string) {
+	for _, dirtyNode := range r.DirtyNodes {
+		dirtyNode.deleteTxBranch(txid)
+	}
+	delete(r.DirtyNodes, txid)
+}
+
+func (r *Root) foldTxBranch(txid string) {
+	// TODO: implement foldTxBranch
+	// if err := r.Node.mergeTxBranch(txid, dryRun=true); err != nil {
+	//   r.deleteTxBranch(txid)
+	// } else {
+	//   r.Node.mergeTxBranch(txid)
+	//   r.executeCallbacks()
+	// }
+}
+
+func (r *Root) executeCallbacks() {
+	for len(r.Callbacks) > 0 {
+		callback := r.Callbacks[0]
+		r.Callbacks = r.Callbacks[1:]
+		callback()
+	}
+	for len(r.NotificationCallbacks) > 0 {
+		callback := r.NotificationCallbacks[0]
+		r.NotificationCallbacks = r.NotificationCallbacks[1:]
+		callback()
+	}
+}
+
+func (r *Root) noCallbacks() bool {
+	return len(r.Callbacks) == 0
+}
+
+func (r *Root) addCallback(callback func() interface{}) {
+	r.Callbacks = append(r.Callbacks, callback)
+}
+func (r *Root) addNotificationCallback(callback func() interface{}) {
+	r.NotificationCallbacks = append(r.NotificationCallbacks, callback)
+}
+
+func (r *Root) Update(path string, data interface{}, strict bool, txid string, makeBranch t_makeBranch) *Revision {
+	var result *Revision
+	// FIXME: the more i look at this... i think i need to implement an interface for Node & root
+
+	if makeBranch == nil {
+		// TODO: raise error
+	}
+
+	if r.noCallbacks() {
+		// TODO: raise error
+	}
+
+	if txid != "" {
+		//dirtied := r.DirtyNodes[txid]
+
+		trackDirty := func(node *Node) *Branch {
+			//dirtied.Add(Node)
+			return node.makeTxBranch(txid)
+		}
+		result = r.Node.Update(path, data, strict, txid, trackDirty)
+	} else {
+		result = r.Node.Update(path, data, strict, "", nil)
+	}
+
+	r.executeCallbacks()
+
+	return result
+}
+
+func (r *Root) Add(path string, data interface{}, txid string, makeBranch t_makeBranch) *Revision {
+	var result *Revision
+	// FIXME: the more i look at this... i think i need to implement an interface for Node & root
+
+	if makeBranch == nil {
+		// TODO: raise error
+	}
+
+	if r.noCallbacks() {
+		// TODO: raise error
+	}
+
+	if txid != "" {
+		//dirtied := r.DirtyNodes[txid]
+
+		trackDirty := func(node *Node) *Branch {
+			//dirtied.Add(Node)
+			return node.makeTxBranch(txid)
+		}
+		result = r.Node.Add(path, data, txid, trackDirty)
+	} else {
+		result = r.Node.Add(path, data, "", nil)
+	}
+
+	r.executeCallbacks()
+
+	return result
+}
+
+func (r *Root) Remove(path string, txid string, makeBranch t_makeBranch) *Revision {
+	var result *Revision
+	// FIXME: the more i look at this... i think i need to implement an interface for Node & root
+
+	if makeBranch == nil {
+		// TODO: raise error
+	}
+
+	if r.noCallbacks() {
+		// TODO: raise error
+	}
+
+	if txid != "" {
+		//dirtied := r.DirtyNodes[txid]
+
+		trackDirty := func(node *Node) *Branch {
+			//dirtied.Add(Node)
+			return node.makeTxBranch(txid)
+		}
+		result = r.Node.Remove(path, txid, trackDirty)
+	} else {
+		result = r.Node.Remove(path, "", nil)
+	}
+
+	r.executeCallbacks()
+
+	return result
+}
+
+func (r *Root) Load(rootClass interface{}) *Root {
+	//fakeKvStore := &Backend{}
+	//root := NewRoot(rootClass, fakeKvStore, PersistedRevision{})
+	//r.KvStore = KvStore
+	r.loadFromPersistence(rootClass)
+	return r
+}
+
+func (r *Root) LoadLatest(hash string) {
+	r.Node.LoadLatest(r.KvStore, hash)
+}
+
+type rootData struct {
+	Latest string            `json:GetLatest`
+	Tags   map[string]string `json:Tags`
+}
+
+func (r *Root) loadFromPersistence(rootClass interface{}) {
+	var data rootData
+
+	r.Loading = true
+	blob, _ := r.KvStore.Get("root")
+
+	if err := json.Unmarshal(blob.Value.([]byte), &data); err != nil {
+		fmt.Errorf("problem to unmarshal blob - error:%s\n", err.Error())
+	}
+
+	for tag, hash := range data.Tags {
+		r.Node.LoadLatest(r.KvStore, hash)
+		r.Node.Tags[tag] = r.Node.Latest()
+	}
+
+	r.Node.LoadLatest(r.KvStore, data.Latest)
+	r.Loading = false
+}
