Bug 66548 UIPerformChangeOperation doesn't completely guard UI access
In UIPerformChangeOperation::executeChange care is taken to execute the change on the UI thread, but "beginCompoundChange" and "endCompundChange" are not called on UI thread. I don't know if this is ever a problem in base Eclipse code, but our particular undoManager access a 'widget' and thus causes SWT thread access error, when the refactoring framework calls UIPerformChangeOperation::executeChange on our behalf. If it is the case that there is a contract is that "beginCompoundChange" and "endCompoundChange" are not supposed to to access UI thread, then I guess this would not be a bug in UIPerformChangeOperation, but I'd be surprised if this was part of "contract", since other methods in IRewriteTarget (e.g. redraw) would seem to need to access UI at some point (and doesn't seem to be specifically prohibited in JavaDoc of IRewriteTarget). My suggesttion is to move beginCompoundChange and endCompundChange to be inside the Runable that's created in executeChange (but haven't tried it yet).
org.eclipse.ltk.ui.refactoring/src/org/eclipse/ltk/internal/ui/refactoring/UIPerformChangeOperation.java
cancel.setEnabled(false);
							}
							try {
								UIPerformChangeOperation.super.executeChange(pm);
							} finally {
								if (cancel != null && !cancel.isDisposed()) {
									cancel.setEnabled(enabled);
								}
							}
							
						} catch (CoreException e) {
							exception[0]= e;
						}
					}
				};
				fDisplay.syncExec(r);
				if (exception[0] != null)
					throw new CoreException(exception[0].getStatus());
			} else {
				super.executeChange(pm);
			}
		} finally {
			if (targets != null)
				endCompoundChange(targets);
		}
	}
	private static void beginCompoundChange(IRewriteTarget[] targets) {
		for (int i= 0; i < targets.length; i++) {
			targets[i].beginCompoundChange();
		}