throws Exception {
assert from != null;
assert to != null;
assert base != null;
NodeDelta theirDelta = new NodeDelta(store, store.getNodeState(from), store.getNodeState(base));
NodeDelta ourDelta = new NodeDelta(store, store.getNodeState(from), store.getNodeState(to));
// apply the changes
StagedNode stagedNode = getStagedNode(path, true);
for (Entry<String, String> added : ourDelta.getAddedProperties().entrySet()) {
String name = added.getKey();
String ourValue = added.getValue();
String theirValue = theirDelta.getAddedProperties().get(name);
if (theirValue != null && !theirValue.equals(ourValue)) {
markConflict(stagedNode, "addExistingProperty", name, ourValue);
}
else {
stagedNode.getProperties().put(name, ourValue);
}
}
for (Entry<String, String> removed : ourDelta.getRemovedProperties().entrySet()) {
String name = removed.getKey();
String ourValue = removed.getValue();
if (theirDelta.getRemovedProperties().containsKey(name)) {
markConflict(stagedNode, "deleteDeletedProperty", name, ourValue);
}
else if (theirDelta.getChangedProperties().containsKey(name)) {
markConflict(stagedNode, "deleteChangedProperty", name, ourValue);
}
else {
stagedNode.getProperties().remove(name);
}
}
for (Entry<String, String> changed : ourDelta.getChangedProperties().entrySet()) {
String name = changed.getKey();
String ourValue = changed.getValue();
String theirValue = theirDelta.getChangedProperties().get(name);
if (theirDelta.getRemovedProperties().containsKey(name)) {
markConflict(stagedNode, "changeDeletedProperty", name, ourValue);
}
else if (theirValue != null && !theirValue.equals(ourValue)) {
markConflict(stagedNode, "changeChangedProperty", name, ourValue);
}
else {
stagedNode.getProperties().put(name, ourValue);
}
}
for (Entry<String, Id> added : ourDelta.getAddedChildNodes().entrySet()) {
String name = added.getKey();
Id ourId = added.getValue();
Id theirId = theirDelta.getAddedChildNodes().get(name);
if (theirId != null && !theirId.equals(ourId)) {
markConflict(stagedNode, "addExistingNode", name, ourId);
}
else {
stagedNode.add(new ChildNodeEntry(name, ourId));
}
}
for (Entry<String, Id> removed : ourDelta.getRemovedChildNodes().entrySet()) {
String name = removed.getKey();
Id ourId = removed.getValue();
if (theirDelta.getRemovedChildNodes().containsKey(name)) {
markConflict(stagedNode, "deleteDeletedNode", name, ourId);
}
else if (theirDelta.getChangedChildNodes().containsKey(name)) {
markConflict(stagedNode, "deleteChangedNode", name, ourId);
}
else {
stagedNode.remove(name);
}
}
for (Entry<String, Id> changed : ourDelta.getChangedChildNodes().entrySet()) {
String name = changed.getKey();
Id ourId = changed.getValue();
StoredNode changedBase = getChildNode(base, name);
if (changedBase == null) {