Merge remote-tracking branch 'origin/R4_2_maintenance'
diff --git a/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ActiveContextsFunction.java b/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ActiveContextsFunction.java
index 1dd844d..c74fc11 100644
--- a/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ActiveContextsFunction.java
+++ b/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ActiveContextsFunction.java
@@ -11,6 +11,7 @@
 package org.eclipse.e4.ui.internal.services;
 
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.Set;
 import org.eclipse.e4.core.contexts.ContextFunction;
 import org.eclipse.e4.core.contexts.IEclipseContext;
@@ -25,7 +26,7 @@
 		boolean inDialog = false;
 		Set<String> rc = new HashSet<String>();
 		while (current != null) {
-			Set<String> locals = (Set<String>) current.getLocal(ContextContextService.LOCAL_CONTEXTS);
+			LinkedList<String> locals = (LinkedList<String>) current.getLocal(ContextContextService.LOCAL_CONTEXTS);
 			if (locals != null) {
 				if (!inDialog || !locals.contains("org.eclipse.ui.contexts.window")) {
 					rc.addAll(locals);
diff --git a/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ContextContextService.java b/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ContextContextService.java
index 712ab83..ce839b9 100644
--- a/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ContextContextService.java
+++ b/bundles/org.eclipse.e4.ui.services/src/org/eclipse/e4/ui/internal/services/ContextContextService.java
@@ -11,14 +11,12 @@
 
 package org.eclipse.e4.ui.internal.services;
 
-import org.eclipse.e4.core.contexts.IEclipseContext;
-
 import java.util.Collection;
-import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.Set;
-
 import org.eclipse.core.commands.contexts.Context;
 import org.eclipse.core.commands.contexts.ContextManager;
+import org.eclipse.e4.core.contexts.IEclipseContext;
 import org.eclipse.e4.ui.services.EContextService;
 import org.eclipse.e4.ui.services.IServiceConstants;
 
@@ -42,15 +40,18 @@
 	 * String)
 	 */
 	public void activateContext(String id) {
-		Set<String> locals = (Set<String>) eclipseContext
+		LinkedList<String> locals = (LinkedList<String>) eclipseContext
 				.getLocal(LOCAL_CONTEXTS);
 		if (locals == null) {
-			locals = new HashSet<String>();
+			locals = new LinkedList<String>();
 			locals.add(id);
 			eclipseContext.set(LOCAL_CONTEXTS, locals);
-		} else if (locals.add(id)) {
-			// copy the set so the change is propagated
-			eclipseContext.set(LOCAL_CONTEXTS, new HashSet<String>(locals));
+		} else {
+			boolean contained = locals.contains(id);
+			if (locals.add(id) && !contained) {
+				// copy the set so the change is propagated
+				eclipseContext.set(LOCAL_CONTEXTS, locals.clone());
+			}
 		}
 	}
 
@@ -62,12 +63,14 @@
 	 * .String)
 	 */
 	public void deactivateContext(String id) {
-		Set<String> locals = (Set<String>) eclipseContext
+		LinkedList<String> locals = (LinkedList<String>) eclipseContext
 				.getLocal(LOCAL_CONTEXTS);
 		if (locals != null && locals.remove(id)) {
-			// copy the set so the change is propagated
-			locals = new HashSet<String>(locals);
-			eclipseContext.set(LOCAL_CONTEXTS, locals);
+			boolean contained = locals.contains(id);
+			if (!contained) {
+				// copy the set so the change is propagated
+				eclipseContext.set(LOCAL_CONTEXTS, locals.clone());
+			}
 		}
 	}
 
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRenderer.java
index 84e1550..1451741 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/MenuManagerRenderer.java
@@ -847,6 +847,17 @@
 						}
 					} else {
 						modelChildren.add(childModel);
+						if (childModel instanceof MPopupMenu) {
+							if (((MPopupMenu) childModel).getContext() == null) {
+								IEclipseContext lclContext = getContext(menuModel);
+								if (lclContext != null) {
+									((MPopupMenu) childModel)
+											.setContext(lclContext
+													.createChild(childModel
+															.getElementId()));
+								}
+							}
+						}
 					}
 				}
 			} else if (item.isSeparator() || item.isGroupMarker()) {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPage.java
index 4968902..7e366eb 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPage.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/IWorkbenchPage.java
@@ -1209,7 +1209,23 @@
 
 	/**
 	 * Opens editors for the given inputs. Only the editor constructed for the
-	 * first input gets activated.
+	 * given index will be activated.
+	 * <p>
+	 * There are effectively two different ways to use this method based on what
+	 * information the supplied mementos contain @see
+	 * org.eclipse.ui.IWorkbenchPage
+	 * #getEditorState(org.eclipse.ui.IEditorReference []):
+	 * <ol>
+	 * <li>
+	 * If the mementos contain the 'input' information then only the memento
+	 * itself is required since it can be used to re-create the editor input and
+	 * its editorID. If all the mementos are of this type then the inputs and
+	 * editorIDs arrays may be null.</li>
+	 * <li>
+	 * If the supplied memento only contains the editor state then both the
+	 * input and editorID must be non-null.</li>
+	 * </ol>
+	 * </p>
 	 * <p>
 	 * The editor type is determined by mapping <code>editorIDs</code> to an
 	 * editor extension registered with the workbench. An editor id is passed
@@ -1234,11 +1250,18 @@
 	 *            the IDs of the editor extensions to use, in the order of
 	 *            inputs
 	 * @param mementos
-	 *            the mementos representing the state to open the editor with
+	 *            the mementos representing the state to open the editor with.
+	 *            If the supplied memento contains the input's state as well as
+	 *            the editor's state then the corresponding entries in the
+	 *            'inputs' and 'ids' arrays may be <code>null</code> (they will
+	 *            be created from the supplied memento).
 	 * 
 	 * @param matchFlags
 	 *            a bit mask consisting of zero or more of the MATCH_* constants
 	 *            OR-ed together
+	 * @param activateIndex
+	 *            the index of the editor to make active or -1 if no activation
+	 *            is desired.
 	 * @return references to the editors constructed for the inputs. The editors
 	 *         corresponding to those reference might not be materialized.
 	 * @exception MultiPartInitException
@@ -1249,7 +1272,8 @@
 	 * @since 3.8.2
 	 */
 	public IEditorReference[] openEditors(final IEditorInput[] inputs, final String[] editorIDs,
-			IMemento[] mementos, final int matchFlags) throws MultiPartInitException;
+			final IMemento[] mementos, final int matchFlags, final int activateIndex)
+			throws MultiPartInitException;
 
 	/**
 	 * Return an IMemento containing the current state of the editor for each of
@@ -1258,9 +1282,13 @@
 	 * 
 	 * @param editorRefs
 	 *            The array of editor references to get the state for
+	 * @param includeInputState
+	 *            If <code>true</code> then the resulting memento will be
+	 *            contain the editor input's state as well as the editor's
+	 *            state.
 	 * @return The array of mementos. The length of the array will match that of
 	 *         the refs array.
 	 * @since 3.8.2
 	 */
-	public IMemento[] getEditorState(IEditorReference[] editorRefs);
+	public IMemento[] getEditorState(IEditorReference[] editorRefs, boolean includeInputState);
 }
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/MultiPartInitException.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/MultiPartInitException.java
index 539febf..d0c8cf6 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/MultiPartInitException.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/MultiPartInitException.java
@@ -34,7 +34,7 @@
 	 */
 	public MultiPartInitException(IWorkbenchPartReference[] references,
 			PartInitException[] exceptions) {
-		super(exceptions[findSingleException(exceptions)].getStatus());
+		super(exceptions[findFirstException(exceptions)].getStatus());
 		this.references = references;
 		this.exceptions = exceptions;
 	}
@@ -61,20 +61,12 @@
 		return exceptions;
 	}
 
-	private static int findSingleException(PartInitException[] exceptions) {
-		int index = -1;
+	private static int findFirstException(PartInitException[] exceptions) {
 		for (int i = 0; i < exceptions.length; i++) {
-			if (exceptions[i] != null) {
-				if (index == -1) {
-					index = i;
-				} else
-					throw new IllegalArgumentException();
-			}
+			if (exceptions[i] != null)
+				return i;
 		}
-		if (index == -1) {
-			throw new IllegalArgumentException();
-		}
-		return index;
+		throw new IllegalArgumentException();
 	}
 
 	private static final long serialVersionUID = -9138185942975165490L;
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorReference.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorReference.java
index 7f4e7c2..7136d8c 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorReference.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/EditorReference.java
@@ -218,21 +218,31 @@
 	}
 
 	private IEditorInput restoreInput(IMemento editorMem) throws PartInitException {
+		return createInput(editorMem);
+	}
+
+	public static IEditorInput createInput(IMemento editorMem)
+			throws PartInitException {
+		String editorId = editorMem.getString(IWorkbenchConstants.TAG_ID);
+
 		IMemento inputMem = editorMem.getChild(IWorkbenchConstants.TAG_INPUT);
+
+		String editorName = null;
 		String factoryID = null;
 		if (inputMem != null) {
+			editorName = inputMem.getString(IWorkbenchConstants.TAG_PATH);
 			factoryID = inputMem.getString(IWorkbenchConstants.TAG_FACTORY_ID);
 		}
 		if (factoryID == null) {
 			throw new PartInitException(NLS.bind(
-					WorkbenchMessages.EditorManager_no_input_factory_ID, getId(), getName()));
+					WorkbenchMessages.EditorManager_no_input_factory_ID, editorId, editorName));
 		}
 		IAdaptable input = null;
 		IElementFactory factory = PlatformUI.getWorkbench().getElementFactory(factoryID);
 		if (factory == null) {
 			throw new PartInitException(NLS.bind(
 					WorkbenchMessages.EditorManager_bad_element_factory, new Object[] { factoryID,
-							getId(), getName() }));
+							editorId, editorName }));
 		}
 
 		// Get the input element.
@@ -240,12 +250,12 @@
 		if (input == null) {
 			throw new PartInitException(NLS.bind(
 					WorkbenchMessages.EditorManager_create_element_returned_null, new Object[] {
-							factoryID, getId(), getName() }));
+							factoryID, editorId, editorName }));
 		}
 		if (!(input instanceof IEditorInput)) {
 			throw new PartInitException(NLS.bind(
 					WorkbenchMessages.EditorManager_wrong_createElement_result, new Object[] {
-							factoryID, getId(), getName() }));
+							factoryID, editorId, editorName }));
 		}
 		return (IEditorInput) input;
 	}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PopupMenuExtender.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PopupMenuExtender.java
index 97d2a98..f4c6ec6 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PopupMenuExtender.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PopupMenuExtender.java
@@ -157,7 +157,7 @@
 		menuModel = null;
 		for (MMenu item : modelPart.getMenus()) {
 			if (id.equals(item.getElementId()) && item instanceof MPopupMenu
-					&& item.getTags().contains("popup")) { //$NON-NLS-1$
+					&& item.getTags().contains(ContributionsAnalyzer.MC_POPUP)) {
 				menuModel = (MPopupMenu) item;
 				break;
 			}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java
index a0500a6..2b813cb 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java
@@ -99,6 +99,7 @@
 import org.eclipse.ui.IPartListener;
 import org.eclipse.ui.IPartListener2;
 import org.eclipse.ui.IPathEditorInput;
+import org.eclipse.ui.IPersistableEditor;
 import org.eclipse.ui.IPersistableElement;
 import org.eclipse.ui.IPerspectiveDescriptor;
 import org.eclipse.ui.IPerspectiveFactory;
@@ -978,41 +979,19 @@
 	}
 
 	private List<EditorReference> getCurrentEditorReferences() {
-		List<EditorReference> sortedReferences = new ArrayList<EditorReference>();
-		for (MPart part : activationList) {
-			for (EditorReference ref : editorReferences) {
-				if (ref.getModel() == part) {
-					sortedReferences.add(ref);
-					break;
+		List<EditorReference> editorRefs = new ArrayList<EditorReference>();
+		List<MPart> visibleEditors = modelService.findElements(window,
+				CompatibilityEditor.MODEL_ELEMENT_ID, MPart.class, null);
+		for (MPart editor : visibleEditors) {
+			if (editor.isToBeRendered()) {
+				EditorReference ref = getEditorReference(editor);
+				if (ref != null && !editorRefs.contains(ref)) {
+					editorRefs.add(ref);
 				}
 			}
 		}
 
-		for (EditorReference ref : editorReferences) {
-			if (!sortedReferences.contains(ref)) {
-				sortedReferences.add(ref);
-			}
-		}
-
-		MPerspective currentPerspective = getCurrentPerspective();
-		if (currentPerspective != null) {
-			List<MPart> placeholders = modelService.findElements(window,
-					CompatibilityEditor.MODEL_ELEMENT_ID, MPart.class, null,
-					EModelService.PRESENTATION);
-			List<EditorReference> visibleReferences = new ArrayList<EditorReference>();
-			for (EditorReference reference : sortedReferences) {
-				for (MPart placeholder : placeholders) {
-					if (reference.getModel() == placeholder && placeholder.isToBeRendered()) {
-						// only rendered placeholders are valid references
-						visibleReferences.add(reference);
-					}
-				}
-			}
-
-			return visibleReferences;
-		}
-
-		return sortedReferences;
+		return editorRefs;
 	}
 
 	public List<EditorReference> getInternalEditorReferences() {
@@ -4211,10 +4190,13 @@
 	 * org.eclipse.ui.IWorkbenchPage#getEditorState(org.eclipse.ui.IEditorReference
 	 * [])
 	 */
-	public IMemento[] getEditorState(IEditorReference[] editorRefs) {
+	public IMemento[] getEditorState(IEditorReference[] editorRefs, boolean includeInputState) {
 		IMemento[] m = new IMemento[editorRefs.length];
 		for (int i = 0; i < editorRefs.length; i++) {
 			m[i] = ((EditorReference) editorRefs[i]).getEditorState();
+			if (!includeInputState && m[i] != null) {
+				m[i] = m[i].getChild(IWorkbenchConstants.TAG_EDITOR_STATE);
+			}
 		}
 		return m;
 	}
@@ -4227,7 +4209,7 @@
 	 * java.lang.String[], int)
 	 */
 	public IEditorReference[] openEditors(IEditorInput[] inputs, String[] editorIDs, int matchFlags) throws MultiPartInitException {
-		return openEditors(inputs, editorIDs, null, matchFlags);
+		return openEditors(inputs, editorIDs, null, matchFlags, 0);
 	}
 
 	/*
@@ -4237,43 +4219,97 @@
 	 * org.eclipse.ui.IWorkbenchPage#openEditors(org.eclipse.ui.IEditorInput[],
 	 * java.lang.String[], org.eclipse.ui.IMemento[], int)
 	 */
-	public IEditorReference[] openEditors(IEditorInput[] inputs, String[] editorIDs, IMemento[] mementos, int matchFlags)
+	public IEditorReference[] openEditors(IEditorInput[] inputs, String[] editorIDs,
+			IMemento[] mementos, int matchFlags, int activationIndex)
 			throws MultiPartInitException {
+		// If we are only working with mementos create a placeholder array of
+		// nulls
+		if (inputs == null) {
+			Assert.isTrue(mementos != null);
+			inputs = new IEditorInput[mementos.length];
+		}
+
+		// If we are only working with mementos create a placeholder array of
+		// nulls
+		if (editorIDs == null) {
+			Assert.isTrue(mementos != null);
+			editorIDs = new String[mementos.length];
+		}
+
 		Assert.isTrue(inputs.length == editorIDs.length);
 		Assert.isTrue(inputs.length > 0);
 		Assert.isTrue(mementos == null || mementos.length == inputs.length);
 
-		for (IEditorInput ei : inputs) {
-			System.out.println(ei.getName());
-		}
 		PartInitException[] exceptions = new PartInitException[inputs.length];
 		IEditorReference[] references = new IEditorReference[inputs.length];
 		boolean hasFailures = false;
 
 		IEditorRegistry reg = getWorkbenchWindow().getWorkbench().getEditorRegistry();
-		MPart firstEditor = null;
+		MPart editorToActivate = null;
 		for (int i = 0; i < inputs.length; i++) {
-			if (reg.findEditor(editorIDs[i]) == null) {
+			String curEditorID = editorIDs == null ? null : editorIDs[i];
+			IEditorInput curInput = inputs == null ? null : inputs[i];
+			IMemento curMemento = mementos == null ? null : mementos[i];
+
+			// If we don't have an editorID get it from the memento
+			if (curEditorID == null && curMemento != null) {
+				curEditorID = curMemento.getString(IWorkbenchConstants.TAG_ID);
+			}
+
+			// If we don't have an input create on from the memento
+			if (curInput == null && curMemento != null) {
+				try {
+					curInput = EditorReference.createInput(curMemento);
+				} catch (PartInitException e) {
+					curInput = null;
+					exceptions[i] = e;
+					hasFailures = true;
+					continue;
+				}
+			}
+
+			// Adjust the memento so that it's always 'comlpete (i.e. including
+			// both input and editor state)
+			if (curMemento != null && !curMemento.getID().equals(IWorkbenchConstants.TAG_EDITOR)) {
+				XMLMemento outerMem = XMLMemento.createWriteRoot(IWorkbenchConstants.TAG_EDITOR);
+				outerMem.putString(IWorkbenchConstants.TAG_ID, curEditorID);
+				outerMem.copyChild(curMemento);
+
+				XMLMemento inputMem = (XMLMemento) outerMem
+						.createChild(IWorkbenchConstants.TAG_INPUT);
+				inputMem.putString(IWorkbenchConstants.TAG_FACTORY_ID, curInput.getPersistable()
+						.getFactoryId());
+				inputMem.putString(IWorkbenchConstants.TAG_PATH, curInput.getName());
+			}
+
+			// OK, by this point we should have the EditorInput, the editor ID
+			// and the memento (if any)
+			if (reg.findEditor(curEditorID) == null) {
 				references[i] = null;
 				exceptions[i] = new PartInitException(NLS.bind(
-						WorkbenchMessages.EditorManager_unknownEditorIDMessage, editorIDs[i]));
+						WorkbenchMessages.EditorManager_unknownEditorIDMessage, curEditorID));
+				hasFailures = true;
+			} else if (curInput == null) {
+				references[i] = null;
+				exceptions[i] = new PartInitException(NLS.bind(
+						WorkbenchMessages.EditorManager_no_persisted_state, curEditorID));
 				hasFailures = true;
 			} else {
 				// Is there an existing editor ?
-				IEditorReference[] existingEditors = findEditors(inputs[i], editorIDs[i],
+				IEditorReference[] existingEditors = findEditors(curInput, curEditorID,
 						matchFlags);
 				if (existingEditors.length == 0) {
 					MPart editor = partService.createPart(CompatibilityEditor.MODEL_ELEMENT_ID);
-					references[i] = createEditorReferenceForPart(editor, inputs[i], editorIDs[i],
+					references[i] = createEditorReferenceForPart(editor, curInput, curEditorID,
 							null);
 
-					if (firstEditor == null)
-						firstEditor = editor;
+					if (i == activationIndex)
+						editorToActivate = editor;
 
 					// Set the information in the supplied IMemento into the
 					// editor's model
-					if (mementos != null && mementos[i] instanceof XMLMemento) {
-						XMLMemento memento = (XMLMemento) mementos[i];
+					if (curMemento instanceof XMLMemento) {
+						XMLMemento memento = (XMLMemento) curMemento;
 						StringWriter writer = new StringWriter();
 						try {
 							memento.save(writer);
@@ -4284,6 +4320,7 @@
 						}
 					}
 
+					System.out.println("OE: " + references[i].getTitle()); //$NON-NLS-1$
 					editor.setLabel(references[i].getTitle());
 					editor.setTooltip(references[i].getTitleToolTip());
 					editor.setIconURI(getEditorImageURI((EditorReference) references[i]));
@@ -4292,11 +4329,14 @@
 					// Use the existing editor, update the state if it has *not*
 					// been rendered
 					EditorReference ee = (EditorReference) existingEditors[0];
+					if (i == activationIndex)
+						editorToActivate = ee.getModel();
+
 					if (ee.getModel().getWidget() == null) {
 						// Set the information in the supplied IMemento into the
 						// editor's model
-						if (mementos != null && mementos[i] instanceof XMLMemento) {
-							XMLMemento momento = (XMLMemento) mementos[i];
+						if (curMemento instanceof XMLMemento) {
+							XMLMemento momento = (XMLMemento) curMemento;
 							StringWriter writer = new StringWriter();
 							try {
 								momento.save(writer);
@@ -4306,15 +4346,37 @@
 								WorkbenchPlugin.log(e);
 							}
 						}
-					}
+					} else {
+						// editor already rendered, try to update its state
+						if (curMemento != null
+								&& ee.getModel().getObject() instanceof CompatibilityEditor) {
+							CompatibilityEditor ce = (CompatibilityEditor) ee.getModel()
+									.getObject();
+							if (ce.getEditor() instanceof IPersistableEditor) {
+								IPersistableEditor pe = (IPersistableEditor) ce.getEditor();
 
-					if (firstEditor == null)
-						firstEditor = ee.getModel();
+								// Extract the 'editorState' from the memento
+								IMemento editorMem = curMemento
+										.getChild(IWorkbenchConstants.TAG_EDITOR_STATE);
+								if (editorMem == null) {
+									// Must be an externally defined memento,
+									// take the second child
+									IMemento[] kids = curMemento.getChildren();
+									if (kids.length == 2)
+										editorMem = kids[1];
+								}
+								if (editorMem != null)
+									pe.restoreState(editorMem);
+							}
+						}
+					}
 				}
 			}
 		}
 
-		partService.activate(firstEditor);
+		if (editorToActivate != null) {
+			partService.activate(editorToActivate);
+		}
 
 		boolean hasSuccesses = false;
 		for (IEditorReference reference : references) {
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/activities/MutableActivityManager.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/activities/MutableActivityManager.java
index bf92ebc..f306dd5 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/activities/MutableActivityManager.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/activities/MutableActivityManager.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation 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
@@ -22,7 +22,6 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
-
 import org.eclipse.core.expressions.Expression;
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -56,7 +55,7 @@
  */
 public final class MutableActivityManager extends AbstractActivityManager
         implements IMutableActivityManager, Cloneable {
-
+	
     private Map activitiesById = new HashMap();
 
     private Map activityRequirementBindingsByActivityId = new HashMap();
@@ -133,7 +132,7 @@
         readRegistry(true);
     }
 
-    public IActivity getActivity(String activityId) {
+	synchronized public IActivity getActivity(String activityId) {
         if (activityId == null) {
 			throw new NullPointerException();
 		}
@@ -149,7 +148,7 @@
         return activity;
     }
 
-    public ICategory getCategory(String categoryId) {
+	synchronized public ICategory getCategory(String categoryId) {
         if (categoryId == null) {
 			throw new NullPointerException();
 		}
@@ -165,19 +164,19 @@
         return category;
     }
 
-    public Set getDefinedActivityIds() {
+	synchronized public Set getDefinedActivityIds() {
         return Collections.unmodifiableSet(definedActivityIds);
     }
 
-    public Set getDefinedCategoryIds() {
+	synchronized public Set getDefinedCategoryIds() {
         return Collections.unmodifiableSet(definedCategoryIds);
     }
 
-    public Set getEnabledActivityIds() {
+	synchronized public Set getEnabledActivityIds() {
         return Collections.unmodifiableSet(enabledActivityIds);
     }
 
-    public IIdentifier getIdentifier(String identifierId) {
+	synchronized public IIdentifier getIdentifier(String identifierId) {
         if (identifierId == null) {
 			throw new NullPointerException();
 		}
@@ -523,7 +522,7 @@
 		}
 	}
 
-	public void setEnabledActivityIds(Set enabledActivityIds) {
+	synchronized public void setEnabledActivityIds(Set enabledActivityIds) {
         enabledActivityIds = new HashSet(enabledActivityIds);
         Set requiredActivityIds = new HashSet(enabledActivityIds);
         getRequiredActivityIds(enabledActivityIds, requiredActivityIds);
@@ -906,7 +905,7 @@
     /* (non-Javadoc)
      * @see java.lang.Object#clone()
      */
-    public Object clone() {
+	synchronized public Object clone() {
         MutableActivityManager clone = new MutableActivityManager(advisor, activityRegistry);
         clone.setEnabledActivityIds(getEnabledActivityIds());
         return clone;
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java
index 8fb2bad..f471cbe 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/contexts/ContextService.java
@@ -109,6 +109,8 @@
 		private String contextId;
 		private Expression expression;
 
+		private EvaluationResult cached = null;
+
 		public UpdateExpression(String contextId, Expression expression) {
 			this.contextId = contextId;
 			this.expression = expression;
@@ -122,7 +124,13 @@
 			ExpressionContext ctx = new ExpressionContext(eclipseContext.getActiveLeaf());
 			try {
 				if (updating) {
-					if (expression.evaluate(ctx) != EvaluationResult.FALSE) {
+					EvaluationResult result = expression.evaluate(ctx);
+					if (cached != null
+							&& (cached == result || (cached != EvaluationResult.FALSE && result != EvaluationResult.FALSE))) {
+						return updating;
+					}
+					cached = result;
+					if (result != EvaluationResult.FALSE) {
 						runExternalCode(new Runnable() {
 							public void run() {
 								contextService.activateContext(contextId);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java
index 352b795..d20dc13 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/quickaccess/SearchField.java
@@ -16,6 +16,7 @@
 import java.util.Map;
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
+import javax.inject.Inject;
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.expressions.EvaluationResult;
@@ -23,9 +24,13 @@
 import org.eclipse.core.expressions.ExpressionInfo;
 import org.eclipse.core.expressions.IEvaluationContext;
 import org.eclipse.core.runtime.Assert;
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
 import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.ui.di.Focus;
 import org.eclipse.e4.ui.model.application.MApplication;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
+import org.eclipse.e4.ui.workbench.modeling.EPartService;
 import org.eclipse.jface.dialogs.IDialogSettings;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.layout.GridLayoutFactory;
@@ -90,6 +95,9 @@
 	private int dialogWidth = -1;
 	private Control previousFocusControl;
 
+	@Inject
+	private EPartService partService;
+
 	@PostConstruct
 	void createWidget(final Composite parent, MApplication application, MWindow window) {
 		this.window = window;
@@ -151,6 +159,22 @@
 					addPreviousPick(string, element);
 					text.setText(""); //$NON-NLS-1$
 					element.execute();
+
+					/*
+					 * By design, attempting to activate a part that is already
+					 * active does not change the focus. However in the case of
+					 * using Quick Access, focus is not in the active part, so
+					 * re-activating the active part results in focus being left
+					 * behind in the text field. If this happens then assign
+					 * focus to the active part explicitly.
+					 */
+					if (text.isFocusControl()) {
+						MPart activePart = partService.getActivePart();
+						if (activePart != null) {
+							ContextInjectionFactory.invoke(activePart.getObject(), Focus.class,
+									activePart.getContext(), null);
+						}
+					}
 				}
 			}
 		};