func createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
	originalDoc := map[string]interface{}{}
	modifiedDoc := map[string]interface{}{}
	err := json.Unmarshal(originalJSON, &originalDoc)
	if err != nil {
		return nil, ErrBadJSONDoc
	}
	err = json.Unmarshal(modifiedJSON, &modifiedDoc)
	if err != nil {
		return nil, ErrBadJSONDoc
	}
	dest, err := getDiff(originalDoc, modifiedDoc)
	if err != nil {
		return nil, err
	}
	return json.Marshal(dest)
}
createObjectMergePatch will return a merge-patch document capable of
converting the original document to the modified document.
package jsonpatch
import (
	"bytes"
	"encoding/json"
	"fmt"
	"reflect"
)
func merge(cur, patch *lazyNode, mergeMerge bool) *lazyNode {
	curDoc, err := cur.intoDoc()
	if err != nil {
		pruneNulls(patch)
		return patch
	}
	patchDoc, err := patch.intoDoc()
	if err != nil {
		return patch
	}
	mergeDocs(curDoc, patchDoc, mergeMerge)
	return cur
}
func mergeDocs(doc, patch *partialDoc, mergeMerge bool) {
	for k, v := range *patch {
		if v == nil {
			if mergeMerge {
				(*doc)[k] = nil
			} else {
				delete(*doc, k)
			}
		} else {
			cur, ok := (*doc)[k]
			if !ok || cur == nil {
				if !mergeMerge {
					pruneNulls(v)
				}
				(*doc)[k] = v
			} else {
				(*doc)[k] = merge(cur, v, mergeMerge)
			}
		}
	}
}
func pruneNulls(n *lazyNode) {
	sub, err := n.intoDoc()
	if err == nil {
		pruneDocNulls(sub)
	} else {
		ary, err := n.intoAry()
		if err == nil {
			pruneAryNulls(ary)
		}
	}
}
func pruneDocNulls(doc *partialDoc) *partialDoc {
	for k, v := range *doc {
		if v == nil {
			delete(*doc, k)
		} else {
			pruneNulls(v)
		}
	}
	return doc
}
func pruneAryNulls(ary *partialArray) *partialArray {
	newAry := []*lazyNode{}
	for _, v := range *ary {
		if v != nil {
			pruneNulls(v)
		}
		newAry = append(newAry, v)
	}
	*ary = newAry
	return ary
}
var ErrBadJSONDoc = fmt.Errorf("Invalid JSON Document")
var ErrBadJSONPatch = fmt.Errorf("Invalid JSON Patch")
var errBadMergeTypes = fmt.Errorf("Mismatched JSON Documents")
func MergeMergePatches(patch1Data, patch2Data []byte) ([]byte, error) {
	return doMergePatch(patch1Data, patch2Data, true)
}
func MergePatch(docData, patchData []byte) ([]byte, error) {
	return doMergePatch(docData, patchData, false)
}
func doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {
	doc := &partialDoc{}
	docErr := json.Unmarshal(docData, doc)
	patch := &partialDoc{}
	patchErr := json.Unmarshal(patchData, patch)
	if _, ok := docErr.(*json.SyntaxError); ok {
		return nil, ErrBadJSONDoc
	}
	if _, ok := patchErr.(*json.SyntaxError); ok {
		return nil, ErrBadJSONPatch
	}
	if docErr == nil && *doc == nil {
		return nil, ErrBadJSONDoc
	}
	if patchErr == nil && *patch == nil {
		return nil, ErrBadJSONPatch
	}
	if docErr != nil || patchErr != nil {
		if patchErr == nil {
			if mergeMerge {
				doc = patch
			} else {
				doc = pruneDocNulls(patch)
			}
		} else {
			patchAry := &partialArray{}
			patchErr = json.Unmarshal(patchData, patchAry)
			if patchErr != nil {
				return nil, ErrBadJSONPatch
			}
			pruneAryNulls(patchAry)
			out, patchErr := json.Marshal(patchAry)
			if patchErr != nil {
				return nil, ErrBadJSONPatch
			}
			return out, nil
		}
	} else {
		mergeDocs(doc, patch, mergeMerge)
	}
	return json.Marshal(doc)
}
func resemblesJSONArray(input []byte) bool {
	input = bytes.TrimSpace(input)
	hasPrefix := bytes.HasPrefix(input, []byte("["))
	hasSuffix := bytes.HasSuffix(input, []byte("]"))
	return hasPrefix && hasSuffix
}
func CreateMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {
	originalResemblesArray := resemblesJSONArray(originalJSON)
	modifiedResemblesArray := resemblesJSONArray(modifiedJSON)
	if originalResemblesArray && modifiedResemblesArray {
		return createArrayMergePatch(originalJSON, modifiedJSON)
	}
	if !originalResemblesArray && !modifiedResemblesArray {
		return createObjectMergePatch(originalJSON, modifiedJSON)
	}
	return nil, errBadMergeTypes
}