Bug 405290 - Undo-ing to the point where the compare editor is not dirty
leaves you with no easy way to recalculate diffs


diff --git a/bundles/org.eclipse.compare/META-INF/MANIFEST.MF b/bundles/org.eclipse.compare/META-INF/MANIFEST.MF
index 016995a..3b2e66a 100644
--- a/bundles/org.eclipse.compare/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.compare/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.compare; singleton:=true
-Bundle-Version: 3.5.400.qualifier
+Bundle-Version: 3.5.500.qualifier
 Bundle-Activator: org.eclipse.compare.internal.CompareUIPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
index b1db005..3492dbd 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java
@@ -433,6 +433,7 @@
 	private DocumentMerger fMerger;
 	/** The current diff */
 	private Diff fCurrentDiff;
+	private Diff fSavedDiff;
 
 	// Bug 259362 - Update diffs after undo
 	private boolean copyOperationInProgress = false;
@@ -3007,11 +3008,17 @@
 		}
 		if (!isLeftDirty() && !isRightDirty()) {
 			fRedoDiff = false;
+			final Diff oldDiff = getLastDiff();
 			new UIJob(CompareMessages.DocumentMerger_0) {
 				public IStatus runInUIThread(IProgressMonitor monitor) {
 					if (!getControl().isDisposed()) {
 						doDiff();
-						if (!getControl().isDisposed()) { // doDiff() might have closed the editor
+						if (!getControl().isDisposed()) {
+							Diff newDiff = findNewDiff(oldDiff);
+							if (newDiff != null) {
+								updateStatus(newDiff);
+								setCurrentDiff(newDiff, true);
+							}
 							invalidateLines();
 							updateLines(doc);
 						}
@@ -3024,6 +3031,43 @@
 		}
 	}
 	
+	
+	private void saveDiff() {
+			fSavedDiff = fCurrentDiff;
+	}
+
+	private Diff getLastDiff() {
+		if (fCurrentDiff != null) {
+			return fCurrentDiff;
+		}
+		return fSavedDiff;
+	}
+	
+	
+	private Diff findNewDiff(Diff oldDiff) {
+		if (oldDiff == null)
+			return null;
+		Diff newDiff = findNewDiff(oldDiff, LEFT_CONTRIBUTOR);
+		if (newDiff == null) {
+			newDiff = findNewDiff(oldDiff, RIGHT_CONTRIBUTOR);
+		}
+		return newDiff;
+	}
+
+	private Diff findNewDiff(Diff oldDiff, char type) {
+		int offset = oldDiff.getPosition(type).offset;
+		int length = oldDiff.getPosition(type).length;
+
+		// DocumentMerger.findDiff method doesn't really work well with 0-length
+		// diffs
+		if (length == 0) {
+			if (offset > 0)
+				offset--;
+			length = 1;
+		}
+		return fMerger.findDiff(type, offset, offset + length);
+	}
+	
 	/*
 	 * This method is called if a range of text on one side is copied into an empty sub-document
 	 * on the other side. The method returns the position where the sub-document is placed into the base document.
@@ -3336,7 +3380,7 @@
 		fAncestor.resetLineBackground();
 		fLeft.resetLineBackground();
 		fRight.resetLineBackground();
-		
+		saveDiff();
 		fCurrentDiff= null;
 		try {
 			fMerger.doDiff();
@@ -4637,9 +4681,11 @@
 			}
 			
 			// now switch diffs
+			saveDiff();
 			fCurrentDiff= d;
 			revealDiff(d, d.isToken());
 		} else {
+			saveDiff();
 			fCurrentDiff= d;
 		}
 
@@ -4890,7 +4936,7 @@
 	 */
 	private boolean copy(Diff diff, boolean leftToRight) {
 		
-		if (diff != null && !diff.isResolved()) {
+		if (diff != null) {
 			if (!validateChange(!leftToRight))
 				return false;
 			if (leftToRight) {
@@ -5222,6 +5268,7 @@
 
 	private void resetDiffs() {
 		// clear stuff
+		saveDiff();
 		fCurrentDiff= null;
 		fMerger.reset();
 		resetPositions(fLeft.getSourceViewer().getDocument());
diff --git a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java
index c961c80..ef7bf02 100644
--- a/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java
+++ b/bundles/org.eclipse.compare/compare/org/eclipse/compare/internal/merge/DocumentMerger.java
@@ -1258,7 +1258,7 @@
 	 */
 	public boolean copy(Diff diff, boolean leftToRight) {
 		
-		if (diff != null && !diff.isResolved()) {
+		if (diff != null) {
 			Position fromPos= null;
 			Position toPos= null;
 			IDocument fromDoc= null;