####
8.2.10.1 Merge Algorithm

The above declarative description can also be expressed in pseudo-code as follows:

let **ws'** be the workspace against which the **merge** is done.

let **bestEffort** be the flag passed to **merge**.

let **failedset** be a set of UUIDs, initially empty.

let **startnode** be the node on which **merge** was called.

**domerge(startnode)**.

return the nodes with the UUIDs in **failedset**.

**domerge(n)**

let **n'** be the corresponding node of **n** in **ws'**.

if no such **n'** **doleave(n)**.

else if **n** is not versionable **doupdate(n, n')**.

else if **n'** is not versionable **doleave(n)**.

let **v** be base version of **n**.

let **v'** be base version of **n'**.

if **v'** is a successor of **v** and

**n** is not checked-in **doupdate(n, n')**.

else if **v** is equal to or a predecessor of **v'** **doleave(n)**.

else **dofail(n, v')**.

**dofail(n, v')**

if **bestEffort** = **false** throw **MergeException**.

else add UUID of **v'** (if not already present) to the

**jcr:mergeFailed** property of **n**,

add UUID of **n** to **failedset**,

**doleave(n)**.

**doLeave(n)**

for each child node **c** of **n domerge(c)**.

**doupdate(n, n')**

replace set of properties of **n** with those of **n'**.

let **S** be the set of child nodes of **n**.

let **S'** be the set of child nodes of **n'**.

judging by the name of the child node:

let **C** be the set of nodes in **S** and in **S'**

let **D** be the set of nodes in **S** but not in **S'**.

let **D'** be the set of nodes in **S'** but not in **S**.

remove from **n** all child nodes in **D**.

for each child node of **n'** in **D'** copy it (and its subtree) to **n**

as a new child node (if an incoming node has the same

UUID as a node already existing in this workspace,

the already existing node is removed).

for each child node **m** of **n** in **C** **domerge(m)**.