diff --git a/db/model/merge.go b/db/model/merge.go
new file mode 100644
index 0000000..8ff89c4
--- /dev/null
+++ b/db/model/merge.go
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package model
+
+import (
+	"github.com/opencord/voltha-go/common/log"
+	"reflect"
+)
+
+func revisionsAreEqual(a, b []Revision) bool {
+	// If one is nil, the other must also be nil.
+	if (a == nil) != (b == nil) {
+		return false
+	}
+
+	if len(a) != len(b) {
+		return false
+	}
+
+	for i := range a {
+		if a[i] != b[i] {
+			return false
+		}
+	}
+
+	return true
+}
+
+type changeAnalysis struct {
+	KeyMap1     map[reflect.Value]int
+	KeyMap2     map[reflect.Value]int
+	AddedKeys   map[reflect.Value]struct{}
+	RemovedKeys map[reflect.Value]struct{}
+	ChangedKeys map[reflect.Value]struct{}
+}
+
+func newChangeAnalysis(lst1, lst2 []Revision, keyName string) *changeAnalysis {
+	changes := &changeAnalysis{}
+
+	changes.KeyMap1 = make(map[reflect.Value]int)
+	changes.KeyMap2 = make(map[reflect.Value]int)
+
+	changes.AddedKeys = make(map[reflect.Value]struct{})
+	changes.RemovedKeys = make(map[reflect.Value]struct{})
+	changes.ChangedKeys = make(map[reflect.Value]struct{})
+
+	for i, rev := range lst1 {
+		_, v := GetAttributeValue(rev.GetData(), keyName, 0)
+		changes.KeyMap1[v] = i
+	}
+	for i, rev := range lst2 {
+		_, v := GetAttributeValue(rev.GetData(), keyName, 0)
+		changes.KeyMap2[v] = i
+	}
+	for v, _ := range changes.KeyMap2 {
+		if _, ok := changes.KeyMap1[v]; !ok {
+			changes.AddedKeys[v] = struct{}{}
+		}
+	}
+	for v, _ := range changes.KeyMap1 {
+		if _, ok := changes.KeyMap2[v]; !ok {
+			changes.RemovedKeys[v] = struct{}{}
+		}
+	}
+	for v, _ := range changes.KeyMap1 {
+		if _, ok := changes.KeyMap2[v]; ok && lst1[changes.KeyMap1[v]].GetHash() != lst1[changes.KeyMap2[v]].GetHash() {
+			changes.ChangedKeys[v] = struct{}{}
+		}
+	}
+
+	return changes
+}
+
+func Merge3Way(
+	forkRev, srcRev, dstRev Revision,
+	mergeChildFunc func(Revision) Revision,
+	dryRun bool) (rev Revision, changes map[CallbackType][]interface{}) {
+
+	var configChanged bool
+
+	if dstRev.GetConfig() == forkRev.GetConfig() {
+		configChanged = dstRev.GetConfig() != srcRev.GetConfig()
+	} else {
+		if dstRev.GetConfig().Hash != srcRev.GetConfig().Hash {
+			log.Error("config-collision")
+		}
+		configChanged = true
+	}
+
+	newChildren := reflect.ValueOf(dstRev.GetChildren()).Elem().Interface().(map[string][]Revision)
+	childrenFields := ChildrenFields(forkRev.GetData())
+
+	for fieldName, field := range childrenFields {
+		forkList := forkRev.GetChildren()[fieldName]
+		srcList := srcRev.GetChildren()[fieldName]
+		dstList := dstRev.GetChildren()[fieldName]
+
+		if revisionsAreEqual(forkList, srcList) {
+			for _, rev := range srcList {
+				mergeChildFunc(rev)
+			}
+			continue
+		}
+
+		if field.Key == "" {
+			if revisionsAreEqual(dstList, forkList) {
+				if !revisionsAreEqual(srcList, forkList) {
+					log.Error("we should not be here")
+				} else {
+					for _, rev := range srcList {
+						newChildren[fieldName] = append(newChildren[fieldName], mergeChildFunc(rev))
+					}
+					if field.IsContainer {
+						changes[POST_LISTCHANGE] = append(
+							changes[POST_LISTCHANGE],
+							NewOperationContext("", nil, fieldName, ""),
+						)
+					}
+				}
+			} else {
+				if !revisionsAreEqual(srcList, forkList) {
+					log.Error("cannot merge - single child node or un-keyed children list has changed")
+				}
+			}
+		} else {
+			if revisionsAreEqual(dstList, forkList) {
+				src := newChangeAnalysis(forkList, srcList, field.Key)
+
+				newList := reflect.ValueOf(srcList).Elem().Interface().([]Revision)
+
+				for key, _ := range src.AddedKeys {
+					idx := src.KeyMap1[key]
+					newRev := mergeChildFunc(newList[idx])
+					newList[idx] = newRev
+
+					changes[POST_ADD] = append(
+						changes[POST_ADD],
+						newRev.GetData(),
+					)
+				}
+				for key, _ := range src.RemovedKeys {
+					oldRev := forkList[src.KeyMap1[key]]
+
+					changes[POST_REMOVE] = append(
+						changes[POST_REMOVE],
+						oldRev.GetData(),
+					)
+				}
+				for key, _ := range src.ChangedKeys {
+					idx := src.KeyMap2[key]
+					newRev := mergeChildFunc(newList[idx])
+					newList[idx] = newRev
+				}
+
+				newChildren[fieldName] = newList
+			} else {
+				src := newChangeAnalysis(forkList, srcList, field.Key)
+				dst := newChangeAnalysis(forkList, dstList, field.Key)
+
+				newList := reflect.ValueOf(dstList).Elem().Interface().([]Revision)
+
+				for key, _ := range src.AddedKeys {
+					if _, exists := dst.AddedKeys[key]; exists {
+						childDstRev := dstList[dst.KeyMap2[key]]
+						childSrcRev := srcList[src.KeyMap2[key]]
+						if childDstRev.GetHash() == childSrcRev.GetHash() {
+							mergeChildFunc(childDstRev)
+						} else {
+							log.Error("conflict error - revision has been added is different")
+						}
+					} else {
+						newRev := mergeChildFunc(srcList[src.KeyMap2[key]])
+						newList = append(newList, newRev)
+						changes[POST_ADD] = append(
+							changes[POST_ADD],
+							newRev.GetData(),
+						)
+					}
+				}
+				for key, _ := range src.ChangedKeys {
+					if _, removed := dst.RemovedKeys[key]; removed {
+						log.Error("conflict error - revision has been removed")
+					} else if _, changed := dst.ChangedKeys[key]; changed {
+						childDstRev := dstList[dst.KeyMap2[key]]
+						childSrcRev := srcList[src.KeyMap2[key]]
+						if childDstRev.GetHash() == childSrcRev.GetHash() {
+							mergeChildFunc(childSrcRev)
+						} else if childDstRev.GetConfig().Hash != childSrcRev.GetConfig().Hash {
+							log.Error("conflict error - revision has been changed and is different")
+						} else {
+							newRev := mergeChildFunc(srcList[src.KeyMap2[key]])
+							newList[dst.KeyMap2[key]] = newRev
+						}
+					} else {
+						newRev := mergeChildFunc(srcList[src.KeyMap2[key]])
+						newList[dst.KeyMap2[key]] = newRev
+					}
+				}
+
+				// TODO: how do i sort this map in reverse order?
+				for key, _ := range src.RemovedKeys {
+					if _, changed := dst.ChangedKeys[key]; changed {
+						log.Error("conflict error - revision has changed")
+					}
+					if _, removed := dst.ChangedKeys[key]; !removed {
+						dstIdx := dst.KeyMap2[key]
+						oldRev := newList[dstIdx]
+
+						copy(newList[dstIdx:], newList[dstIdx+1:])
+						newList[len(newList)-1] = nil
+						newList = newList[:len(newList)-1]
+
+						changes[POST_REMOVE] = append(
+							changes[POST_REMOVE],
+							oldRev.GetData(),
+						)
+					}
+				}
+
+				newChildren[fieldName] = newList
+
+			}
+		}
+	}
+
+	if !dryRun {
+		if configChanged {
+			rev = srcRev
+		} else {
+			rev = dstRev
+		}
+
+		rev = rev.UpdateAllChildren(newChildren, dstRev.GetBranch())
+
+		if configChanged {
+			changes[POST_UPDATE] = append(
+				changes[POST_UPDATE],
+				rev.GetData(),
+			)
+		}
+		return rev, changes
+	}
+
+	return nil, nil
+}
