Target Explorer: Reduce flicker on connect and disconnect
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/handler/DefaultContextSelectorToolbarContribution.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/handler/DefaultContextSelectorToolbarContribution.java
index 48834bf..8bfe4ed 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/handler/DefaultContextSelectorToolbarContribution.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/handler/DefaultContextSelectorToolbarContribution.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2014-2015 Wind River Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2014, 2016 Wind River Systems, Inc. and others. All rights reserved.
  * This program and the accompanying materials are made available under the terms
  * of the Eclipse Public License v1.0 which accompanies this distribution, and is
  * available at http://www.eclipse.org/legal/epl-v10.html
@@ -121,6 +121,8 @@
 
 	/* default */ Boolean signatureValid;
 
+	protected volatile boolean updatePending;
+
 	/**
 	 * Constructor.
 	 */
@@ -553,30 +555,35 @@
     										IPeerNodeProperties.PROPERTY_IS_VALID.equals(changeEvent.getEventId()) ||
     										IPeerNodeProperties.PROPERTY_WARNINGS.equals(changeEvent.getEventId()) ||
     										"properties".equals(changeEvent.getEventId())))) { //$NON-NLS-1$
-    			if (menuMgr != null) menuMgr.markDirty();
-    			ExecutorsUtil.executeInUI(new Runnable() {
-    				@Override
-    				public void run() {
-    					update();
-    				}
-    			});
+    			scheduleUpdate();
     		}
     	}
     }
 
+	private void scheduleUpdate() {
+		if (updatePending) return;
+		updatePending = true;
+		ExecutorsUtil.executeInUI(new Runnable() {
+			private boolean scheduled;
+			@Override
+			public void run() {
+				if (!scheduled) {
+					Display.getCurrent().timerExec(200, this);
+					scheduled = true;
+					return;
+				}
+				updatePending = false;
+				update();
+			}
+		});
+	}
 
 	/* (non-Javadoc)
 	 * @see org.eclipse.tcf.te.tcf.locator.interfaces.IPeerModelListener#modelChanged(org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerModel, org.eclipse.tcf.te.tcf.locator.interfaces.nodes.IPeerNode, boolean)
 	 */
     @Override
     public void modelChanged(IPeerModel model, IPeerNode peerNode, boolean added) {
-    	if (menuMgr != null) menuMgr.markDirty();
-		ExecutorsUtil.executeInUI(new Runnable() {
-			@Override
-			public void run() {
-				update();
-			}
-		});
+    	scheduleUpdate();
     }
 
 
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/SourceProvider.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/SourceProvider.java
index 46e1125..5a9cd9f 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/SourceProvider.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.ui/src/org/eclipse/tcf/te/tcf/ui/internal/SourceProvider.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2014 Wind River Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2012, 2016 Wind River Systems, Inc. and others. All rights reserved.
  * This program and the accompanying materials are made available under the terms
  * of the Eclipse Public License v1.0 which accompanies this distribution, and is
  * available at http://www.eclipse.org/legal/epl-v10.html
@@ -37,20 +37,24 @@
 	 */
 	public static final String defaultContextSelectionName = "defaultContextSelection"; //$NON-NLS-1$
 
+	// see org.eclipse.ui.internal.services.EvaluationService
+	private static final String RE_EVAL = "org.eclipse.ui.internal.services.EvaluationService.evaluate"; //$NON-NLS-1$
+
 	// The internal list of provided source names
 	private final static String[] PROVIDED_SOURCE_NAMES = {defaultContextSelectionName};
 
 	// The reference to the expression evaluation service
 	private IEvaluationService service = null;
 
-	private IPeerNode defaultContext = null;
+	private IPeerNode defaultContext;
+	private IPeerNode prevContext;
+	private volatile boolean changePending;
 
 	/**
      * Constructor.
      */
     public SourceProvider() {
     	super();
-	    EventManager.getInstance().addEventListener(this, ChangeEvent.class);
     }
 
 	/* (non-Javadoc)
@@ -61,6 +65,7 @@
 	    super.initialize(locator);
 
 	    defaultContext = ServiceManager.getInstance().getService(IDefaultContextService.class).getDefaultContext(null);
+	    EventManager.getInstance().addEventListener(this, ChangeEvent.class);
 
 	    // Register the source provider with the expression evaluation service
 	    if (locator.hasService(IEvaluationService.class)) {
@@ -109,19 +114,32 @@
     		ChangeEvent changeEvent = (ChangeEvent)event;
     		if (changeEvent.getSource() instanceof IDefaultContextService || changeEvent.getSource() == defaultContext) {
     			defaultContext = ServiceManager.getInstance().getService(IDefaultContextService.class).getDefaultContext(null);
+    			if (changePending || !PlatformUI.isWorkbenchRunning() || PlatformUI.getWorkbench().isClosing())
+    				return;
+    			changePending = true;
     			// Fire the source changed notification within the UI thread
-    			if (Display.getCurrent() != null) {
-	    			fireSourceChanged(ISources.WORKBENCH, defaultContextSelectionName, defaultContext != null ? defaultContext : IEvaluationContext.UNDEFINED_VARIABLE);
-    			} else if (PlatformUI.isWorkbenchRunning() && PlatformUI.getWorkbench().getDisplay() != null && !PlatformUI.getWorkbench().getDisplay().isDisposed()) {
-    				PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
-						@SuppressWarnings("synthetic-access")
-                        @Override
-						public void run() {
-			    			fireSourceChanged(ISources.WORKBENCH, defaultContextSelectionName, IEvaluationContext.UNDEFINED_VARIABLE);
-			    			fireSourceChanged(ISources.WORKBENCH, defaultContextSelectionName, defaultContext != null ? defaultContext : IEvaluationContext.UNDEFINED_VARIABLE);
-						}
-					});
-    			}
+    			final Display display = PlatformUI.getWorkbench().getDisplay();
+    			display.asyncExec(new Runnable() {
+    				private boolean scheduled;
+    				@SuppressWarnings("synthetic-access")
+    				@Override
+    				public void run() {
+    					if (service == null) return;
+    					if (!scheduled) {
+    						scheduled = true;
+    						display.timerExec(100, this);
+    						return;
+    					}
+    					IPeerNode newContext = defaultContext;
+    	    			changePending = false;
+    					if (newContext == prevContext) {
+    						// force re-evaluation of enablement expressions
+    						service.getCurrentState().addVariable(RE_EVAL, new Object());
+    					} else
+    						fireSourceChanged(ISources.WORKBENCH, defaultContextSelectionName, newContext != null ? newContext : IEvaluationContext.UNDEFINED_VARIABLE);
+    					prevContext = newContext;
+    				}
+    			});
     		}
     	}
     }
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/EditorEventListener.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/EditorEventListener.java
index d8b2e57..c4dd53c4 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/EditorEventListener.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/EditorEventListener.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2014 Wind River Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2011, 2016 Wind River Systems, Inc. and others. All rights reserved.
  * This program and the accompanying materials are made available under the terms
  * of the Eclipse Public License v1.0 which accompanies this distribution, and is
  * available at http://www.eclipse.org/legal/epl-v10.html
@@ -13,6 +13,7 @@
 
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.swt.widgets.Display;
 import org.eclipse.tcf.te.runtime.events.ChangeEvent;
 import org.eclipse.tcf.te.runtime.events.EventManager;
 import org.eclipse.tcf.te.runtime.interfaces.IDisposable;
@@ -34,9 +35,11 @@
  */
 public final class EditorEventListener extends AbstractEventListener implements IDisposable, IPropertyListener {
 	// Reference to the parent editor
-	private final Editor editor;
+	protected final Editor editor;
 	// Flag to remember the disposed action
-	private boolean disposed = false;
+	protected boolean disposed = false;
+	protected boolean changePending;
+	protected boolean fullRefresh;
 
 	/**
      * Constructor.
@@ -103,27 +106,42 @@
 			return;
 		}
 
-		// Refresh the page list. Changing editor input element properties
-		// may effect the page list -> Update in any case.
-		editor.updatePageList();
+		fullRefresh = fullRefresh || !"editor.refreshTab".equals(changeEvent.getEventId()); //$NON-NLS-1$
+		if (changePending) return;
 
-		// If the event is a "editor.refreshTab" event, skip the rest
-		if (!"editor.refreshTab".equals(changeEvent.getEventId())) { //$NON-NLS-1$
-			// Update the active page content by calling IFormPage#setActive(boolean)
-			Object page = editor.getSelectedPage();
-			if (page instanceof IFormPage) {
-				((IFormPage)page).setActive(((IFormPage)page).isActive());
+		changePending = true;
+		Display display = editor.getSite().getShell().getDisplay();
+		display.timerExec(200, new Runnable() {
+			@Override
+			public void run() {
+				if (disposed) return;
+				boolean doFullRefresh = fullRefresh;
+
+				// Refresh the page list. Changing editor input element properties
+				// may effect the page list -> Update in any case.
+				editor.updatePageList();
+
+				// If the event is a "editor.refreshTab" event, skip the rest
+				if (doFullRefresh) {
+					// Update the active page content by calling IFormPage#setActive(boolean)
+					Object page = editor.getSelectedPage();
+					if (page instanceof IFormPage) {
+						((IFormPage)page).setActive(((IFormPage)page).isActive());
+					}
+
+					// Update the editor part name
+					editor.updatePartName();
+
+					// Request a re-evaluation if all expressions referring the "activeEditorInput" source.
+					IEvaluationService service = (IEvaluationService)editor.getSite().getService(IEvaluationService.class);
+					if (service != null) {
+						service.requestEvaluation(ISources.ACTIVE_EDITOR_INPUT_NAME);
+					}
+				}
+				fullRefresh = false;
+				changePending = false;
 			}
-
-			// Update the editor part name
-			editor.updatePartName();
-
-			// Request a re-evaluation if all expressions referring the "activeEditorInput" source.
-			IEvaluationService service = (IEvaluationService)editor.getSite().getService(IEvaluationService.class);
-			if (service != null) {
-				service.requestEvaluation(ISources.ACTIVE_EDITOR_INPUT_NAME);
-			}
-		}
+		});
 	}
 
 	/* (non-Javadoc)
@@ -131,7 +149,7 @@
 	 */
     @Override
     public void propertyChanged(Object source, int propId) {
-    	if (source == this.editor) {
+    	if (source == this.editor && (!changePending || !fullRefresh)) {
     		if (IEditorPart.PROP_DIRTY == propId) {
     			// Request a re-evaluation if all expressions referring the "activeEditorInput" source.
     			IEvaluationService service = (IEvaluationService)editor.getSite().getService(IEvaluationService.class);
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/pages/AbstractCustomFormToolkitEditorPage.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/pages/AbstractCustomFormToolkitEditorPage.java
index f7de5b7..596044b 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/pages/AbstractCustomFormToolkitEditorPage.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/pages/AbstractCustomFormToolkitEditorPage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2014 Wind River Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2011, 2016 Wind River Systems, Inc. and others. All rights reserved.
  * This program and the accompanying materials are made available under the terms
  * of the Eclipse Public License v1.0 which accompanies this distribution, and is
  * available at http://www.eclipse.org/legal/epl-v10.html
@@ -42,6 +42,7 @@
 import org.eclipse.ui.IWorkbenchActionConstants;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
 import org.eclipse.ui.menus.IMenuService;
 
 /**
@@ -276,9 +277,11 @@
 	 * @param image The image or <code>null</code>.
 	 */
 	public void setFormImage(Image image) {
-		getManagedForm().getForm().setImage(image);
+		ScrolledForm form = getManagedForm().getForm();
+		if (form.getImage() != image) form.setImage(image);
 		if (getEditor() instanceof Editor) {
-			((Editor)getEditor()).setTitleImage(image);
+			Editor editor = (Editor)getEditor();
+			if (editor.getTitleImage() != image) editor.setTitleImage(image);
 		}
 	}
 
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/pages/AbstractEditorPage.java b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/pages/AbstractEditorPage.java
index 04a8ce0..3097847 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/pages/AbstractEditorPage.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.ui.views/src/org/eclipse/tcf/te/ui/views/editor/pages/AbstractEditorPage.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2014 Wind River Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2011, 2016 Wind River Systems, Inc. and others. All rights reserved.
  * This program and the accompanying materials are made available under the terms
  * of the Eclipse Public License v1.0 which accompanies this distribution, and is
  * available at http://www.eclipse.org/legal/epl-v10.html
@@ -47,6 +47,7 @@
 	private Composite messageComp = null;
 	private Label message = null;
 	private Label messageType = null;
+	private boolean hasHeadClient;
 	/**
 	 * Constructor.
 	 */
@@ -233,9 +234,11 @@
 				messageType.setImage(getMessageImage(type));
 				message.setText(text);
 				form.setHeadClient(messageComp);
+				hasHeadClient = true;
 			}
-			else {
+			else if (hasHeadClient) {
 				form.setHeadClient(null);
+				hasHeadClient = false;
 			}
 		}
 	}