Using Eclipse RCP, I noticed that whenever I refreshed a TreeViewer the selection was lost. Reading the code, I found out that RCP was attempting to preserve the selection but it just wasn't working. After further experimentation, I noticed that treeViewer.setSelection(treeViewer.getSelection()) does not work at all. After a lot of fiddling around, I finally tracked down the problem: one of my model objects had a broken Object.equals() method that erroneously thought that the object was equal to the tree's root object. Needless to say, this caused the RCP framework to get very confused.
Having worked through all that, I was pleasantly surprised to find that the TreeViewer gracefully handles modifications to the model without collapsing the tree view or losing its selection. It uses the registered IElementComparer to perform the equality test (naturally, the default comparer uses Object.equals()).
One thing to note: if you do set an element comparer on a tree viewer, then for some reason the getElements() method on the ITreeContentProvider will be called.