Bug 304277 - debug view: updating stack frames on suspend can take up to 40s
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ChildrenUpdate.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ChildrenUpdate.java
index 9900c09..425709b 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ChildrenUpdate.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/ChildrenUpdate.java
@@ -56,13 +56,10 @@
 					int viewIndex = provider.modelToViewIndex(elementPath, modelIndex);
 					if (provider.shouldFilter(elementPath, element)) {
 						if (provider.addFilteredIndex(elementPath, modelIndex, element)) {
-							if (viewer.getChildElement(elementPath, viewIndex) == null) {
-								// only remove the element if currently unmapped
-								if (ModelContentProvider.DEBUG_CONTENT_PROVIDER) {
-									System.out.println("REMOVE(" + getElement() + ", modelIndex: " + modelIndex + " viewIndex: " + viewIndex + ", " + element + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-								}
-								viewer.remove(elementPath, viewIndex);
+							if (ModelContentProvider.DEBUG_CONTENT_PROVIDER) {
+								System.out.println("REMOVE(" + getElement() + ", modelIndex: " + modelIndex + " viewIndex: " + viewIndex + ", " + element + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
 							}
+							viewer.remove(elementPath, viewIndex);
 						}
 					} else {
 						if (provider.isFiltered(elementPath, modelIndex)) {
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java
index d99677a..d43e0d1 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/InternalTreeModelViewer.java
@@ -1655,6 +1655,10 @@
 		}
 	}
 	
+	void clearSelection() {
+		getTree().setSelection(new TreeItem[0]);
+	}
+	
 	/**
 	 * Registers the specified listener for view update notifications.
 	 * 
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java
index dbe8ee2..f7d9fdc 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java
@@ -24,6 +24,7 @@
 import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
 import org.eclipse.jface.viewers.IBasicPropertyConstants;
 import org.eclipse.jface.viewers.ILazyTreePathContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.TreePath;
 import org.eclipse.jface.viewers.TreeSelection;
 import org.eclipse.jface.viewers.TreeViewer;
@@ -348,7 +349,14 @@
 	 */
 	protected void handleSelect(IModelDelta delta) {
 		int modelIndex = delta.getIndex();
-		TreeViewer treeViewer = getTreeViewer();
+		InternalTreeModelViewer treeViewer = (InternalTreeModelViewer) getTreeViewer();
+		// check if selection is allowed
+		IStructuredSelection candidate = new TreeSelection(getViewerTreePath(delta));
+		if (!treeViewer.overrideSelection(treeViewer.getSelection(), candidate)) {
+			return;
+		}
+		// empty the selection before replacing elements to avoid materializing elements (@see bug 305739)
+		treeViewer.clearSelection();
 		if (modelIndex >= 0) {
 			IModelDelta parentDelta = delta.getParentDelta();
 			TreePath parentPath = getViewerTreePath(parentDelta);
@@ -369,7 +377,7 @@
 				treeViewer.replace(parentPath, viewIndex, delta.getElement());
 			}
 		}
-		treeViewer.setSelection(new TreeSelection(getViewerTreePath(delta)));
+		treeViewer.setSelection(candidate, true, true);
 	}
 
 	/* (non-Javadoc)