private void merge(ElementNavigator snapNav, ElementNavigator diffNav) { var snapPos = snapNav.Bookmark(); var diffPos = diffNav.Bookmark(); try { var matches = (new ElementMatcher()).Match(snapNav, diffNav); //Debug.WriteLine("Matches for children of {0}".FormatWith(snapNav.Path)); //matches.DumpMatches(snapNav, diffNav); foreach (var match in matches) { if (!snapNav.ReturnToBookmark(match.BaseBookmark)) throw Error.InvalidOperation("Internal merging error: bookmark {0} in snap is no longer available", match.BaseBookmark); if (!diffNav.ReturnToBookmark(match.DiffBookmark)) throw Error.InvalidOperation("Internal merging error: bookmark {0} in diff is no longer available", match.DiffBookmark); if (match.Action == ElementMatcher.MatchAction.Add) { // TODO: move this logic to matcher, the Add should point to the last slice where // the new slice will be added after. // Find last entry in slice to add to the end var current = snapNav.Path; while (snapNav.Current.Path == current && snapNav.MoveToNext()) ; snapNav.MoveToPrevious(); // take one step back... var dest = snapNav.Bookmark(); snapNav.ReturnToBookmark(match.BaseBookmark); snapNav.DuplicateAfter(dest); markChange(snapNav.Current); mergeElement(snapNav, diffNav); snapNav.Current.Slicing = null; // Probably not good enough... } else if (match.Action == ElementMatcher.MatchAction.Merge) { mergeElement(snapNav, diffNav); } else if (match.Action == ElementMatcher.MatchAction.Slice) { makeSlice(snapNav, diffNav); } } } finally { snapNav.ReturnToBookmark(snapPos); diffNav.ReturnToBookmark(diffPos); } }