func (snapshot *NewSnapshot) Flush(wb kv.Batch) (flushed *Snapshot) {
	if snapshot.root == nil {
		flushed = &Snapshot{snapshot.tree, 0}
	} else {
		rootId, _ := snapshot.tree.flushNode([]bool{}, snapshot.root, wb)
		flushed = &Snapshot{snapshot.tree, rootId}
	}
	allocCountVal := make([]byte, 8)
	binary.LittleEndian.PutUint64(allocCountVal, snapshot.tree.allocCounter)
	wb.Put(snapshot.tree.allocCounterKey, allocCountVal)
	return
}
Flush returns a newly usable Snapshot
package merkletree
import (
	"bytes"
	"encoding/binary"
	"fmt"
	"log"
	"sync"
	"github.com/yahoo/coname"
	"github.com/yahoo/coname/keyserver/kv"
	"github.com/yahoo/coname/proto"
)
const (
	NodePrefix       = 'T'
	AllocCounterKey  = "AC"
	NodeKeyDelimiter = 'N'
	SnapshotNrBytes  = 8
	IndexLengthBytes = 4
)
type MerkleTree struct {
	treeNonce       []byte
	db              kv.DB
	nodeKeyPrefix   []byte
	allocCounterKey []byte
	allocMutex   sync.Mutex
	allocCounter uint64
}
func AccessMerkleTree(db kv.DB, prefix []byte, treeNonce []byte) (*MerkleTree, error) {
	allocCounterKey := append(append([]byte(nil), prefix...), AllocCounterKey...)
	val, err := db.Get(allocCounterKey)
	var allocCount uint64
	if err == db.ErrNotFound() {
		allocCount = 0
	} else if err != nil {
		return nil, err
	} else if len(val) != 8 {
		log.Panicf("bad alloc counter")
	} else {
		allocCount = binary.LittleEndian.Uint64(val)
	}
	return &MerkleTree{
		treeNonce:       treeNonce,
		db:              db,
		nodeKeyPrefix:   append(append([]byte(nil), prefix...), NodePrefix),
		allocCounterKey: allocCounterKey,
		allocCounter:    allocCount,
	}, nil
}
type Snapshot struct {
	tree *MerkleTree
	Nr   uint64
}
type diskNode struct {
	isLeaf      bool
	childIds    [2]uint64                  
	childHashes [2][coname.HashBytes]byte  
	value       []byte                     
	indexBytes  []byte                     
}
type node struct {
	diskNode
	prefixBits []bool    
	children   [2]*node  
}
type NewSnapshot struct {
	Snapshot
	root *node
}
func (tree *MerkleTree) GetSnapshot(nr uint64) *Snapshot {
	return &Snapshot{tree, nr}
}
func (snapshot *Snapshot) GetRootHash() ([]byte, error) {
	root, err := snapshot.loadRoot()
	if err != nil {
		return nil, err
	}
	return snapshot.tree.hash([]bool{}, root), nil
}
type LookupTracingNode struct {
	tree  *MerkleTree
	trace *proto.TreeProof
	node  *node
}
func makeTracingNode(tree *MerkleTree, trace *proto.TreeProof, n *node) *LookupTracingNode {
	if n == nil {
		return nil
	} else {
		return &LookupTracingNode{tree, trace, n}
	}
}
var _ coname.MerkleNode = (*LookupTracingNode)(nil)
func (n *LookupTracingNode) IsEmpty() bool {
	return n == nil
}
func (n *LookupTracingNode) IsLeaf() bool {
	return n.node.isLeaf
}
func (n *LookupTracingNode) Depth() int {
	return len(n.node.prefixBits)
}
func (n *LookupTracingNode) ChildHash(rightChild bool) []byte {
	return n.node.childHashes[coname.BitToIndex(rightChild)][:]
}
func (n *LookupTracingNode) Child(rightChild bool) (coname.MerkleNode, error) {
	if len(n.trace.Neighbors) != n.Depth() {
		log.Panicf("unexpected access pattern: at depth %v, have %v", n.Depth(), n.trace.Neighbors)
	}
	n.trace.Neighbors = append(n.trace.Neighbors, n.ChildHash(!rightChild))
	childPtr, err := n.tree.getChildPointer(n.node, rightChild)
	if err != nil {
		return nil, err
	}
	return makeTracingNode(n.tree, n.trace, *childPtr), nil
}
func (n *LookupTracingNode) Index() []byte {
	n.trace.ExistingIndex = n.node.indexBytes
	n.trace.ExistingEntryHash = n.node.value
	return n.node.indexBytes
}
func (n *LookupTracingNode) Value() []byte {
	return n.node.value
}
func (snapshot *Snapshot) Lookup(indexBytes []byte) (value []byte, trace *proto.TreeProof, err error) {
	root, err := snapshot.loadRoot()
	if err != nil {
		return nil, nil, err
	}
	return snapshot.tree.lookup(root, indexBytes)
}
func (snapshot *NewSnapshot) Lookup(indexBytes []byte) (value []byte, trace *proto.TreeProof, err error) {
	return snapshot.tree.lookup(snapshot.root, indexBytes)
}
func (tree *MerkleTree) lookup(root *node, indexBytes []byte) (value []byte, trace *proto.TreeProof, err error) {
	trace = &proto.TreeProof{}
	var tracingRoot coname.MerkleNode = makeTracingNode(tree, trace, root)
	value, err = coname.TreeLookup(tracingRoot, indexBytes)
	if err != nil {
		return nil, nil, err
	}
	return
}
func (snapshot *Snapshot) BeginModification() (*NewSnapshot, error) {
	root, err := snapshot.loadRoot()
	if err != nil {
		return nil, err
	}
	return &NewSnapshot{*snapshot, root}, nil
}
func (snapshot *NewSnapshot) Set(indexBytes []byte, value []byte) (err error) {
	if len(indexBytes) != coname.IndexBytes {
		return fmt.Errorf("Wrong index length")
	}
	if len(value) != coname.HashBytes {
		return fmt.Errorf("Wrong value length")
	}
	value = append([]byte(nil), value...)  
	indexBits := coname.ToBits(coname.IndexBits, indexBytes)
	nodePointer := &snapshot.root
	position := 0
	for *nodePointer != nil && !(*nodePointer).isLeaf {
		nodePointer, err = snapshot.tree.getChildPointer(*nodePointer, indexBits[position])
		if err != nil {
			return
		}
		position++
	}
	if *nodePointer == nil {
		*nodePointer = &node{
			diskNode: diskNode{
				isLeaf:     true,
				indexBytes: append([]byte{}, indexBytes...),  
				value:      value,
			},
			prefixBits: indexBits[:position],
		}
	} else if bytes.Equal((*nodePointer).indexBytes, indexBytes) {
		(*nodePointer).value = value
	} else {
		oldLeaf := *nodePointer
		oldLeafIndexBits := coname.ToBits(coname.IndexBits, oldLeaf.indexBytes)
		for oldLeafIndexBits[position] == indexBits[position] {
			newNode := &node{
				diskNode: diskNode{
					isLeaf: false,
				},
				prefixBits: indexBits[:position],
			}
			*nodePointer, nodePointer = newNode, &newNode.children[coname.BitToIndex(indexBits[position])]
			position++
		}
		splitNode := &node{
			diskNode: diskNode{
				isLeaf: false,
			},
			prefixBits: indexBits[:position],
		}
		newLeaf := &node{
			diskNode: diskNode{
				isLeaf:     true,
				indexBytes: append([]byte{}, indexBytes...),  
				value:      value,
			},
			prefixBits: indexBits[:position+1],
		}
		oldLeaf.prefixBits = oldLeafIndexBits[:position+1]
		splitNode.children[coname.BitToIndex(indexBits[position])] = newLeaf
		splitNode.children[coname.BitToIndex(oldLeafIndexBits[position])] = oldLeaf
		*nodePointer = splitNode
	}
	return nil
}