diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/LegacyViewFactory.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/LegacyViewFactory.java
index f8acb64..669561c 100644
--- a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/LegacyViewFactory.java
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/e4/extensions/LegacyViewFactory.java
@@ -1,5 +1,8 @@
 package org.eclipse.e4.extensions;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.e4.core.services.context.EclipseContextFactory;
@@ -17,12 +20,17 @@
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.IEditorActionBarContributor;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.internal.EditorActionBars;
+import org.eclipse.ui.internal.EditorActionBuilder;
 import org.eclipse.ui.internal.EditorSite;
 import org.eclipse.ui.internal.ViewSite;
 import org.eclipse.ui.internal.WorkbenchPage;
+import org.eclipse.ui.internal.registry.EditorDescriptor;
 import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
 
 public class LegacyViewFactory extends SWTPartFactory {
@@ -59,14 +67,15 @@
 	private Control createEditor(MContributedPart<MPart<?>> part,
 			IConfigurationElement editorElement) {
 		Composite parent = (Composite) getParentWidget(part);
+		EditorDescriptor desc = new EditorDescriptor(part.getId(),
+				editorElement);
 
 		// part.setPlugin(viewContribution.getContributor().getName());
 		part.setIconURI(editorElement.getAttribute("icon")); //$NON-NLS-1$
 		//part.setName(editorElement.getAttribute("name")); //$NON-NLS-1$
 		IEditorPart impl = null;
 		try {
-			impl = (IEditorPart) editorElement
-					.createExecutableExtension("class"); //$NON-NLS-1$
+			impl = desc.createEditor();
 		} catch (CoreException e) {
 			e.printStackTrace();
 		}
@@ -91,6 +100,9 @@
 					.get(WorkbenchPage.class.getName());
 			ModelEditorReference ref = new ModelEditorReference(part, page);
 			EditorSite site = new EditorSite(ref, impl, page);
+			EditorActionBars bars = getEditorActionBars(desc, page, page
+					.getWorkbenchWindow(), part.getId());
+			site.setActionBars(bars);
 			site.setConfigurationElement(editorElement);
 			impl.init(site, (IEditorInput) localContext.get(IEditorInput.class
 					.getName()));
@@ -104,6 +116,43 @@
 		return null;
 	}
 
+	Map<String, EditorActionBars> actionCache = new HashMap<String, EditorActionBars>();
+
+	private EditorActionBars getEditorActionBars(EditorDescriptor desc,
+			WorkbenchPage page, IWorkbenchWindow workbenchWindow, String type) {
+		// Get the editor type.
+
+		// If an action bar already exists for this editor type return it.
+		EditorActionBars actionBars = actionCache.get(type);
+		if (actionBars != null) {
+			actionBars.addRef();
+			return actionBars;
+		}
+
+		// Create a new action bar set.
+		actionBars = new EditorActionBars(page, workbenchWindow, type);
+		actionBars.addRef();
+		actionCache.put(type, actionBars);
+
+		// Read base contributor.
+		IEditorActionBarContributor contr = desc.createActionBarContributor();
+		if (contr != null) {
+			actionBars.setEditorContributor(contr);
+			contr.init(actionBars, page);
+		}
+
+		// Read action extensions.
+		EditorActionBuilder builder = new EditorActionBuilder();
+		contr = builder.readActionExtensions(desc);
+		if (contr != null) {
+			actionBars.setExtensionContributor(contr);
+			contr.init(actionBars, page);
+		}
+
+		// Return action bars.
+		return actionBars;
+	}
+
 	private Control createView(MContributedPart<MPart<?>> part,
 			IConfigurationElement viewContribution) {
 		Composite parent = (Composite) getParentWidget(part);
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/EditorSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/EditorSite.java
index d3728b4..79a10dd 100644
--- a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/EditorSite.java
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/EditorSite.java
@@ -12,12 +12,8 @@
 
 import java.util.ArrayList;
 
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.action.IToolBarManager;
 import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.internal.provisional.action.ToolBarManager2;
 import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IActionBars2;
 import org.eclipse.ui.IEditorActionBarContributor;
 import org.eclipse.ui.IEditorPart;
@@ -44,29 +40,6 @@
 			WorkbenchPage page) {
 		super(ref, editor, page);
 
-		SubActionBars bars = new SubActionBars(((WorkbenchPage) page)
-				.getActionBars(), serviceLocator) {
-			private IToolBarManager tbMgr;
-			private MenuManager menuMgr;
-
-			@Override
-			public IToolBarManager getToolBarManager() {
-				if (tbMgr == null) {
-					tbMgr = new ToolBarManager2();
-				}
-				return tbMgr;
-			}
-
-			@Override
-			public IMenuManager getMenuManager() {
-				if (menuMgr == null) {
-					menuMgr = new MenuManager();
-				}
-				return menuMgr;
-			}
-		};
-		e4Context.set(IActionBars.class.getName(), bars);
-		setActionBars(bars);
 		// Initialize the services specific to this editor site.
 		initializeDefaultServices();
 	}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartSite.java
index 2602ed1..9a6be66 100644
--- a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartSite.java
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/PartSite.java
@@ -388,6 +388,7 @@
 	 * Sets the action bars for the part.
 	 */
 	public void setActionBars(SubActionBars bars) {
+		e4Context.set(IActionBars.class.getName(), bars);
 		actionBars = bars;
 	}
 
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewSite.java
index c509573..3509af1 100644
--- a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewSite.java
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/ViewSite.java
@@ -14,7 +14,6 @@
 import org.eclipse.jface.action.IToolBarManager;
 import org.eclipse.jface.action.MenuManager;
 import org.eclipse.jface.internal.provisional.action.ToolBarManager2;
-import org.eclipse.ui.IActionBars;
 import org.eclipse.ui.IViewPart;
 import org.eclipse.ui.IViewReference;
 import org.eclipse.ui.IViewSite;
@@ -55,7 +54,6 @@
 				return menuMgr;
 			}
 		};
-		e4Context.set(IActionBars.class.getName(), bars);
 		setActionBars(bars);
 	}
 
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/registry/EditorDescriptor.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/registry/EditorDescriptor.java
new file mode 100644
index 0000000..7c94906
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/internal/registry/EditorDescriptor.java
@@ -0,0 +1,682 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     James Blackburn - Bug 256316 getImageDescriptor() is not thread safe 
+ *******************************************************************************/
+package org.eclipse.ui.internal.registry;
+
+import java.io.File;
+import java.io.Serializable;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.program.Program;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorMatchingStrategy;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPluginContribution;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.internal.IWorkbenchConstants;
+import org.eclipse.ui.internal.WorkbenchImages;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.misc.ProgramImageDescriptor;
+import org.eclipse.ui.internal.tweaklets.InterceptContributions;
+import org.eclipse.ui.internal.tweaklets.Tweaklets;
+import org.eclipse.ui.internal.util.Util;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * @see IEditorDescriptor
+ */
+public final class EditorDescriptor implements IEditorDescriptor, Serializable,
+		IPluginContribution {
+
+	/**
+	 * Generated serial version UID for this class.
+	 * 
+	 * @since 3.1
+	 */
+	private static final long serialVersionUID = 3905241225668998961L;
+
+	// @issue the following constants need not be public; see bug 47600
+	/**
+	 * Open internal constant. Value <code>0x01</code>.
+	 */
+	public static final int OPEN_INTERNAL = 0x01;
+
+	/**
+	 * Open in place constant. Value <code>0x02</code>.
+	 */
+	public static final int OPEN_INPLACE = 0x02;
+
+	/**
+	 * Open external constant. Value <code>0x04</code>.
+	 */
+	public static final int OPEN_EXTERNAL = 0x04;
+
+	private String editorName;
+
+	private String imageFilename;
+
+	private transient ImageDescriptor imageDesc;
+	private transient Object imageDescLock = new Object();
+
+	private boolean testImage = true;
+
+	private String className;
+
+	private String launcherName;
+
+	private String fileName;
+
+	private String id = Util.ZERO_LENGTH_STRING;
+
+	private boolean matchingStrategyChecked = false;
+	private IEditorMatchingStrategy matchingStrategy;
+
+	private Program program;
+
+	// The id of the plugin which contributed this editor, null for external
+	// editors
+	private String pluginIdentifier;
+
+	private int openMode = 0;
+
+	private transient IConfigurationElement configurationElement;
+
+	/**
+	 * Create a new instance of an editor descriptor. Limited to internal
+	 * framework calls.
+	 * 
+	 * @param element
+	 * @param id2
+	 */
+	public EditorDescriptor(String id2, IConfigurationElement element) {
+		setID(id2);
+		setConfigurationElement(element);
+	}
+
+	/**
+	 * Create a new instance of an editor descriptor. Limited to internal
+	 * framework calls.
+	 */
+	/* package */EditorDescriptor() {
+		super();
+	}
+
+	/**
+	 * Creates a descriptor for an external program.
+	 * 
+	 * @param filename
+	 *            the external editor full path and filename
+	 * @return the editor descriptor
+	 */
+	public static EditorDescriptor createForProgram(String filename) {
+		if (filename == null) {
+			throw new IllegalArgumentException();
+		}
+		EditorDescriptor editor = new EditorDescriptor();
+
+		editor.setFileName(filename);
+		editor.setID(filename);
+		editor.setOpenMode(OPEN_EXTERNAL);
+
+		// Isolate the program name (no directory or extension)
+		int start = filename.lastIndexOf(File.separator);
+		String name;
+		if (start != -1) {
+			name = filename.substring(start + 1);
+		} else {
+			name = filename;
+		}
+		int end = name.lastIndexOf('.');
+		if (end != -1) {
+			name = name.substring(0, end);
+		}
+		editor.setName(name);
+
+		// get the program icon without storing it in the registry
+		ImageDescriptor imageDescriptor = new ProgramImageDescriptor(filename,
+				0);
+		editor.setImageDescriptor(imageDescriptor);
+
+		return editor;
+	}
+
+	/**
+	 * Return the program called programName. Return null if it is not found.
+	 * 
+	 * @return org.eclipse.swt.program.Program
+	 */
+	private static Program findProgram(String programName) {
+
+		Program[] programs = Program.getPrograms();
+		for (int i = 0; i < programs.length; i++) {
+			if (programs[i].getName().equals(programName)) {
+				return programs[i];
+			}
+		}
+
+		return null;
+	}
+
+	/**
+	 * Create the editor action bar contributor for editors of this type.
+	 * 
+	 * @return the action bar contributor, or <code>null</code>
+	 */
+	public IEditorActionBarContributor createActionBarContributor() {
+		// Handle case for predefined editor descriptors, like the
+		// one for IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID, which
+		// don't have a configuration element.
+		if (configurationElement == null) {
+			return null;
+		}
+
+		// Get the contributor class name.
+		String className = configurationElement
+				.getAttribute(IWorkbenchRegistryConstants.ATT_CONTRIBUTOR_CLASS);
+		if (className == null) {
+			return null;
+		}
+
+		// Create the contributor object.
+		IEditorActionBarContributor contributor = null;
+		try {
+			contributor = (IEditorActionBarContributor) WorkbenchPlugin
+					.createExtension(configurationElement,
+							IWorkbenchRegistryConstants.ATT_CONTRIBUTOR_CLASS);
+		} catch (CoreException e) {
+			WorkbenchPlugin.log("Unable to create editor contributor: " + //$NON-NLS-1$
+					id, e.getStatus());
+		}
+		return contributor;
+	}
+
+	/**
+	 * Return the editor class name.
+	 * 
+	 * @return the class name
+	 */
+	public String getClassName() {
+		if (configurationElement == null) {
+			return className;
+		}
+		return RegistryReader.getClassValue(configurationElement,
+				IWorkbenchRegistryConstants.ATT_CLASS);
+	}
+
+	/**
+	 * Return the configuration element used to define this editor, or
+	 * <code>null</code>.
+	 * 
+	 * @return the element or null
+	 */
+	public IConfigurationElement getConfigurationElement() {
+		return configurationElement;
+	}
+
+	/**
+	 * Create an editor part based on this descriptor.
+	 * 
+	 * @return the editor part
+	 * @throws CoreException
+	 *             thrown if there is an issue creating the editor
+	 */
+	public IEditorPart createEditor() throws CoreException {
+		Object extension = WorkbenchPlugin.createExtension(
+				getConfigurationElement(),
+				IWorkbenchRegistryConstants.ATT_CLASS);
+		return ((InterceptContributions) Tweaklets
+				.get(InterceptContributions.KEY)).tweakEditor(extension);
+	}
+
+	/**
+	 * Return the file name of the command to execute for this editor.
+	 * 
+	 * @return the file name to execute
+	 */
+	public String getFileName() {
+		if (program == null) {
+			if (configurationElement == null) {
+				return fileName;
+			}
+			return configurationElement
+					.getAttribute(IWorkbenchRegistryConstants.ATT_COMMAND);
+		}
+		return program.getName();
+	}
+
+	/**
+	 * Return the id for this editor.
+	 * 
+	 * @return the id
+	 */
+	public String getId() {
+		if (program == null) {
+			if (configurationElement == null) {
+				return Util.safeString(id);
+			}
+			return Util.safeString(configurationElement
+					.getAttribute(IWorkbenchRegistryConstants.ATT_ID));
+
+		}
+		return Util.safeString(program.getName());
+	}
+
+	/**
+	 * Return the image descriptor describing this editor.
+	 * 
+	 * @return the image descriptor
+	 */
+	public ImageDescriptor getImageDescriptor() {
+		ImageDescriptor tempDescriptor = null;
+
+		synchronized (imageDescLock) {
+			if (!testImage)
+				return imageDesc;
+
+			if (imageDesc == null) {
+				String imageFileName = getImageFilename();
+				String command = getFileName();
+				if (imageFileName != null && configurationElement != null)
+					tempDescriptor = AbstractUIPlugin
+							.imageDescriptorFromPlugin(configurationElement
+									.getNamespaceIdentifier(), imageFileName);
+				else if (command != null)
+					tempDescriptor = WorkbenchImages
+							.getImageDescriptorFromProgram(command, 0);
+			} else
+				tempDescriptor = imageDesc;
+
+			if (tempDescriptor == null) { // still null? return default image
+				imageDesc = WorkbenchImages
+						.getImageDescriptor(ISharedImages.IMG_OBJ_FILE);
+				testImage = false;
+				return imageDesc;
+			}
+		}
+
+		// Verifies that the image descriptor generates an image. If not, the
+		// descriptor is
+		// replaced with the default image.
+		// We must create the image without holding any locks, since there is a
+		// potential for deadlock
+		// on Linux due to SWT's implementation of Image. See bugs 265028 and
+		// 256316 for details.
+		Image img = tempDescriptor.createImage(false);
+		if (img == null) // @issue what should be the default image?
+			tempDescriptor = WorkbenchImages
+					.getImageDescriptor(ISharedImages.IMG_OBJ_FILE);
+		else
+			img.dispose();
+		// <----- End of must-not-lock part
+
+		// reenter synchronized block
+		synchronized (imageDescLock) {
+			// if another thread has set the image description, use it
+			if (!testImage)
+				return imageDesc;
+			// otherwise set the image description we calculated above
+			imageDesc = tempDescriptor;
+			testImage = false;
+			return imageDesc;
+		}
+	}
+
+	/**
+	 * The Image to use to repesent this editor
+	 */
+	/* package */void setImageDescriptor(ImageDescriptor desc) {
+		synchronized (imageDescLock) {
+			imageDesc = desc;
+			testImage = true;
+		}
+	}
+
+	/**
+	 * The name of the image describing this editor.
+	 * 
+	 * @return the image file name
+	 */
+	public String getImageFilename() {
+		if (configurationElement == null) {
+			return imageFilename;
+		}
+		return configurationElement
+				.getAttribute(IWorkbenchRegistryConstants.ATT_ICON);
+	}
+
+	/**
+	 * Return the user printable label for this editor.
+	 * 
+	 * @return the label
+	 */
+	public String getLabel() {
+		if (program == null) {
+			if (configurationElement == null) {
+				return editorName;
+			}
+			return configurationElement
+					.getAttribute(IWorkbenchRegistryConstants.ATT_NAME);
+		}
+		return program.getName();
+	}
+
+	/**
+	 * Returns the class name of the launcher.
+	 * 
+	 * @return the launcher class name
+	 */
+	public String getLauncher() {
+		if (configurationElement == null) {
+			return launcherName;
+		}
+		return configurationElement
+				.getAttribute(IWorkbenchRegistryConstants.ATT_LAUNCHER);
+	}
+
+	/**
+	 * Return the contributing plugin id.
+	 * 
+	 * @return the contributing plugin id
+	 */
+	public String getPluginID() {
+		if (configurationElement != null) {
+			return configurationElement.getNamespace();
+		}
+		return pluginIdentifier;
+	}
+
+	/**
+	 * Get the program for the receiver if there is one.
+	 * 
+	 * @return Program
+	 */
+	public Program getProgram() {
+		return this.program;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorDescriptor#isInternal
+	 */
+	public boolean isInternal() {
+		return getOpenMode() == OPEN_INTERNAL;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorDescriptor#isOpenInPlace
+	 */
+	public boolean isOpenInPlace() {
+		return getOpenMode() == OPEN_INPLACE;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorDescriptor#isOpenExternal
+	 */
+	public boolean isOpenExternal() {
+		return getOpenMode() == OPEN_EXTERNAL;
+	}
+
+	/**
+	 * Load the object properties from a memento.
+	 * 
+	 * @return <code>true</code> if the values are valid, <code>false</code>
+	 *         otherwise
+	 */
+	protected boolean loadValues(IMemento memento) {
+		editorName = memento.getString(IWorkbenchConstants.TAG_LABEL);
+		imageFilename = memento.getString(IWorkbenchConstants.TAG_IMAGE);
+		className = memento.getString(IWorkbenchConstants.TAG_CLASS);
+		launcherName = memento.getString(IWorkbenchConstants.TAG_LAUNCHER);
+		fileName = memento.getString(IWorkbenchConstants.TAG_FILE);
+		id = Util.safeString(memento.getString(IWorkbenchConstants.TAG_ID));
+		pluginIdentifier = memento.getString(IWorkbenchConstants.TAG_PLUGIN);
+
+		Integer openModeInt = memento
+				.getInteger(IWorkbenchConstants.TAG_OPEN_MODE);
+		if (openModeInt != null) {
+			openMode = openModeInt.intValue();
+		} else {
+			// legacy: handle the older attribute names, needed to allow reading
+			// of pre-3.0-RCP workspaces
+			boolean internal = new Boolean(memento
+					.getString(IWorkbenchConstants.TAG_INTERNAL))
+					.booleanValue();
+			boolean openInPlace = new Boolean(memento
+					.getString(IWorkbenchConstants.TAG_OPEN_IN_PLACE))
+					.booleanValue();
+			if (internal) {
+				openMode = OPEN_INTERNAL;
+			} else {
+				if (openInPlace) {
+					openMode = OPEN_INPLACE;
+				} else {
+					openMode = OPEN_EXTERNAL;
+				}
+			}
+		}
+		if (openMode != OPEN_EXTERNAL && openMode != OPEN_INTERNAL
+				&& openMode != OPEN_INPLACE) {
+			WorkbenchPlugin
+					.log("Ignoring editor descriptor with invalid openMode: " + this); //$NON-NLS-1$
+			return false;
+		}
+
+		String programName = memento
+				.getString(IWorkbenchConstants.TAG_PROGRAM_NAME);
+		if (programName != null) {
+			this.program = findProgram(programName);
+		}
+		return true;
+	}
+
+	/**
+	 * Save the object values in a IMemento
+	 */
+	protected void saveValues(IMemento memento) {
+		memento.putString(IWorkbenchConstants.TAG_LABEL, getLabel());
+		memento.putString(IWorkbenchConstants.TAG_IMAGE, getImageFilename());
+		memento.putString(IWorkbenchConstants.TAG_CLASS, getClassName());
+		memento.putString(IWorkbenchConstants.TAG_LAUNCHER, getLauncher());
+		memento.putString(IWorkbenchConstants.TAG_FILE, getFileName());
+		memento.putString(IWorkbenchConstants.TAG_ID, getId());
+		memento.putString(IWorkbenchConstants.TAG_PLUGIN, getPluginId());
+
+		memento.putInteger(IWorkbenchConstants.TAG_OPEN_MODE, getOpenMode());
+		// legacy: handle the older attribute names, needed to allow reading of
+		// workspace by pre-3.0-RCP eclipses
+		memento.putString(IWorkbenchConstants.TAG_INTERNAL, String
+				.valueOf(isInternal()));
+		memento.putString(IWorkbenchConstants.TAG_OPEN_IN_PLACE, String
+				.valueOf(isOpenInPlace()));
+
+		if (this.program != null) {
+			memento.putString(IWorkbenchConstants.TAG_PROGRAM_NAME,
+					this.program.getName());
+		}
+	}
+
+	/**
+	 * Return the open mode of this editor.
+	 * 
+	 * @return the open mode of this editor
+	 * @since 3.1
+	 */
+	private int getOpenMode() {
+		if (configurationElement == null) { // if we've been serialized, return
+			// our serialized value
+			return openMode;
+		} else if (getLauncher() != null) {
+			// open using a launcer
+			return EditorDescriptor.OPEN_EXTERNAL;
+		} else if (getFileName() != null) {
+			// open using an external editor
+			return EditorDescriptor.OPEN_EXTERNAL;
+		} else if (getPluginId() != null) {
+			// open using an internal editor
+			return EditorDescriptor.OPEN_INTERNAL;
+		} else {
+			return 0; // default for system editor
+		}
+	}
+
+	/**
+	 * Set the class name of an internal editor.
+	 */
+	/* package */void setClassName(String newClassName) {
+		className = newClassName;
+	}
+
+	/**
+	 * Set the configuration element which contributed this editor.
+	 */
+	/* package */void setConfigurationElement(
+			IConfigurationElement newConfigurationElement) {
+		configurationElement = newConfigurationElement;
+	}
+
+	/**
+	 * Set the filename of an external editor.
+	 */
+	/* package */void setFileName(String aFileName) {
+		fileName = aFileName;
+	}
+
+	/**
+	 * Set the id of the editor. For internal editors this is the id as provided
+	 * in the extension point For external editors it is path and filename of
+	 * the editor
+	 */
+	/* package */void setID(String anID) {
+		Assert.isNotNull(anID);
+		id = anID;
+	}
+
+	/**
+	 * The name of the image to use for this editor.
+	 */
+	/* package */void setImageFilename(String aFileName) {
+		imageFilename = aFileName;
+	}
+
+	/**
+	 * Sets the new launcher class name
+	 * 
+	 * @param newLauncher
+	 *            the new launcher
+	 */
+	/* package */void setLauncher(String newLauncher) {
+		launcherName = newLauncher;
+	}
+
+	/**
+	 * The label to show for this editor.
+	 */
+	/* package */void setName(String newName) {
+		editorName = newName;
+	}
+
+	/**
+	 * Sets the open mode of this editor descriptor.
+	 * 
+	 * @param mode
+	 *            the open mode
+	 * 
+	 * @issue this method is public as a temporary fix for bug 47600
+	 */
+	public void setOpenMode(int mode) {
+		openMode = mode;
+	}
+
+	/**
+	 * The id of the plugin which contributed this editor, null for external
+	 * editors.
+	 */
+	/* package */void setPluginIdentifier(String anID) {
+		pluginIdentifier = anID;
+	}
+
+	/**
+	 * Set the receivers program.
+	 * 
+	 * @param newProgram
+	 */
+	/* package */void setProgram(Program newProgram) {
+
+		this.program = newProgram;
+		if (editorName == null) {
+			setName(newProgram.getName());
+		}
+	}
+
+	/**
+	 * For debugging purposes only.
+	 */
+	public String toString() {
+		return "EditorDescriptor(id=" + getId() + ", label=" + getLabel() + ")"; //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-1$
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.activities.support.IPluginContribution#getLocalId()
+	 */
+	public String getLocalId() {
+		return getId();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.activities.support.IPluginContribution#getPluginId()
+	 */
+	public String getPluginId() {
+		return getPluginID();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IEditorDescriptor#getEditorManagementPolicy()
+	 */
+	public IEditorMatchingStrategy getEditorMatchingStrategy() {
+		if (matchingStrategy == null && !matchingStrategyChecked) {
+			matchingStrategyChecked = true;
+			if (program == null && configurationElement != null) {
+				if (configurationElement
+						.getAttribute(IWorkbenchRegistryConstants.ATT_MATCHING_STRATEGY) != null) {
+					try {
+						matchingStrategy = (IEditorMatchingStrategy) WorkbenchPlugin
+								.createExtension(
+										configurationElement,
+										IWorkbenchRegistryConstants.ATT_MATCHING_STRATEGY);
+					} catch (CoreException e) {
+						WorkbenchPlugin
+								.log(
+										"Error creating editor management policy for editor id " + getId(), e); //$NON-NLS-1$
+					}
+				}
+			}
+		}
+		return matchingStrategy;
+	}
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorPart.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorPart.java
new file mode 100644
index 0000000..cb95109
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorPart.java
@@ -0,0 +1,1311 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.part;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.util.Tracing;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.ListenerList;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.workbench.ui.internal.UISchedulerStrategy;
+import org.eclipse.jface.dialogs.IPageChangeProvider;
+import org.eclipse.jface.dialogs.IPageChangedListener;
+import org.eclipse.jface.dialogs.PageChangedEvent;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.CTabItem;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.INestableKeyBindingService;
+import org.eclipse.ui.IPartService;
+import org.eclipse.ui.IPropertyListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.EditorSite;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.misc.Policy;
+import org.eclipse.ui.internal.services.INestable;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.util.Util;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceLocator;
+
+/**
+ * A multi-page editor is an editor with multiple pages, each of which may
+ * contain an editor or an arbitrary SWT control.
+ * <p>
+ * Subclasses must implement the following methods:
+ * <ul>
+ * <li><code>createPages</code> - to create the required pages by calling one of
+ * the <code>addPage</code> methods</li>
+ * <li><code>IEditorPart.doSave</code> - to save contents of editor</li>
+ * <li><code>IEditorPart.doSaveAs</code> - to save contents of editor</li>
+ * <li><code>IEditorPart.isSaveAsAllowed</code> - to enable Save As</li>
+ * <li><code>IEditorPart.gotoMarker</code> - to scroll to a marker</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Multi-page editors have a single action bar contributor, which manages
+ * contributions for all the pages. The contributor must be a subclass of
+ * <code>MultiPageEditorActionBarContributor</code>. Note that since any nested
+ * editors are created directly in code by callers of
+ * <code>addPage(IEditorPart,IEditorInput)</code>, nested editors do not have
+ * their own contributors.
+ * </p>
+ * <p>
+ * As of 3.5 multi-page editors will post PageChangedEvents at the end of
+ * {@link #pageChange(int)}. Subclasses may override {@link #getSelectedPage()}
+ * to return a page appropriate to their multi-page editor. IPartListener2
+ * listeners registered with the IPartService can implement IPageChangedListener
+ * to be notified about all page change events within the workbench page or
+ * workbench window.
+ * </p>
+ * 
+ * @see org.eclipse.ui.part.MultiPageEditorActionBarContributor
+ * @see org.eclipse.jface.dialogs.IPageChangeProvider
+ * @see org.eclipse.jface.dialogs.IPageChangedListener
+ * @see org.eclipse.ui.IPartService
+ */
+public abstract class MultiPageEditorPart extends EditorPart implements
+		IPageChangeProvider {
+
+	private static final String COMMAND_NEXT_SUB_TAB = "org.eclipse.ui.navigate.nextSubTab"; //$NON-NLS-1$
+	private static final String COMMAND_PREVIOUS_SUB_TAB = "org.eclipse.ui.navigate.previousSubTab"; //$NON-NLS-1$
+
+	/**
+	 * Subclasses that override {@link #createPageContainer(Composite)} can use
+	 * this constant to get a site for the container that can be active while
+	 * the current page is deactivated.
+	 * 
+	 * @since 3.4
+	 * @see #activateSite()
+	 * @see #deactivateSite(boolean, boolean)
+	 * @see #getPageSite(int)
+	 */
+	protected static final int PAGE_CONTAINER_SITE = 65535;
+
+	/**
+	 * Private tracing output.
+	 */
+	private static final String TRACING_COMPONENT = "MPE"; //$NON-NLS-1$
+
+	/**
+	 * The active service locator. This value may be <code>null</code> if there
+	 * is no selected page, or if the selected page is a control with no site.
+	 */
+	private INestable activeServiceLocator;
+
+	/**
+	 * The container widget.
+	 */
+	private CTabFolder container;
+
+	/**
+	 * List of nested editors. Element type: IEditorPart. Need to hang onto them
+	 * here, in addition to using get/setData on the items, because dispose()
+	 * needs to access them, but widgetry has already been disposed at that
+	 * point.
+	 */
+	private ArrayList nestedEditors = new ArrayList(3);
+
+	private List pageSites = new ArrayList(3);
+
+	private IServiceLocator pageContainerSite;
+
+	private ListenerList pageChangeListeners = new ListenerList(
+			ListenerList.IDENTITY);
+
+	/**
+	 * Creates an empty multi-page editor with no pages.
+	 */
+	protected MultiPageEditorPart() {
+		super();
+	}
+
+	/**
+	 * Creates and adds a new page containing the given control to this
+	 * multi-page editor. The control may be <code>null</code>, allowing it to
+	 * be created and set later using <code>setControl</code>.
+	 * 
+	 * @param control
+	 *            the control, or <code>null</code>
+	 * @return the index of the new page
+	 * 
+	 * @see MultiPageEditorPart#setControl(int, Control)
+	 */
+	public int addPage(Control control) {
+		int index = getPageCount();
+		addPage(index, control);
+		return index;
+	}
+
+	/**
+	 * Creates and adds a new page containing the given control to this
+	 * multi-page editor. The page is added at the given index. The control may
+	 * be <code>null</code>, allowing it to be created and set later using
+	 * <code>setControl</code>.
+	 * 
+	 * @param index
+	 *            the index at which to add the page (0-based)
+	 * @param control
+	 *            the control, or <code>null</code>
+	 * 
+	 * @see MultiPageEditorPart#setControl(int, Control)
+	 */
+	public void addPage(int index, Control control) {
+		createItem(index, control);
+	}
+
+	/**
+	 * Creates and adds a new page containing the given editor to this
+	 * multi-page editor. This also hooks a property change listener on the
+	 * nested editor.
+	 * 
+	 * @param editor
+	 *            the nested editor
+	 * @param input
+	 *            the input for the nested editor
+	 * @return the index of the new page
+	 * @exception PartInitException
+	 *                if a new page could not be created
+	 * 
+	 * @see MultiPageEditorPart#handlePropertyChange(int) the handler for
+	 *      property change events from the nested editor
+	 */
+	public int addPage(IEditorPart editor, IEditorInput input)
+			throws PartInitException {
+		int index = getPageCount();
+		addPage(index, editor, input);
+		return index;
+	}
+
+	/**
+	 * Creates and adds a new page containing the given editor to this
+	 * multi-page editor. The page is added at the given index. This also hooks
+	 * a property change listener on the nested editor.
+	 * 
+	 * @param index
+	 *            the index at which to add the page (0-based)
+	 * @param editor
+	 *            the nested editor
+	 * @param input
+	 *            the input for the nested editor
+	 * @exception PartInitException
+	 *                if a new page could not be created
+	 * 
+	 * @see MultiPageEditorPart#handlePropertyChange(int) the handler for
+	 *      property change events from the nested editor
+	 */
+	public void addPage(int index, IEditorPart editor, IEditorInput input)
+			throws PartInitException {
+		IEditorSite site = createSite(editor);
+		// call init first so that if an exception is thrown, we have created no
+		// new widgets
+		editor.init(site, input);
+		Composite parent2 = new Composite(getContainer(),
+				getOrientation(editor));
+		parent2.setLayout(new FillLayout());
+		editor.createPartControl(parent2);
+		editor.addPropertyListener(new IPropertyListener() {
+			public void propertyChanged(Object source, int propertyId) {
+				MultiPageEditorPart.this.handlePropertyChange(propertyId);
+			}
+		});
+		// create item for page only after createPartControl has succeeded
+		Item item = createItem(index, parent2);
+		// remember the editor, as both data on the item, and in the list of
+		// editors (see field comment)
+		item.setData(editor);
+		nestedEditors.add(editor);
+	}
+
+	/**
+	 * Get the orientation of the editor.
+	 * 
+	 * @param editor
+	 * @return int the orientation flag
+	 * @see SWT#RIGHT_TO_LEFT
+	 * @see SWT#LEFT_TO_RIGHT
+	 * @see SWT#NONE
+	 */
+	private int getOrientation(IEditorPart editor) {
+		if (editor instanceof IWorkbenchPartOrientation) {
+			return ((IWorkbenchPartOrientation) editor).getOrientation();
+		}
+		return getOrientation();
+	}
+
+	/**
+	 * Creates an empty container. Creates a CTabFolder with no style bits set,
+	 * and hooks a selection listener which calls <code>pageChange()</code>
+	 * whenever the selected tab changes.
+	 * 
+	 * @param parent
+	 *            The composite in which the container tab folder should be
+	 *            created; must not be <code>null</code>.
+	 * @return a new container
+	 */
+	private CTabFolder createContainer(Composite parent) {
+		// use SWT.FLAT style so that an extra 1 pixel border is not reserved
+		// inside the folder
+		parent.setLayout(new FillLayout());
+		final CTabFolder newContainer = new CTabFolder(parent, SWT.BOTTOM
+				| SWT.FLAT);
+		newContainer.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				int newPageIndex = newContainer.indexOf((CTabItem) e.item);
+				pageChange(newPageIndex);
+			}
+		});
+		newContainer.addTraverseListener(new TraverseListener() {
+			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=199499 :
+			// Switching tabs by Ctrl+PageUp/PageDown must not be caught on the
+			// inner tab set
+			public void keyTraversed(TraverseEvent e) {
+				switch (e.detail) {
+				case SWT.TRAVERSE_PAGE_NEXT:
+				case SWT.TRAVERSE_PAGE_PREVIOUS:
+					int detail = e.detail;
+					e.doit = true;
+					e.detail = SWT.TRAVERSE_NONE;
+					Control control = newContainer.getParent();
+					do {
+						if (control.traverse(detail))
+							return;
+						if (control.getListeners(SWT.Traverse).length != 0)
+							return;
+						if (control instanceof Shell)
+							return;
+						control = control.getParent();
+					} while (control != null);
+				}
+			}
+		});
+		return newContainer;
+	}
+
+	/**
+	 * Creates a tab item at the given index and places the given control in the
+	 * new item. The item is a CTabItem with no style bits set.
+	 * 
+	 * @param index
+	 *            the index at which to add the control
+	 * @param control
+	 *            is the control to be placed in an item
+	 * @return a new item
+	 */
+	private CTabItem createItem(int index, Control control) {
+		CTabItem item = new CTabItem(getTabFolder(), SWT.NONE, index);
+		item.setControl(control);
+		return item;
+	}
+
+	/**
+	 * Creates the pages of this multi-page editor.
+	 * <p>
+	 * Subclasses must implement this method.
+	 * </p>
+	 */
+	protected abstract void createPages();
+
+	/**
+	 * The <code>MultiPageEditor</code> implementation of this
+	 * <code>IWorkbenchPart</code> method creates the control for the multi-page
+	 * editor by calling <code>createContainer</code>, then
+	 * <code>createPages</code>. Subclasses should implement
+	 * <code>createPages</code> rather than overriding this method.
+	 * 
+	 * @param parent
+	 *            The parent in which the editor should be created; must not be
+	 *            <code>null</code>.
+	 */
+	public final void createPartControl(Composite parent) {
+		Composite pageContainer = createPageContainer(parent);
+		this.container = createContainer(pageContainer);
+		createPages();
+		// set the active page (page 0 by default), unless it has already been
+		// done
+		if (getActivePage() == -1) {
+			setActivePage(0);
+			IEditorPart part = getEditor(0);
+			if (part != null) {
+				final IServiceLocator serviceLocator = part.getEditorSite();
+				if (serviceLocator instanceof INestable) {
+					activeServiceLocator = (INestable) serviceLocator;
+					activeServiceLocator.activate();
+				}
+			}
+		}
+		initializePageSwitching();
+		initializeSubTabSwitching();
+	}
+
+	/**
+	 * Initialize the MultiPageEditorPart to use the page switching command.
+	 * Clients can override this method with an empty body if they wish to
+	 * opt-out.
+	 * 
+	 * @since 3.4
+	 */
+	protected void initializePageSwitching() {
+		new PageSwitcher(this) {
+			public Object[] getPages() {
+				int pageCount = getPageCount();
+				Object[] result = new Object[pageCount];
+				for (int i = 0; i < pageCount; i++) {
+					result[i] = new Integer(i);
+				}
+				return result;
+			}
+
+			public String getName(Object page) {
+				return getPageText(((Integer) page).intValue());
+			}
+
+			public ImageDescriptor getImageDescriptor(Object page) {
+				Image image = getPageImage(((Integer) page).intValue());
+				if (image == null)
+					return null;
+
+				return ImageDescriptor.createFromImage(image);
+			}
+
+			public void activatePage(Object page) {
+				setActivePage(((Integer) page).intValue());
+			}
+
+			public int getCurrentPageIndex() {
+				return getActivePage();
+			}
+		};
+	}
+
+	/**
+	 * Initialize the MultiPageEditorPart to use the sub-tab switching commands.
+	 * 
+	 * @since 3.5
+	 */
+	private void initializeSubTabSwitching() {
+		IHandlerService service = (IHandlerService) getSite().getService(
+				IHandlerService.class);
+		service.activateHandler(COMMAND_NEXT_SUB_TAB, new AbstractHandler() {
+			/**
+			 * {@inheritDoc}
+			 * 
+			 * @throws ExecutionException
+			 *             if an exception occurred during execution
+			 */
+			public Object execute(ExecutionEvent event)
+					throws ExecutionException {
+				int n = getPageCount();
+				if (n == 0)
+					return null;
+
+				int i = getActivePage() + 1;
+				if (i >= n)
+					i = 0;
+				setActivePage(i);
+				return null;
+			}
+		});
+
+		service.activateHandler(COMMAND_PREVIOUS_SUB_TAB,
+				new AbstractHandler() {
+					/**
+					 * {@inheritDoc}
+					 * 
+					 * @throws ExecutionException
+					 *             if an exception occurred during execution
+					 */
+					public Object execute(ExecutionEvent event)
+							throws ExecutionException {
+						int n = getPageCount();
+						if (n == 0)
+							return null;
+
+						int i = getActivePage() - 1;
+						if (i < 0)
+							i = n - 1;
+						setActivePage(i);
+						return null;
+					}
+				});
+	}
+
+	/**
+	 * Creates the parent control for the container returned by
+	 * {@link #getContainer() }.
+	 * 
+	 * <p>
+	 * Subclasses may extend and must call super implementation first.
+	 * </p>
+	 * 
+	 * @param parent
+	 *            the parent for all of the editors contents.
+	 * @return the parent for this editor's container. Must not be
+	 *         <code>null</code>.
+	 * 
+	 * @since 3.2
+	 */
+	protected Composite createPageContainer(Composite parent) {
+		return parent;
+	}
+
+	/**
+	 * Creates the site for the given nested editor. The
+	 * <code>MultiPageEditorPart</code> implementation of this method creates an
+	 * instance of <code>MultiPageEditorSite</code>. Subclasses may reimplement
+	 * to create more specialized sites.
+	 * 
+	 * @param editor
+	 *            the nested editor
+	 * @return the editor site
+	 */
+	protected IEditorSite createSite(IEditorPart editor) {
+		return new MultiPageEditorSite(this, editor);
+	}
+
+	/**
+	 * The <code>MultiPageEditorPart</code> implementation of this
+	 * <code>IWorkbenchPart</code> method disposes all nested editors.
+	 * Subclasses may extend.
+	 */
+	public void dispose() {
+		pageChangeListeners.clear();
+		for (int i = 0; i < nestedEditors.size(); ++i) {
+			IEditorPart editor = (IEditorPart) nestedEditors.get(i);
+			disposePart(editor);
+		}
+		nestedEditors.clear();
+		if (pageContainerSite instanceof IDisposable) {
+			((IDisposable) pageContainerSite).dispose();
+			pageContainerSite = null;
+		}
+		for (int i = 0; i < pageSites.size(); i++) {
+			IServiceLocator sl = (IServiceLocator) pageSites.get(i);
+			if (sl instanceof IDisposable) {
+				((IDisposable) sl).dispose();
+			}
+		}
+		pageSites.clear();
+		super.dispose();
+	}
+
+	/**
+	 * Returns the active nested editor if there is one.
+	 * <p>
+	 * Subclasses should not override this method
+	 * </p>
+	 * 
+	 * @nooverride
+	 * @return the active nested editor, or <code>null</code> if none
+	 */
+	protected IEditorPart getActiveEditor() {
+		int index = getActivePage();
+		if (index != -1) {
+			return getEditor(index);
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the index of the currently active page, or -1 if there is no
+	 * active page.
+	 * <p>
+	 * Subclasses should not override this method
+	 * </p>
+	 * 
+	 * @nooverride
+	 * 
+	 * @return the index of the active page, or -1 if there is no active page
+	 * @since 3.5
+	 */
+	public int getActivePage() {
+		CTabFolder tabFolder = getTabFolder();
+		if (tabFolder != null && !tabFolder.isDisposed()) {
+			return tabFolder.getSelectionIndex();
+		}
+		return -1;
+	}
+
+	/**
+	 * Returns the composite control containing this multi-page editor's pages.
+	 * This should be used as the parent when creating controls for the
+	 * individual pages. That is, when calling <code>addPage(Control)</code>,
+	 * the passed control should be a child of this container.
+	 * <p>
+	 * Warning: Clients should not assume that the container is any particular
+	 * subclass of Composite. The actual class used may change in order to
+	 * improve the look and feel of multi-page editors. Any code making
+	 * assumptions on the particular subclass would thus be broken.
+	 * </p>
+	 * <p>
+	 * Subclasses should not override this method
+	 * </p>
+	 * 
+	 * @return the composite, or <code>null</code> if
+	 *         <code>createPartControl</code> has not been called yet
+	 */
+	protected Composite getContainer() {
+		return container;
+	}
+
+	/**
+	 * Returns the control for the given page index, or <code>null</code> if no
+	 * control has been set for the page. The page index must be valid.
+	 * <p>
+	 * Subclasses should not override this method
+	 * </p>
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the control for the specified page, or <code>null</code> if none
+	 *         has been set
+	 */
+	protected Control getControl(int pageIndex) {
+		return getItem(pageIndex).getControl();
+	}
+
+	/**
+	 * Returns the editor for the given page index. The page index must be
+	 * valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the editor for the specified page, or <code>null</code> if the
+	 *         specified page was not created with
+	 *         <code>addPage(IEditorPart,IEditorInput)</code>
+	 */
+	protected IEditorPart getEditor(int pageIndex) {
+		Item item = getItem(pageIndex);
+		if (item != null) {
+			Object data = item.getData();
+			if (data instanceof IEditorPart) {
+				return (IEditorPart) data;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the service locator for the given page index. This method can be
+	 * used to create service locators for pages that are just controls. The
+	 * page index must be valid.
+	 * <p>
+	 * This will return the editor site service locator for an editor, and
+	 * create one for a page that is just a control.
+	 * </p>
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the editor for the specified page, or <code>null</code> if the
+	 *         specified page was not created with
+	 *         <code>addPage(IEditorPart,IEditorInput)</code>
+	 * @since 3.4
+	 */
+	protected final IServiceLocator getPageSite(int pageIndex) {
+		if (pageIndex == PAGE_CONTAINER_SITE) {
+			return getPageContainerSite();
+		}
+
+		Item item = getItem(pageIndex);
+		if (item != null) {
+			Object data = item.getData();
+			if (data instanceof IEditorPart) {
+				return ((IEditorPart) data).getSite();
+			} else if (data instanceof IServiceLocator) {
+				return (IServiceLocator) data;
+			} else if (data == null) {
+				IServiceLocatorCreator slc = (IServiceLocatorCreator) getSite()
+						.getService(IServiceLocatorCreator.class);
+				IServiceLocator sl = slc.createServiceLocator(getSite(), null,
+						new IDisposable() {
+							public void dispose() {
+								final Control control = ((PartSite) getSite())
+										.getPane().getControl();
+								if (control != null && !control.isDisposed()) {
+									((PartSite) getSite()).getPane().doHide();
+								}
+							}
+						});
+				IEclipseContext e4Context = EclipseContextFactory.create(
+						((EditorSite) getSite()).getContext(),
+						UISchedulerStrategy.getInstance());
+				((ServiceLocator) sl).setContext(e4Context);
+				item.setData(sl);
+				pageSites.add(sl);
+				return sl;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @return A site that can be used with a header.
+	 * @since 3.4
+	 * @see #createPageContainer(Composite)
+	 * @see #PAGE_CONTAINER_SITE
+	 * @see #getPageSite(int)
+	 */
+	private IServiceLocator getPageContainerSite() {
+		if (pageContainerSite == null) {
+			IServiceLocatorCreator slc = (IServiceLocatorCreator) getSite()
+					.getService(IServiceLocatorCreator.class);
+			pageContainerSite = slc.createServiceLocator(getSite(), null,
+					new IDisposable() {
+						public void dispose() {
+							final Control control = ((PartSite) getSite())
+									.getPane().getControl();
+							if (control != null && !control.isDisposed()) {
+								((PartSite) getSite()).getPane().doHide();
+							}
+						}
+					});
+			IEclipseContext e4Context = EclipseContextFactory.create(
+					((EditorSite) getSite()).getContext(), UISchedulerStrategy
+							.getInstance());
+			((ServiceLocator) pageContainerSite).setContext(e4Context);
+		}
+		return pageContainerSite;
+	}
+
+	/**
+	 * Returns the tab item for the given page index (page index is 0-based).
+	 * The page index must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the tab item for the given page index
+	 */
+	private CTabItem getItem(int pageIndex) {
+		return getTabFolder().getItem(pageIndex);
+	}
+
+	/**
+	 * Returns the number of pages in this multi-page editor.
+	 * 
+	 * @return the number of pages
+	 */
+	protected int getPageCount() {
+		CTabFolder folder = getTabFolder();
+		// May not have been created yet, or may have been disposed.
+		if (folder != null && !folder.isDisposed()) {
+			return folder.getItemCount();
+		}
+		return 0;
+	}
+
+	/**
+	 * Returns the image for the page with the given index, or <code>null</code>
+	 * if no image has been set for the page. The page index must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the image, or <code>null</code> if none
+	 */
+	protected Image getPageImage(int pageIndex) {
+		return getItem(pageIndex).getImage();
+	}
+
+	/**
+	 * Returns the text label for the page with the given index. Returns the
+	 * empty string if no text label has been set for the page. The page index
+	 * must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @return the text label for the page
+	 */
+	protected String getPageText(int pageIndex) {
+		return getItem(pageIndex).getText();
+	}
+
+	/**
+	 * Returns the tab folder containing this multi-page editor's pages.
+	 * 
+	 * @return the tab folder, or <code>null</code> if
+	 *         <code>createPartControl</code> has not been called yet
+	 */
+	private CTabFolder getTabFolder() {
+		return container;
+	}
+
+	/**
+	 * Handles a property change notification from a nested editor. The default
+	 * implementation simply forwards the change to listeners on this multi-page
+	 * editor by calling <code>firePropertyChange</code> with the same property
+	 * id. For example, if the dirty state of a nested editor changes (property
+	 * id <code>IEditorPart.PROP_DIRTY</code>), this method handles it by firing
+	 * a property change event for <code>IEditorPart.PROP_DIRTY</code> to
+	 * property listeners on this multi-page editor.
+	 * <p>
+	 * Subclasses may extend or reimplement this method.
+	 * </p>
+	 * 
+	 * @param propertyId
+	 *            the id of the property that changed
+	 */
+	protected void handlePropertyChange(int propertyId) {
+		firePropertyChange(propertyId);
+	}
+
+	/**
+	 * The <code>MultiPageEditorPart</code> implementation of this
+	 * <code>IEditorPart</code> method sets its site to the given site, its
+	 * input to the given input, and the site's selection provider to a
+	 * <code>MultiPageSelectionProvider</code>. Subclasses may extend this
+	 * method.
+	 * 
+	 * @param site
+	 *            The site for which this part is being created; must not be
+	 *            <code>null</code>.
+	 * @param input
+	 *            The input on which this editor should be created; must not be
+	 *            <code>null</code>.
+	 * @throws PartInitException
+	 *             If the initialization of the part fails -- currently never.
+	 */
+	public void init(IEditorSite site, IEditorInput input)
+			throws PartInitException {
+		setSite(site);
+		setInput(input);
+		site.setSelectionProvider(new MultiPageSelectionProvider(this));
+	}
+
+	/**
+	 * The <code>MultiPageEditorPart</code> implementation of this
+	 * <code>IEditorPart</code> method returns whether the contents of any of
+	 * this multi-page editor's nested editors have changed since the last save.
+	 * Pages created with <code>addPage(Control)</code> are ignored.
+	 * <p>
+	 * Subclasses may extend or reimplement this method.
+	 * </p>
+	 * 
+	 * @return <code>true</code> if any of the nested editors are dirty;
+	 *         <code>false</code> otherwise.
+	 */
+	public boolean isDirty() {
+		// use nestedEditors to avoid SWT requests; see bug 12996
+		for (Iterator i = nestedEditors.iterator(); i.hasNext();) {
+			IEditorPart editor = (IEditorPart) i.next();
+			if (editor.isDirty()) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Notifies this multi-page editor that the page with the given id has been
+	 * activated. This method is called when the user selects a different tab.
+	 * <p>
+	 * The <code>MultiPageEditorPart</code> implementation of this method sets
+	 * focus to the new page, and notifies the action bar contributor (if there
+	 * is one). This checks whether the action bar contributor is an instance of
+	 * <code>MultiPageEditorActionBarContributor</code>, and, if so, calls
+	 * <code>setActivePage</code> with the active nested editor. This also fires
+	 * a selection change event if required.
+	 * </p>
+	 * <p>
+	 * Subclasses may extend this method.
+	 * </p>
+	 * 
+	 * @param newPageIndex
+	 *            the index of the activated page
+	 */
+	protected void pageChange(int newPageIndex) {
+		deactivateSite(false, false);
+
+		IPartService partService = (IPartService) getSite().getService(
+				IPartService.class);
+		if (partService.getActivePart() == this) {
+			setFocus();
+		}
+
+		IEditorPart activeEditor = getEditor(newPageIndex);
+
+		IEditorActionBarContributor contributor = getEditorSite()
+				.getActionBarContributor();
+		if (contributor != null
+				&& contributor instanceof MultiPageEditorActionBarContributor) {
+			((MultiPageEditorActionBarContributor) contributor)
+					.setActivePage(activeEditor);
+		}
+
+		if (activeEditor != null) {
+			ISelectionProvider selectionProvider = activeEditor.getSite()
+					.getSelectionProvider();
+			if (selectionProvider != null) {
+				ISelectionProvider outerProvider = getSite()
+						.getSelectionProvider();
+				if (outerProvider instanceof MultiPageSelectionProvider) {
+					SelectionChangedEvent event = new SelectionChangedEvent(
+							selectionProvider, selectionProvider.getSelection());
+
+					MultiPageSelectionProvider provider = (MultiPageSelectionProvider) outerProvider;
+					provider.fireSelectionChanged(event);
+					provider.firePostSelectionChanged(event);
+				} else {
+					if (Policy.DEBUG_MPE) {
+						Tracing.printTrace(TRACING_COMPONENT,
+								"MultiPageEditorPart " + getTitle() //$NON-NLS-1$
+										+ " did not propogate selection for " //$NON-NLS-1$
+										+ activeEditor.getTitle());
+					}
+				}
+			}
+		}
+
+		activateSite();
+		Object selectedPage = getSelectedPage();
+		if (selectedPage != null) {
+			firePageChanged(new PageChangedEvent(this, selectedPage));
+		}
+	}
+
+	/**
+	 * This method can be used by implementors of
+	 * {@link MultiPageEditorPart#createPageContainer(Composite)} to deactivate
+	 * the active inner editor services while their header has focus. A
+	 * deactivateSite() must have a matching call to activateSite() when
+	 * appropriate.
+	 * <p>
+	 * An new inner editor will have its site activated on a
+	 * {@link MultiPageEditorPart#pageChange(int)}.
+	 * </p>
+	 * <p>
+	 * <b>Note:</b> This API is evolving in 3.4 and this might not be its final
+	 * form.
+	 * </p>
+	 * 
+	 * @param immediate
+	 *            immediately deactivate the legacy keybinding service
+	 * @param containerSiteActive
+	 *            Leave the page container site active.
+	 * @since 3.4
+	 * @see #activateSite()
+	 * @see #createPageContainer(Composite)
+	 * @see #getPageSite(int)
+	 * @see #PAGE_CONTAINER_SITE
+	 */
+	protected final void deactivateSite(boolean immediate,
+			boolean containerSiteActive) {
+		// Deactivate the nested services from the last active service locator.
+		if (activeServiceLocator != null) {
+			activeServiceLocator.deactivate();
+			activeServiceLocator = null;
+		}
+
+		final int pageIndex = getActivePage();
+		final IKeyBindingService service = getSite().getKeyBindingService();
+		if (pageIndex < 0 || pageIndex >= getPageCount() || immediate) {
+			// There is no selected page, so deactivate the active service.
+			if (service instanceof INestableKeyBindingService) {
+				final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+				nestableService.activateKeyBindingService(null);
+			} else {
+				WorkbenchPlugin
+						.log("MultiPageEditorPart.deactivateSite()   Parent key binding service was not an instance of INestableKeyBindingService.  It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
+
+		if (containerSiteActive) {
+			IServiceLocator containerSite = getPageContainerSite();
+			if (containerSite instanceof INestable) {
+				activeServiceLocator = (INestable) containerSite;
+				activeServiceLocator.activate();
+			}
+		}
+	}
+
+	/**
+	 * This method can be used by implementors of
+	 * {@link #createPageContainer(Composite)} to activate the active inner
+	 * editor services when their header loses focus.
+	 * <p>
+	 * An new inner editor will have its site activated on a
+	 * {@link #pageChange(int)}.
+	 * </p>
+	 * <p>
+	 * <b>Note:</b> This API is evolving in 3.4 and this might not be its final
+	 * form.
+	 * </p>
+	 * 
+	 * @since 3.4
+	 * @see #deactivateSite(boolean,boolean)
+	 * @see #createPageContainer(Composite)
+	 * @see #getPageSite(int)
+	 */
+	protected final void activateSite() {
+		if (activeServiceLocator != null) {
+			activeServiceLocator.deactivate();
+			activeServiceLocator = null;
+		}
+
+		final IKeyBindingService service = getSite().getKeyBindingService();
+		final int pageIndex = getActivePage();
+		final IEditorPart editor = getEditor(pageIndex);
+
+		if (editor != null) {
+			// active the service for this inner editor
+			if (service instanceof INestableKeyBindingService) {
+				final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+				nestableService.activateKeyBindingService(editor
+						.getEditorSite());
+
+			} else {
+				WorkbenchPlugin
+						.log("MultiPageEditorPart.activateSite()   Parent key binding service was not an instance of INestableKeyBindingService.  It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			// Activate the services for the new service locator.
+			final IServiceLocator serviceLocator = editor.getEditorSite();
+			if (serviceLocator instanceof INestable) {
+				activeServiceLocator = (INestable) serviceLocator;
+				activeServiceLocator.activate();
+			}
+
+		} else {
+			Item item = getItem(pageIndex);
+
+			// There is no selected editor, so deactivate the active service.
+			if (service instanceof INestableKeyBindingService) {
+				final INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+				nestableService.activateKeyBindingService(null);
+			} else {
+				WorkbenchPlugin
+						.log("MultiPageEditorPart.activateSite()   Parent key binding service was not an instance of INestableKeyBindingService.  It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+
+			if (item.getData() instanceof INestable) {
+				activeServiceLocator = (INestable) item.getData();
+				activeServiceLocator.activate();
+			}
+		}
+	}
+
+	/**
+	 * Disposes the given part and its site.
+	 * 
+	 * @param part
+	 *            The part to dispose; must not be <code>null</code>.
+	 */
+	private void disposePart(final IWorkbenchPart part) {
+		SafeRunner.run(new ISafeRunnable() {
+			public void run() {
+				IWorkbenchPartSite partSite = part.getSite();
+				part.dispose();
+				if (partSite instanceof MultiPageEditorSite) {
+					((MultiPageEditorSite) partSite).dispose();
+				}
+			}
+
+			public void handleException(Throwable e) {
+				// Exception has already being logged by Core. Do nothing.
+			}
+		});
+	}
+
+	/**
+	 * Removes the page with the given index from this multi-page editor. The
+	 * controls for the page are disposed of; if the page has an editor, it is
+	 * disposed of too. The page index must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @see MultiPageEditorPart#addPage(Control)
+	 * @see MultiPageEditorPart#addPage(IEditorPart, IEditorInput)
+	 */
+	public void removePage(int pageIndex) {
+		Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount());
+		// get editor (if any) before disposing item
+		IEditorPart editor = getEditor(pageIndex);
+
+		// get control for the item if it's not an editor
+		CTabItem item = getItem(pageIndex);
+		IServiceLocator pageLocator = null;
+		if (item.getData() instanceof IServiceLocator) {
+			pageLocator = (IServiceLocator) item.getData();
+		}
+		Control pageControl = item.getControl();
+
+		// dispose item before disposing editor, in case there's an exception
+		// in editor's dispose
+		item.dispose();
+
+		if (pageControl != null) {
+			pageControl.dispose();
+		}
+
+		// dispose editor (if any)
+		if (editor != null) {
+			nestedEditors.remove(editor);
+			disposePart(editor);
+		}
+		if (pageLocator != null) {
+			pageSites.remove(pageLocator);
+			if (pageLocator instanceof IDisposable) {
+				((IDisposable) pageLocator).dispose();
+			}
+		}
+	}
+
+	/**
+	 * Sets the currently active page.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page to be activated; the index must be valid
+	 */
+	protected void setActivePage(int pageIndex) {
+		Assert.isTrue(pageIndex >= 0 && pageIndex < getPageCount());
+		getTabFolder().setSelection(pageIndex);
+		pageChange(pageIndex);
+	}
+
+	/**
+	 * Sets the control for the given page index. The page index must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @param control
+	 *            the control for the specified page, or <code>null</code> to
+	 *            clear the control
+	 */
+	protected void setControl(int pageIndex, Control control) {
+		getItem(pageIndex).setControl(control);
+	}
+
+	/**
+	 * The <code>MultiPageEditor</code> implementation of this
+	 * <code>IWorkbenchPart</code> method sets focus on the active nested
+	 * editor, if there is one.
+	 * <p>
+	 * Subclasses may extend or reimplement.
+	 * </p>
+	 */
+	public void setFocus() {
+		setFocus(getActivePage());
+	}
+
+	/**
+	 * Sets focus to the control for the given page. If the page has an editor,
+	 * this calls its <code>setFocus()</code> method. Otherwise, this calls
+	 * <code>setFocus</code> on the control for the page.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 */
+	private void setFocus(int pageIndex) {
+		if (pageIndex < 0 || pageIndex >= getPageCount()) {
+			// page index out of bounds, don't set focus.
+			return;
+		}
+		final IEditorPart editor = getEditor(pageIndex);
+		if (editor != null) {
+			editor.setFocus();
+
+		} else {
+			// Give the page's control focus.
+			final Control control = getControl(pageIndex);
+			if (control != null) {
+				control.setFocus();
+			}
+		}
+	}
+
+	/**
+	 * Sets the image for the page with the given index, or <code>null</code> to
+	 * clear the image for the page. The page index must be valid.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @param image
+	 *            the image, or <code>null</code>
+	 */
+	protected void setPageImage(int pageIndex, Image image) {
+		getItem(pageIndex).setImage(image);
+	}
+
+	/**
+	 * Sets the text label for the page with the given index. The page index
+	 * must be valid. The text label must not be null.
+	 * 
+	 * @param pageIndex
+	 *            the index of the page
+	 * @param text
+	 *            the text label
+	 */
+	protected void setPageText(int pageIndex, String text) {
+		getItem(pageIndex).setText(text);
+	}
+
+	/**
+	 * If there is an adapter registered against the subclass of
+	 * MultiPageEditorPart return that. Otherwise, delegate to the internal
+	 * editor.
+	 * 
+	 * @see org.eclipse.ui.part.WorkbenchPart#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		Object result = super.getAdapter(adapter);
+		// restrict delegating to the UI thread for bug 144851
+		if (result == null && Display.getCurrent() != null) {
+			IEditorPart innerEditor = getActiveEditor();
+			// see bug 138823 - prevent some subclasses from causing
+			// an infinite loop
+			if (innerEditor != null && innerEditor != this) {
+				result = Util.getAdapter(innerEditor, adapter);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Find the editors contained in this multi-page editor whose editor input
+	 * match the provided input.
+	 * 
+	 * @param input
+	 *            the editor input
+	 * @return the editors contained in this multi-page editor whose editor
+	 *         input match the provided input
+	 * @since 3.3
+	 */
+	public final IEditorPart[] findEditors(IEditorInput input) {
+		List result = new ArrayList();
+		int count = getPageCount();
+		for (int i = 0; i < count; i++) {
+			IEditorPart editor = getEditor(i);
+			if (editor != null && editor.getEditorInput() != null
+					&& editor.getEditorInput().equals(input)) {
+				result.add(editor);
+			}
+		}
+		return (IEditorPart[]) result.toArray(new IEditorPart[result.size()]);
+	}
+
+	/**
+	 * Set the active page of this multi-page editor to the page that contains
+	 * the given editor part. This method has no effect of the given editor part
+	 * is not contained in this multi-page editor.
+	 * 
+	 * @param editorPart
+	 *            the editor part
+	 * @since 3.3
+	 */
+	public final void setActiveEditor(IEditorPart editorPart) {
+		int count = getPageCount();
+		for (int i = 0; i < count; i++) {
+			IEditorPart editor = getEditor(i);
+			if (editor == editorPart) {
+				setActivePage(i);
+				break;
+			}
+		}
+	}
+
+	/**
+	 * Returns the selected page for the current active page index, either the
+	 * IEditorPart for editors or the Control for other pages.
+	 * <p>
+	 * <b>Note:</b> clients may override this method to return a page
+	 * appropriate for their editors. Maybe be <code>null</code>.
+	 * </p>
+	 * 
+	 * @return The IEditorPart or Control representing the current active page,
+	 *         or <code>null</code> if there are no active pages.
+	 * @since 3.5
+	 * @see #getActivePage()
+	 */
+	public Object getSelectedPage() {
+		int index = getActivePage();
+		if (index == -1) {
+			return null;
+		}
+		IEditorPart editor = getEditor(index);
+		if (editor != null) {
+			return editor;
+		}
+		return getControl(index);
+	}
+
+	/**
+	 * Add the page change listener to be notified when the page changes. The
+	 * newly selected page will be the Object returned from
+	 * {@link #getSelectedPage()}. In the default case, this will be the active
+	 * page Control, IEditorPart, or <code>null</code>.
+	 * <p>
+	 * This method has no effect if the listener has already been added.
+	 * </p>
+	 * 
+	 * @nooverride
+	 * 
+	 * @since 3.5
+	 */
+	public void addPageChangedListener(IPageChangedListener listener) {
+		pageChangeListeners.add(listener);
+	}
+
+	/**
+	 * Remove the page change listener.
+	 * <p>
+	 * This method has no effect if the listener is not in the list.
+	 * </p>
+	 * 
+	 * @nooverride
+	 * 
+	 * @since 3.5
+	 */
+	public void removePageChangedListener(IPageChangedListener listener) {
+		pageChangeListeners.remove(listener);
+	}
+
+	private void firePageChanged(final PageChangedEvent event) {
+		Object[] listeners = pageChangeListeners.getListeners();
+		for (int i = 0; i < listeners.length; ++i) {
+			final IPageChangedListener l = (IPageChangedListener) listeners[i];
+			SafeRunnable.run(new SafeRunnable() {
+				public void run() {
+					l.pageChanged(event);
+				}
+			});
+		}
+	}
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorSite.java b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorSite.java
new file mode 100644
index 0000000..7f1776e
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench.fragment/src/org/eclipse/ui/part/MultiPageEditorSite.java
@@ -0,0 +1,555 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ui.part;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.e4.core.services.context.EclipseContextFactory;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.workbench.ui.internal.UISchedulerStrategy;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.viewers.ILabelDecorator;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorActionBarContributor;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IKeyBindingService;
+import org.eclipse.ui.INestableKeyBindingService;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.internal.EditorSite;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.PopupMenuExtender;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.part.IMultiPageEditorSiteHolder;
+import org.eclipse.ui.internal.services.INestable;
+import org.eclipse.ui.internal.services.IServiceLocatorCreator;
+import org.eclipse.ui.internal.services.IWorkbenchLocationService;
+import org.eclipse.ui.internal.services.ServiceLocator;
+import org.eclipse.ui.internal.services.WorkbenchLocationService;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.services.IServiceLocator;
+import org.eclipse.ui.services.IServiceScopes;
+
+/**
+ * Site for a nested editor within a multi-page editor. Selection is handled by
+ * forwarding the event to the multi-page editor's selection listeners; most
+ * other methods are forwarded to the multi-page editor's site.
+ * <p>
+ * The base implementation of <code>MultiPageEditor.createSite</code> creates an
+ * instance of this class. This class may be instantiated or subclassed.
+ * </p>
+ */
+public class MultiPageEditorSite implements IEditorSite, INestable {
+
+	/**
+	 * The nested editor.
+	 */
+	private IEditorPart editor;
+
+	/**
+	 * The list of popup menu extenders; <code>null</code> if none registered.
+	 */
+	private ArrayList menuExtenders;
+
+	/**
+	 * The multi-page editor.
+	 */
+	private MultiPageEditorPart multiPageEditor;
+
+	/**
+	 * The post selection changed listener.
+	 */
+	private ISelectionChangedListener postSelectionChangedListener = null;
+
+	/**
+	 * The selection change listener, initialized lazily; <code>null</code> if
+	 * not yet created.
+	 */
+	private ISelectionChangedListener selectionChangedListener = null;
+
+	/**
+	 * The selection provider; <code>null</code> if none.
+	 * 
+	 * @see MultiPageEditorSite#setSelectionProvider(ISelectionProvider)
+	 */
+	private ISelectionProvider selectionProvider = null;
+
+	/**
+	 * The cached copy of the key binding service specific to this multi-page
+	 * editor site. This value is <code>null</code> if it is not yet
+	 * initialized.
+	 */
+	private IKeyBindingService service = null;
+
+	/**
+	 * The local service locator for this multi-page editor site. This value is
+	 * never <code>null</code>.
+	 */
+	private final ServiceLocator serviceLocator;
+
+	/**
+	 * Creates a site for the given editor nested within the given multi-page
+	 * editor.
+	 * 
+	 * @param multiPageEditor
+	 *            the multi-page editor
+	 * @param editor
+	 *            the nested editor
+	 */
+	public MultiPageEditorSite(MultiPageEditorPart multiPageEditor,
+			IEditorPart editor) {
+		Assert.isNotNull(multiPageEditor);
+		Assert.isNotNull(editor);
+		this.multiPageEditor = multiPageEditor;
+		this.editor = editor;
+
+		final IServiceLocator parentServiceLocator = multiPageEditor.getSite();
+		IServiceLocatorCreator slc = (IServiceLocatorCreator) parentServiceLocator
+				.getService(IServiceLocatorCreator.class);
+		this.serviceLocator = (ServiceLocator) slc.createServiceLocator(
+				multiPageEditor.getSite(), null, new IDisposable() {
+					public void dispose() {
+						final Control control = ((PartSite) getMultiPageEditor()
+								.getSite()).getPane().getControl();
+						if (control != null && !control.isDisposed()) {
+							((PartSite) getMultiPageEditor().getSite())
+									.getPane().doHide();
+						}
+					}
+				});
+		IEclipseContext e4Context = EclipseContextFactory.create(
+				((EditorSite) multiPageEditor.getSite()).getContext(),
+				UISchedulerStrategy.getInstance());
+		this.serviceLocator.setContext(e4Context);
+
+		initializeDefaultServices();
+	}
+
+	/**
+	 * Initialize the slave services for this site.
+	 */
+	private void initializeDefaultServices() {
+		serviceLocator.registerService(IWorkbenchLocationService.class,
+				new WorkbenchLocationService(IServiceScopes.MPESITE_SCOPE,
+						getWorkbenchWindow().getWorkbench(),
+						getWorkbenchWindow(), getMultiPageEditor().getSite(),
+						this, null, 3));
+		serviceLocator.registerService(IMultiPageEditorSiteHolder.class,
+				new IMultiPageEditorSiteHolder() {
+					public MultiPageEditorSite getSite() {
+						return MultiPageEditorSite.this;
+					}
+				});
+	}
+
+	/**
+	 * Notifies the multi page editor service that the component within which it
+	 * exists has become active.
+	 * 
+	 * @since 3.2
+	 */
+	public final void activate() {
+		serviceLocator.activate();
+	}
+
+	/**
+	 * Notifies the multi page editor service that the component within which it
+	 * exists has been deactived.
+	 * 
+	 * @since 3.2
+	 */
+	public final void deactivate() {
+		serviceLocator.deactivate();
+	}
+
+	/**
+	 * Dispose the contributions.
+	 */
+	public void dispose() {
+		if (menuExtenders != null) {
+			for (int i = 0; i < menuExtenders.size(); i++) {
+				((PopupMenuExtender) menuExtenders.get(i)).dispose();
+			}
+			menuExtenders = null;
+		}
+
+		// Remove myself from the list of nested key binding services.
+		if (service != null) {
+			IKeyBindingService parentService = getEditor().getSite()
+					.getKeyBindingService();
+			if (parentService instanceof INestableKeyBindingService) {
+				INestableKeyBindingService nestableParent = (INestableKeyBindingService) parentService;
+				nestableParent.removeKeyBindingService(this);
+			}
+			service = null;
+		}
+
+		if (serviceLocator != null) {
+			serviceLocator.dispose();
+		}
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IEditorSite</code> method returns <code>null</code>, since nested
+	 * editors do not have their own action bar contributor.
+	 * 
+	 * @return <code>null</code>
+	 */
+	public IEditorActionBarContributor getActionBarContributor() {
+		return null;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IEditorSite</code> method forwards to the multi-page editor to
+	 * return the action bars.
+	 * 
+	 * @return The action bars from the parent multi-page editor.
+	 */
+	public IActionBars getActionBars() {
+		return multiPageEditor.getEditorSite().getActionBars();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
+	 */
+	public Object getAdapter(Class adapter) {
+		return null;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * to return the decorator manager.
+	 * 
+	 * @return The decorator from the workbench window.
+	 * @deprecated use IWorkbench.getDecoratorManager()
+	 */
+	public ILabelDecorator getDecoratorManager() {
+		return getWorkbenchWindow().getWorkbench().getDecoratorManager()
+				.getLabelDecorator();
+	}
+
+	/**
+	 * Returns the nested editor.
+	 * 
+	 * @return the nested editor
+	 */
+	public IEditorPart getEditor() {
+		return editor;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method returns an empty string since the
+	 * nested editor is not created from the registry.
+	 * 
+	 * @return An empty string.
+	 */
+	public String getId() {
+		return ""; //$NON-NLS-1$
+	}
+
+	/*
+	 * (non-Javadoc) Method declared on IEditorSite.
+	 */
+	public IKeyBindingService getKeyBindingService() {
+		if (service == null) {
+			service = getMultiPageEditor().getEditorSite()
+					.getKeyBindingService();
+			if (service instanceof INestableKeyBindingService) {
+				INestableKeyBindingService nestableService = (INestableKeyBindingService) service;
+				service = nestableService.getKeyBindingService(this);
+
+			} else {
+				/*
+				 * This is an internal reference, and should not be copied by
+				 * client code. If you are thinking of copying this, DON'T DO
+				 * IT.
+				 */
+				WorkbenchPlugin
+						.log("MultiPageEditorSite.getKeyBindingService()   Parent key binding service was not an instance of INestableKeyBindingService.  It was an instance of " + service.getClass().getName() + " instead."); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
+		return service;
+	}
+
+	/**
+	 * Returns the multi-page editor.
+	 * 
+	 * @return the multi-page editor
+	 */
+	public MultiPageEditorPart getMultiPageEditor() {
+		return multiPageEditor;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * to return the workbench page.
+	 * 
+	 * @return The workbench page in which this editor site resides.
+	 */
+	public IWorkbenchPage getPage() {
+		return getMultiPageEditor().getSite().getPage();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.ui.IWorkbenchPartSite#getPart()
+	 */
+	public IWorkbenchPart getPart() {
+		return editor;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method returns an empty string since the
+	 * nested editor is not created from the registry.
+	 * 
+	 * @return An empty string.
+	 */
+	public String getPluginId() {
+		return ""; //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the post selection change listener which listens to the nested
+	 * editor's selection changes.
+	 * 
+	 * @return the post selection change listener.
+	 */
+	private ISelectionChangedListener getPostSelectionChangedListener() {
+		if (postSelectionChangedListener == null) {
+			postSelectionChangedListener = new ISelectionChangedListener() {
+				public void selectionChanged(SelectionChangedEvent event) {
+					MultiPageEditorSite.this.handlePostSelectionChanged(event);
+				}
+			};
+		}
+		return postSelectionChangedListener;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method returns an empty string since the
+	 * nested editor is not created from the registry.
+	 * 
+	 * @return An empty string.
+	 */
+	public String getRegisteredName() {
+		return ""; //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the selection changed listener which listens to the nested
+	 * editor's selection changes, and calls <code>handleSelectionChanged</code>
+	 * .
+	 * 
+	 * @return the selection changed listener
+	 */
+	private ISelectionChangedListener getSelectionChangedListener() {
+		if (selectionChangedListener == null) {
+			selectionChangedListener = new ISelectionChangedListener() {
+				public void selectionChanged(SelectionChangedEvent event) {
+					MultiPageEditorSite.this.handleSelectionChanged(event);
+				}
+			};
+		}
+		return selectionChangedListener;
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method returns the selection provider set
+	 * by <code>setSelectionProvider</code>.
+	 * 
+	 * @return The current selection provider.
+	 */
+	public ISelectionProvider getSelectionProvider() {
+		return selectionProvider;
+	}
+
+	public final Object getService(final Class key) {
+		return serviceLocator.getService(key);
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * to return the shell.
+	 * 
+	 * @return The shell in which this editor site resides.
+	 */
+	public Shell getShell() {
+		return getMultiPageEditor().getSite().getShell();
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * to return the workbench window.
+	 * 
+	 * @return The workbench window in which this editor site resides.
+	 */
+	public IWorkbenchWindow getWorkbenchWindow() {
+		return getMultiPageEditor().getSite().getWorkbenchWindow();
+	}
+
+	/**
+	 * Handles a post selection changed even from the nexted editor.
+	 * <p>
+	 * Subclasses may extend or reimplement this method
+	 * 
+	 * @param event
+	 *            the event
+	 * 
+	 * @since 3.2
+	 */
+	protected void handlePostSelectionChanged(SelectionChangedEvent event) {
+		ISelectionProvider parentProvider = getMultiPageEditor().getSite()
+				.getSelectionProvider();
+		if (parentProvider instanceof MultiPageSelectionProvider) {
+			SelectionChangedEvent newEvent = new SelectionChangedEvent(
+					parentProvider, event.getSelection());
+			MultiPageSelectionProvider prov = (MultiPageSelectionProvider) parentProvider;
+			prov.firePostSelectionChanged(newEvent);
+		}
+	}
+
+	/**
+	 * Handles a selection changed event from the nested editor. The default
+	 * implementation gets the selection provider from the multi-page editor's
+	 * site, and calls <code>fireSelectionChanged</code> on it (only if it is an
+	 * instance of <code>MultiPageSelectionProvider</code>), passing a new event
+	 * object.
+	 * <p>
+	 * Subclasses may extend or reimplement this method.
+	 * </p>
+	 * 
+	 * @param event
+	 *            the event
+	 */
+	protected void handleSelectionChanged(SelectionChangedEvent event) {
+		ISelectionProvider parentProvider = getMultiPageEditor().getSite()
+				.getSelectionProvider();
+		if (parentProvider instanceof MultiPageSelectionProvider) {
+			SelectionChangedEvent newEvent = new SelectionChangedEvent(
+					parentProvider, event.getSelection());
+			MultiPageSelectionProvider prov = (MultiPageSelectionProvider) parentProvider;
+			prov.fireSelectionChanged(newEvent);
+		}
+	}
+
+	public final boolean hasService(final Class key) {
+		return serviceLocator.hasService(key);
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * for registration.
+	 * 
+	 * @param menuManager
+	 *            The menu manager
+	 * @param selProvider
+	 *            The selection provider.
+	 */
+	public void registerContextMenu(MenuManager menuManager,
+			ISelectionProvider selProvider) {
+		getMultiPageEditor().getSite().registerContextMenu(menuManager,
+				selProvider);
+	}
+
+	public final void registerContextMenu(final MenuManager menuManager,
+			final ISelectionProvider selectionProvider,
+			final boolean includeEditorInput) {
+		registerContextMenu(getId(), menuManager, selectionProvider,
+				includeEditorInput);
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method forwards to the multi-page editor
+	 * for registration.
+	 * 
+	 * @param menuID
+	 *            The identifier for the menu.
+	 * @param menuMgr
+	 *            The menu manager
+	 * @param selProvider
+	 *            The selection provider.
+	 */
+	public void registerContextMenu(String menuID, MenuManager menuMgr,
+			ISelectionProvider selProvider) {
+		if (menuExtenders == null) {
+			menuExtenders = new ArrayList(1);
+		}
+		PartSite.registerContextMenu(menuID, menuMgr, selProvider, true,
+				editor, menuExtenders);
+	}
+
+	public final void registerContextMenu(final String menuId,
+			final MenuManager menuManager,
+			final ISelectionProvider selectionProvider,
+			final boolean includeEditorInput) {
+		if (menuExtenders == null) {
+			menuExtenders = new ArrayList(1);
+		}
+		PartSite.registerContextMenu(menuId, menuManager, selectionProvider,
+				includeEditorInput, editor, menuExtenders);
+	}
+
+	/**
+	 * The <code>MultiPageEditorSite</code> implementation of this
+	 * <code>IWorkbenchPartSite</code> method remembers the selection provider,
+	 * and also hooks a listener on it, which calls
+	 * <code>handleSelectionChanged</code> when a selection changed event
+	 * occurs.
+	 * 
+	 * @param provider
+	 *            The selection provider.
+	 * @see MultiPageEditorSite#handleSelectionChanged(SelectionChangedEvent)
+	 */
+	public void setSelectionProvider(ISelectionProvider provider) {
+		ISelectionProvider oldSelectionProvider = selectionProvider;
+		selectionProvider = provider;
+		if (oldSelectionProvider != null) {
+			oldSelectionProvider
+					.removeSelectionChangedListener(getSelectionChangedListener());
+			if (oldSelectionProvider instanceof IPostSelectionProvider) {
+				((IPostSelectionProvider) oldSelectionProvider)
+						.removePostSelectionChangedListener(getPostSelectionChangedListener());
+			}
+		}
+		if (selectionProvider != null) {
+			selectionProvider
+					.addSelectionChangedListener(getSelectionChangedListener());
+			if (selectionProvider instanceof IPostSelectionProvider) {
+				((IPostSelectionProvider) selectionProvider)
+						.addPostSelectionChangedListener(getPostSelectionChangedListener());
+			}
+		}
+	}
+}
