/*******************************************************************************
 * 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.internal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.e4.compatibility.LegacyEditor;
import org.eclipse.e4.compatibility.LegacyView;
import org.eclipse.e4.core.services.IDisposable;
import org.eclipse.e4.core.services.context.IEclipseContext;
import org.eclipse.e4.extensions.ModelEditorReference;
import org.eclipse.e4.extensions.ModelReference;
import org.eclipse.e4.ui.model.application.MApplicationFactory;
import org.eclipse.e4.ui.model.application.MContribution;
import org.eclipse.e4.ui.model.application.MESCElement;
import org.eclipse.e4.ui.model.application.MEditor;
import org.eclipse.e4.ui.model.application.MEditorSashContainer;
import org.eclipse.e4.ui.model.application.MElementContainer;
import org.eclipse.e4.ui.model.application.MPart;
import org.eclipse.e4.ui.model.application.MPerspective;
import org.eclipse.e4.ui.model.application.MPerspectiveStack;
import org.eclipse.e4.ui.model.application.MUIElement;
import org.eclipse.e4.ui.model.application.MWindow;
import org.eclipse.e4.ui.workbench.swt.internal.AbstractPartRenderer;
import org.eclipse.e4.workbench.ui.api.ModeledPageLayout;
import org.eclipse.e4.workbench.ui.internal.IValueFunction;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.INavigationHistory;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.ISaveablePart;
import org.eclipse.ui.ISaveablesLifecycleListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.MultiPartInitException;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
import org.eclipse.ui.internal.misc.UIListenerLogging;
import org.eclipse.ui.internal.misc.UIStats;
import org.eclipse.ui.internal.registry.ActionSetRegistry;
import org.eclipse.ui.internal.registry.EditorDescriptor;
import org.eclipse.ui.internal.registry.IActionSetDescriptor;
import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
import org.eclipse.ui.internal.registry.UIExtensionTracker;
import org.eclipse.ui.internal.tweaklets.GrabFocus;
import org.eclipse.ui.internal.tweaklets.TabBehaviour;
import org.eclipse.ui.internal.tweaklets.Tweaklets;
import org.eclipse.ui.internal.tweaklets.WorkbenchImplementation;
import org.eclipse.ui.internal.util.PrefUtil;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.part.AbstractMultiEditor;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.presentations.IStackPresentationSite;

/**
 * A collection of views and editors in a workbench.
 */
public class WorkbenchPage extends CompatibleWorkbenchPage implements
		IWorkbenchPage {

	private static final String ATT_AGGREGATE_WORKING_SET_ID = "aggregateWorkingSetId"; //$NON-NLS-1$

	private static final IEditorReference[] noEditorRefs = new IEditorReference[0];

	protected WorkbenchWindow window;

	private IAdaptable input;

	private IWorkingSet workingSet;

	private AggregateWorkingSet aggregateWorkingSet;

	private Composite composite;

	private EditorManager editorMgr;

	private ArrayList removedEditors = new ArrayList();

	private ListenerList propertyChangeListeners = new ListenerList();

	private WorkbenchPagePartList partList = null;

	private IActionBars actionBars;

	private ActionSetManager actionSets;

	private ViewFactory viewFactory;

	private PerspectiveList perspList = new PerspectiveList();

	private PerspectiveDescriptor deferredActivePersp;

	private NavigationHistory navigationHistory = null;

	private IStickyViewManager stickyViewMan = StickyViewManager
			.getInstance(this);

	/**
	 * If we're in the process of activating a part, this points to the new
	 * part. Otherwise, this is null.
	 */
	private IWorkbenchPartReference partBeingActivated = null;

	/**
	 * If a part is being opened, don't allow a forceFocus() to request its
	 * activation as well.
	 * 
	 * @since 3.4
	 */
	private boolean partBeingOpened = false;

	/**
	 * Contains a list of perspectives that may be dirty due to plugin
	 * installation and removal.
	 */
	private Set dirtyPerspectives = new HashSet();

	private IPropertyChangeListener workingSetPropertyChangeListener = new IPropertyChangeListener() {
		/*
		 * Remove the working set from the page if the working set is deleted.
		 */
		public void propertyChange(PropertyChangeEvent event) {
			String property = event.getProperty();
			if (IWorkingSetManager.CHANGE_WORKING_SET_REMOVE.equals(property)) {
				if (event.getOldValue().equals(workingSet)) {
					setWorkingSet(null);
				}

				// room for optimization here
				List newList = new ArrayList(Arrays.asList(workingSets));
				if (newList.remove(event.getOldValue())) {
					setWorkingSets((IWorkingSet[]) newList
							.toArray(new IWorkingSet[newList.size()]));
				}
			}
		}
	};

	private IExtensionTracker tracker;

	private IWorkingSet[] workingSets = new IWorkingSet[0];
	private String aggregateWorkingSetId;

	private MWindow e4Window;

	private IEclipseContext e4Context;

	private ISelectionService selectionService;

	/**
	 * Constructs a new page with a given perspective and input.
	 * 
	 * @param w
	 *            the parent window
	 * @param layoutID
	 *            must not be <code>null</code>
	 * @param input
	 *            the page input
	 * @throws WorkbenchException
	 *             on null layout id
	 */
	public WorkbenchPage(WorkbenchWindow w, String layoutID, IAdaptable input)
			throws WorkbenchException {
		super();
		if (layoutID == null) {
			throw new WorkbenchException(
					WorkbenchMessages.WorkbenchPage_UndefinedPerspective);
		}
		init(w, layoutID, input, true);
	}

	/**
	 * Constructs a page. <code>restoreState(IMemento)</code> should be called
	 * to restore this page from data stored in a persistance file.
	 * 
	 * @param w
	 *            the parent window
	 * @param input
	 *            the page input
	 * @throws WorkbenchException
	 */
	public WorkbenchPage(WorkbenchWindow w, IAdaptable input)
			throws WorkbenchException {
		super();
		init(w, null, input, false);
	}

	/**
	 * Activates a part. The part will be brought to the front and given focus.
	 * 
	 * @param part
	 *            the part to activate
	 */
	public void activate(IWorkbenchPart part) {
		// Sanity check.
		if (part == null || !certifyPart(part) || window.isClosing()) {
			return;
		}

		// Activate the part and set its focus
		IWorkbenchPartReference ref = getReference(part);
		if (ref instanceof ModelReference) {
			ModelReference modelRef = (ModelReference) ref;
			MPart modelElement = modelRef.getModel();
			if (modelElement != null) {
				AbstractPartRenderer renderer = (AbstractPartRenderer) modelElement
						.getFactory();
				if (renderer != null)
					renderer.activate(modelElement);

			}
		}

	}

	/**
	 * Add a fast view.
	 */
	public void addFastView(IViewReference ref) {
	}

	/**
	 * Add a fast view.
	 */
	public void makeFastView(IViewReference ref) {
	}

	/**
	 * Adds an IPartListener to the part service.
	 */
	public void addPartListener(IPartListener l) {
		partList.getPartService().addPartListener(l);
	}

	/**
	 * Adds an IPartListener to the part service.
	 */
	public void addPartListener(IPartListener2 l) {
		partList.getPartService().addPartListener(l);
	}

	/**
	 * Implements IWorkbenchPage
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#addPropertyChangeListener(IPropertyChangeListener)
	 * @since 2.0
	 * @deprecated individual views should store a working set if needed and
	 *             register a property change listener directly with the working
	 *             set manager to receive notification when the view working set
	 *             is removed.
	 */
	public void addPropertyChangeListener(IPropertyChangeListener listener) {
		propertyChangeListeners.add(listener);
	}

	/*
	 * (non-Javadoc) Method declared on ISelectionListener.
	 */
	public void addSelectionListener(ISelectionListener listener) {
		selectionService.addSelectionListener(listener);
	}

	/*
	 * (non-Javadoc) Method declared on ISelectionListener.
	 */
	public void addSelectionListener(String partId, ISelectionListener listener) {
		selectionService.addSelectionListener(partId, listener);
	}

	/*
	 * (non-Javadoc) Method declared on ISelectionListener.
	 */
	public void addPostSelectionListener(ISelectionListener listener) {
		selectionService.addPostSelectionListener(listener);
	}

	/*
	 * (non-Javadoc) Method declared on ISelectionListener.
	 */
	public void addPostSelectionListener(String partId,
			ISelectionListener listener) {
		selectionService.addPostSelectionListener(partId, listener);
	}

	/**
	 * Moves a part forward in the Z order of a perspective so it is visible. If
	 * the part is in the same stack as the active part, the new part is
	 * activated.
	 * 
	 * @param part
	 *            the part to bring to move forward
	 */
	public void bringToTop(IWorkbenchPart part) {
		// Sanity check.
		Perspective persp = getActivePerspective();
		if (persp == null || !certifyPart(part)) {
			return;
		}

		if (!((GrabFocus) Tweaklets.get(GrabFocus.KEY)).grabFocusAllowed(part)) {
			return;
		}

		// TBD we have no shared parts so far. Processing below should be
		// updated once shared parts are implemented
		if (part instanceof EditorPart) {
			MEditorSashContainer ea = (MEditorSashContainer) findPartInCurrentPerspective(ModeledPageLayout
					.internalGetEditorArea());
			String editorID = ((EditorPart) part).getEditorSite().getId();
			IEditorInput editorInput = ((EditorPart) part).getEditorInput();
			MEditor editorPart = findEditor(ea, editorID, editorInput);
			if (editorPart != null) {
				editorPart.setVisible(true);
				ea.setActiveChild((MESCElement) editorPart);
			} else {
				try {
					openEditor(editorInput, editorID, true, MATCH_NONE);
				} catch (PartInitException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		} else {
			// TBD implement functionality for views
		}
	}

	/**
	 * Shows a view.
	 * 
	 * Assumes that a busy cursor is active.
	 */
	protected IViewPart busyShowView(String viewID, String secondaryID, int mode)
			throws PartInitException {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return null;
		}

		// If this view is already visible just return.
		IViewReference ref = persp.findView(viewID, secondaryID);
		IViewPart view = null;
		if (ref != null) {
			view = ref.getView(true);
		}
		if (view != null) {
			busyShowView(view, mode);
			return view;
		}

		// Show the view.
		view = persp.showView(viewID, secondaryID);
		if (view != null) {

			window.firePerspectiveChanged(this, getPerspective(), null,
					CHANGE_VIEW_SHOW);
			window.firePerspectiveChanged(this, getPerspective(),
					CHANGE_VIEW_SHOW);
		}
		return view;
	}

	/*
	 * Performs showing of the view in the given mode.
	 */
	private void busyShowView(IViewPart part, int mode) {
		if (!((GrabFocus) Tweaklets.get(GrabFocus.KEY)).grabFocusAllowed(part)) {
			return;
		}
	}

	/**
	 * Returns whether a part exists in the current page.
	 */
	private boolean certifyPart(IWorkbenchPart part) {
		// Workaround for bug 22325
		if (part != null && !(part.getSite() instanceof PartSite)) {
			return false;
		}
		return true;
	}

	/**
	 * Closes the perspective.
	 */
	public boolean close() {
		final boolean[] ret = new boolean[1];
		BusyIndicator.showWhile(null, new Runnable() {
			public void run() {
				ret[0] = window.closePage(WorkbenchPage.this, true);
			}
		});
		return ret[0];
	}

	/**
	 * See IWorkbenchPage
	 */
	public boolean closeAllSavedEditors() {
		// get the Saved editors
		IEditorReference editors[] = getEditorReferences();
		IEditorReference savedEditors[] = new IEditorReference[editors.length];
		int j = 0;
		for (int i = 0; i < editors.length; i++) {
			IEditorReference editor = editors[i];
			if (!editor.isDirty()) {
				savedEditors[j++] = editor;
			}
		}
		// there are no unsaved editors
		if (j == 0) {
			return true;
		}
		IEditorReference[] newSaved = new IEditorReference[j];
		System.arraycopy(savedEditors, 0, newSaved, 0, j);
		return closeEditors(newSaved, false);
	}

	/**
	 * See IWorkbenchPage
	 */
	public boolean closeAllEditors(boolean save) {
		return closeEditors(getEditorReferences(), save);
	}

	/**
	 * See IWorkbenchPage
	 */
	public boolean closeEditors(IEditorReference[] refArray, boolean save) {
		if (refArray.length == 0) {
			return true;
		}

		// Check if we're being asked to close any parts that are already closed
		// or cannot
		// be closed at this time
		ArrayList toClose = new ArrayList();
		for (int i = 0; i < refArray.length; i++) {
			IEditorReference reference = refArray[i];

			// If we're in the middle of creating this part, this is a
			// programming error. Abort the entire
			// close operation. This usually occurs if someone tries to open a
			// dialog in a method that
			// isn't allowed to do so, and a *syncExec tries to close the part.
			// If this shows up in a log
			// file with a dialog's event loop on the stack, then the code that
			// opened the dialog is usually
			// at fault.
			if (reference == partBeingActivated) {
				WorkbenchPlugin
						.log(new RuntimeException(
								"WARNING: Blocked recursive attempt to close part " //$NON-NLS-1$
										+ partBeingActivated.getId()
										+ " while still in the middle of activating it")); //$NON-NLS-1$
				return false;
			}

			if (reference instanceof WorkbenchPartReference) {
				WorkbenchPartReference ref = (WorkbenchPartReference) reference;

				// If we're being asked to close a part that is disposed (ie:
				// already closed),
				// skip it and proceed with closing the remaining parts.
				if (ref.isDisposed()) {
					continue;
				}
			}

			toClose.add(reference);
		}

		IEditorReference[] editorRefs = (IEditorReference[]) toClose
				.toArray(new IEditorReference[toClose.size()]);

		// if active navigation position belongs to an editor being closed,
		// update it
		// (The navigation position for an editor N was updated as an editor N +
		// 1
		// was activated. As a result, all but the last editor have up-to-date
		// navigation positions.)
		for (int i = 0; i < editorRefs.length; i++) {
			IEditorReference ref = editorRefs[i];
			if (ref == null)
				continue;
			IEditorPart oldPart = ref.getEditor(false);
			if (oldPart == null)
				continue;
			if (navigationHistory.updateActive(oldPart))
				break; // updated - skip the rest
		}

		// notify the model manager before the close
		List partsToClose = new ArrayList();
		for (int i = 0; i < editorRefs.length; i++) {
			IEditorPart refPart = editorRefs[i].getEditor(false);
			if (refPart != null) {
				partsToClose.add(refPart);
			}
		}
		SaveablesList modelManager = null;
		Object postCloseInfo = null;
		if (partsToClose.size() > 0) {
			modelManager = (SaveablesList) getWorkbenchWindow().getService(
					ISaveablesLifecycleListener.class);
			// this may prompt for saving and return null if the user canceled:
			postCloseInfo = modelManager.preCloseParts(partsToClose, save,
					getWorkbenchWindow());
			if (postCloseInfo == null) {
				return false;
			}
		}

		// Fire pre-removal changes
		for (int i = 0; i < editorRefs.length; i++) {
			IEditorReference ref = editorRefs[i];

			// Notify interested listeners before the close
			window.firePerspectiveChanged(this, getPerspective(), ref,
					CHANGE_EDITOR_CLOSE);

		}

		if (modelManager != null) {
			modelManager.postClose(postCloseInfo);
		}

		// Close all editors.
		for (int i = 0; i < editorRefs.length; i++) {
			IEditorReference ref = editorRefs[i];

			// Remove editor from the presentation

			partRemoved(ref);
			// now that it has disappeared from the model, dispose its context
			MPart mEditorPart = ((ModelEditorReference) ref).getModel();
			((IDisposable) mEditorPart.getContext()).dispose();
			mEditorPart.setContext(null);
		}

		// Notify interested listeners after the close
		window.firePerspectiveChanged(this, getPerspective(),
				CHANGE_EDITOR_CLOSE);

		// Return true on success.
		return true;
	}

	/**
	 * See IWorkbenchPage#closeEditor
	 */
	public boolean closeEditor(IEditorReference editorRef, boolean save) {
		return closeEditors(new IEditorReference[] { editorRef }, save);
	}

	/**
	 * See IWorkbenchPage#closeEditor
	 */
	public boolean closeEditor(IEditorPart editor, boolean save) {
		IWorkbenchPartReference ref = getReference(editor);
		if (ref instanceof IEditorReference) {
			return closeEditors(
					new IEditorReference[] { (IEditorReference) ref }, save);
		}
		return false;
	}

	/**
	 * @see IWorkbenchPage#closePerspective(IPerspectiveDescriptor, boolean,
	 *      boolean)
	 */
	public void closePerspective(IPerspectiveDescriptor desc,
			boolean saveParts, boolean closePage) {
		Perspective persp = findPerspective(desc);
		if (persp != null) {
			perspList.openedList.remove(persp);
			perspList.usedList.remove(persp);

			// If we close the last perspective there is no active one...
			if (perspList.openedList.isEmpty())
				perspList.setActive(null);
		}
	}

	/**
	 * Closes the specified perspective in this page. If this is not the last
	 * perspective in the page, and it is active, then the perspective specified
	 * by <code>descToActivate</code> will be activated. If the last perspective
	 * in this page is closed, then all editors are closed. Views that are not
	 * shown in other perspectives are closed as well. If <code>saveParts</code>
	 * is <code>true</code>, the user will be prompted to save any unsaved
	 * changes for parts that are being closed. The page itself is closed if
	 * <code>closePage</code> is <code>true</code>.
	 * 
	 * @param desc
	 *            the descriptor of the perspective to be closed
	 * @param descToActivate
	 *            the descriptor of the perspective to activate
	 * @param saveParts
	 *            whether the page's parts should be saved if closed
	 * @param closePage
	 *            whether the page itself should be closed if last perspective
	 * @since 3.4
	 */
	public void closePerspective(IPerspectiveDescriptor desc,
			IPerspectiveDescriptor descToActivate, boolean saveParts,
			boolean closePage) {
		Perspective persp = findPerspective(desc);
		if (persp != null) {
			perspList.openedList.remove(persp);
			perspList.usedList.remove(persp);

			// If we close the last perspective there is no active one...
			if (perspList.openedList.isEmpty())
				perspList.setActive(null);
		}
	}

	/**
	 * Closes the specified perspective. If last perspective, then entire page
	 * is closed.
	 * 
	 * @param persp
	 *            the perspective to be closed
	 * @param saveParts
	 *            whether the parts that are being closed should be saved
	 *            (editors if last perspective, views if not shown in other
	 *            parspectives)
	 */
	/* package */
	void closePerspective(Perspective persp, boolean saveParts,
			boolean closePage) {
		closePerspective(persp, null, saveParts, closePage);
	}

	/**
	 * Closes the specified perspective. If last perspective, then entire page
	 * is closed.
	 * 
	 * @param persp
	 *            the perspective to be closed
	 * @param perspToActivate
	 *            the perspective to activate
	 * @param saveParts
	 *            whether the parts that are being closed should be saved
	 *            (editors if last perspective, views if not shown in other
	 *            parspectives)
	 */
	/* package */
	void closePerspective(Perspective persp, Perspective perspToActivate,
			boolean saveParts, boolean closePage) {

	}

	/**
	 * Forces all perspectives on the page to zoom out.
	 */
	public void unzoomAllPerspectives() {
	}

	/**
	 * @see IWorkbenchPage#closeAllPerspectives(boolean, boolean)
	 */
	public void closeAllPerspectives(boolean saveEditors, boolean closePage) {

		if (perspList.isEmpty()) {
			return;
		}

		// Always unzoom
		if (isZoomed()) {
			zoomOut();
		}

		if (saveEditors) {
			if (!saveAllEditors(true)) {
				return;
			}
		}
		// Close all editors
		if (!closeAllEditors(false)) {
			return;
		}

		// Deactivate the active perspective and part
		setPerspective((Perspective) null);

		// Close each perspective in turn
		PerspectiveList oldList = perspList;
		perspList = new PerspectiveList();
		Iterator itr = oldList.iterator();
		while (itr.hasNext()) {
			closePerspective((Perspective) itr.next(), false, false);
		}
		if (closePage) {
			close();
		}
	}

	/**
	 * Creates a new view set. Return null on failure.
	 * 
	 * @param desc
	 *            the perspective descriptor
	 * @param notify
	 *            whether to fire a perspective opened event
	 */
	private Perspective createPerspective(PerspectiveDescriptor desc,
			boolean notify) {
		String label = desc.getId(); // debugging only
		try {
			UIStats.start(UIStats.CREATE_PERSPECTIVE, label);
			Perspective persp = ((WorkbenchImplementation) Tweaklets
					.get(WorkbenchImplementation.KEY)).createPerspective(desc,
					this);
			perspList.add(persp);
			if (notify) {
				window.firePerspectiveOpened(this, desc);
			}
			// if the perspective is fresh and uncustomzied then it is not dirty
			// no reset will be prompted for
			if (!desc.hasCustomDefinition()) {
				dirtyPerspectives.remove(desc.getId());
			}
			return persp;
		} catch (WorkbenchException e) {
			if (!((Workbench) window.getWorkbench()).isStarting()) {
				MessageDialog
						.openError(
								window.getShell(),
								WorkbenchMessages.Error,
								NLS
										.bind(
												WorkbenchMessages.Workbench_showPerspectiveError,
												desc.getId()));
			}
			return null;
		} finally {
			UIStats.end(UIStats.CREATE_PERSPECTIVE, desc.getId(), label);
		}
	}

	/**
	 * This is called by child objects after a part has been added to the page.
	 * The page will in turn notify its listeners.
	 */
	/* package */void partAdded(WorkbenchPartReference ref) {
		partList.addPart(ref);
	}

	/**
	 * This is called by child objects after a part has been added to the page.
	 * The part will be queued for disposal after all listeners have been
	 * notified
	 */
	/* package */void partRemoved(IWorkbenchPartReference ref) {
		disposePart(ref);
	}

	private void disposePart(IWorkbenchPartReference ref) {
		if (ref instanceof WorkbenchPartReference) {
			partList.removePart((WorkbenchPartReference) ref);
			((WorkbenchPartReference) ref).dispose();
		} else if (ref instanceof ModelReference) {
			MPart modelPart = ((ModelReference) ref).getModel();
			partList.firePartClosed(ref);
			modelPart.setVisible(false);
		}
	}

	/**
	 * Detaches a view from the WorkbenchWindow.
	 */
	public void detachView(IViewReference ref) {

	}

	/**
	 * Removes a detachedwindow.
	 */
	public void attachView(IViewReference ref) {
	}

	/**
	 * Cleanup.
	 */
	public void dispose() {

		// Always unzoom
		if (isZoomed()) {
			zoomOut();
		}

	}

	/**
	 * @return NavigationHistory
	 */
	public INavigationHistory getNavigationHistory() {
		return (INavigationHistory) e4Context.get(INavigationHistory.class
				.getName());
	}

	/**
	 * Edits the action sets.
	 */
	public boolean editActionSets() {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return false;
		}

		// Create list dialog.
		CustomizePerspectiveDialog dlg = window
				.createCustomizePerspectiveDialog(persp);

		// Open.
		boolean ret = (dlg.open() == Window.OK);
		if (ret) {
			window.updateActionSets();
			window.firePerspectiveChanged(this, getPerspective(), CHANGE_RESET);
			window.firePerspectiveChanged(this, getPerspective(),
					CHANGE_RESET_COMPLETE);
		}
		return ret;
	}

	/**
	 * Returns the first view manager with given ID.
	 */
	public Perspective findPerspective(IPerspectiveDescriptor desc) {
		Iterator itr = perspList.iterator();
		while (itr.hasNext()) {
			Perspective mgr = (Perspective) itr.next();
			if (desc.getId().equals(mgr.getDesc().getId())) {
				return mgr;
			}
		}
		return null;
	}

	/**
	 * See IWorkbenchPage@findView.
	 */
	public IViewPart findView(String id) {
		IViewReference ref = findViewReference(id);
		if (ref == null) {
			return null;
		}
		return ref.getView(true);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage
	 */
	public IViewReference findViewReference(String viewId) {
		return findViewReference(viewId, null);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage
	 */
	public IViewReference findViewReference(String viewId, String secondaryId) {
		MPart modelPart = ModeledPageLayout.findPart(e4Window, viewId);
		if (modelPart instanceof MPart) {
			Object obj = ((MPart) modelPart).getObject();
			if (!(obj instanceof LegacyView))
				return null;

			LegacyView lv = (LegacyView) obj;
			return (IViewReference) getReference(lv.getViewPart());
		}
		return null;
	}

	/**
	 * Notify property change listeners about a property change.
	 * 
	 * @param changeId
	 *            the change id
	 * @param oldValue
	 *            old property value
	 * @param newValue
	 *            new property value
	 */
	private void firePropertyChange(String changeId, Object oldValue,
			Object newValue) {

		UIListenerLogging.logPagePropertyChanged(this, changeId, oldValue,
				newValue);

		Object[] listeners = propertyChangeListeners.getListeners();
		PropertyChangeEvent event = new PropertyChangeEvent(this, changeId,
				oldValue, newValue);

		for (int i = 0; i < listeners.length; i++) {
			((IPropertyChangeListener) listeners[i]).propertyChange(event);
		}
	}

	/*
	 * Returns the action bars.
	 */
	public IActionBars getActionBars() {
		if (actionBars == null) {
			actionBars = new WWinActionBars(window);
		}
		return actionBars;
	}

	/**
	 * Returns an array of the visible action sets.
	 */
	public IActionSetDescriptor[] getActionSets() {

		Collection visibleItems = actionSets.getVisibleItems();
		return (IActionSetDescriptor[]) visibleItems
				.toArray(new IActionSetDescriptor[visibleItems.size()]);
	}

	/**
	 * @see IWorkbenchPage
	 */
	public IEditorPart getActiveEditor() {
		return partList.getActiveEditor();
	}

	/**
	 * Returns the reference for the active editor, or <code>null</code> if
	 * there is no active editor.
	 * 
	 * @return the active editor reference or <code>null</code>
	 */
	public IEditorReference getActiveEditorReference() {
		return partList.getActiveEditorReference();
	}

	/*
	 * (non-Javadoc) Method declared on IPartService
	 */
	public IWorkbenchPart getActivePart() {
		return partList.getActivePart();
	}

	/*
	 * (non-Javadoc) Method declared on IPartService
	 */
	public IWorkbenchPartReference getActivePartReference() {
		return partList.getActivePartReference();
	}

	/**
	 * Returns the active perspective for the page, <code>null</code> if none.
	 */
	public Perspective getActivePerspective() {
		return perspList.getActive();
	}

	/**
	 * Returns the client composite.
	 */
	public Composite getClientComposite() {
		return composite;
	}

	/**
	 * Answer the perspective presentation.
	 */
	public PerspectiveHelper getPerspectivePresentation() {
		if (getActivePerspective() != null) {
			return getActivePerspective().getPresentation();
		}
		return null;
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IEditorPart[] getEditors() {
		final IEditorReference refs[] = getEditorReferences();
		final ArrayList result = new ArrayList(refs.length);
		Display d = getWorkbenchWindow().getShell().getDisplay();
		// Must be backward compatible.
		d.syncExec(new Runnable() {
			public void run() {
				for (int i = 0; i < refs.length; i++) {
					IWorkbenchPart part = refs[i].getPart(true);
					if (part != null) {
						result.add(part);
					}
				}
			}
		});
		final IEditorPart editors[] = new IEditorPart[result.size()];
		return (IEditorPart[]) result.toArray(editors);
	}

	public IEditorPart[] getDirtyEditors() {
		return new IEditorPart[0];
	}

	public ISaveablePart[] getDirtyParts() {
		List result = new ArrayList(3);
		IWorkbenchPartReference[] allParts = getAllParts();
		for (int i = 0; i < allParts.length; i++) {
			IWorkbenchPartReference reference = allParts[i];

			IWorkbenchPart part = reference.getPart(false);
			if (part != null && part instanceof ISaveablePart) {
				ISaveablePart saveable = (ISaveablePart) part;
				if (saveable.isDirty()) {
					result.add(saveable);
				}
			}
		}

		return (ISaveablePart[]) result
				.toArray(new ISaveablePart[result.size()]);
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IEditorPart findEditor(IEditorInput input) {
		IEditorReference[] editorReferences = findEditors(input, null,
				IWorkbenchPage.MATCH_INPUT);
		if (editorReferences.length == 0) {
			return null;
		}
		return editorReferences[0].getEditor(true);
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IEditorReference[] findEditors(IEditorInput input, String editorId,
			int matchFlags) {
		IEditorReference[] refs = getEditorReferences();
		ArrayList<IEditorReference> matches = null;
		for (IEditorReference ref : refs) {
			if ((matchFlags & IWorkbenchPage.MATCH_ID) != 0) {
				String testID = ref.getId();
				if ((editorId != null) && !(editorId.equals(testID)))
					continue;
				if (editorId == null && testID != null)
					continue;
			}
			if ((matchFlags & IWorkbenchPage.MATCH_INPUT) != 0) {
				IEditorInput testInput;
				try {
					testInput = ref.getEditorInput();
				} catch (PartInitException e) {
					continue;
				}
				if ((input != null) && !(input.equals(testInput)))
					continue;
				if (input == null && testInput != null)
					continue;
			}
			if (matches == null)
				matches = new ArrayList<IEditorReference>(3);
			matches.add(ref);
		}
		if (matches == null)
			return noEditorRefs;
		IEditorReference[] result = new IEditorReference[matches.size()];
		matches.toArray(result);
		return result;
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IEditorReference[] getEditorReferences() {
		ArrayList<IEditorReference> result = new ArrayList<IEditorReference>();
		getContainedEditorRefs(result, e4Window);
		IEditorReference[] typedResult = new IEditorReference[result.size()];
		result.toArray(typedResult);
		return typedResult;
	}

	public void getContainedEditorRefs(ArrayList<IEditorReference> result,
			MElementContainer<?> container) {
		for (MUIElement child : container.getChildren()) {
			if (child instanceof MEditor) {
				// @issue here we are expected to sort views from editors.
				// However, there is no such distinction for E4 elements.
				// The code below is only good for legacy views/editors.
				Object object = ((MContribution) child).getObject();
				if (object instanceof EditorPart)
					result.add(new ModelEditorReference((MPart) child, this));
			}
			if (child instanceof MElementContainer<?>)
				getContainedEditorRefs(result,
						(MElementContainer<MUIElement>) child);
		}
	}

	/**
	 * Returns the docked views.
	 */
	public IViewReference[] getFastViews() {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			return persp.getFastViews();
		} else {
			return new IViewReference[0];
		}
	}

	/**
	 * @see IWorkbenchPage
	 */
	public IAdaptable getInput() {
		return input;
	}

	/**
	 * Returns the page label. This is a combination of the page input and
	 * active perspective.
	 */
	public String getLabel() {
		String label = WorkbenchMessages.WorkbenchPage_UnknownLabel;
		IWorkbenchAdapter adapter = (IWorkbenchAdapter) Util.getAdapter(input,
				IWorkbenchAdapter.class);
		if (adapter != null) {
			label = adapter.getLabel(input);
		}
		Perspective persp = getActivePerspective();
		if (persp != null) {
			label = NLS.bind(WorkbenchMessages.WorkbenchPage_PerspectiveFormat,
					label, persp.getDesc().getLabel());
		} else if (deferredActivePersp != null) {
			label = NLS.bind(WorkbenchMessages.WorkbenchPage_PerspectiveFormat,
					label, deferredActivePersp.getLabel());
		}
		return label;
	}

	/**
	 * Returns the perspective.
	 */
	public IPerspectiveDescriptor getPerspective() {
		if (deferredActivePersp != null) {
			return deferredActivePersp;
		}
		Perspective persp = getActivePerspective();
		if (persp != null) {
			return persp.getDesc();
		} else {
			return null;
		}
	}

	/*
	 * (non-Javadoc) Method declared on ISelectionService
	 */
	public ISelection getSelection() {
		return selectionService.getSelection();
	}

	/*
	 * (non-Javadoc) Method declared on ISelectionService
	 */
	public ISelection getSelection(String partId) {
		return selectionService.getSelection(partId);
	}

	/**
	 * Returns the ids of the parts to list in the Show In... prompter. This is
	 * a List of Strings.
	 */
	public ArrayList getShowInPartIds() {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			return persp.getShowInPartIds();
		} else {
			return new ArrayList();
		}
	}

	/**
	 * The user successfully performed a Show In... action on the specified
	 * part. Update the list of Show In items accordingly.
	 */
	public void performedShowIn(String partId) {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			persp.performedShowIn(partId);
		}
	}

	/**
	 * Sorts the given collection of show in target part ids in MRU order.
	 */
	public void sortShowInPartIds(ArrayList partIds) {
		final Perspective persp = getActivePerspective();
		if (persp != null) {
			Collections.sort(partIds, new Comparator() {
				public int compare(Object a, Object b) {
					long ta = persp.getShowInTime((String) a);
					long tb = persp.getShowInTime((String) b);
					return (ta == tb) ? 0 : ((ta > tb) ? -1 : 1);
				}
			});
		}
	}

	/*
	 * Returns the view factory.
	 */
	public ViewFactory getViewFactory() {
		if (viewFactory == null) {
			viewFactory = new ViewFactory(this, WorkbenchPlugin.getDefault()
					.getViewRegistry());
		}
		return viewFactory;
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IViewReference[] getViewReferences() {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			return persp.getViewReferences();
		} else {
			return new IViewReference[0];
		}
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IViewPart[] getViews() {
		return getViews(null, true);
	}

	/**
	 * Returns all view parts in the specified perspective
	 * 
	 * @param persp
	 *            the perspective
	 * @return an array of view parts
	 * @since 3.1
	 */
	/* package */IViewPart[] getViews(Perspective persp, boolean restore) {
		if (persp == null) {
			persp = getActivePerspective();
		}

		if (persp != null) {
			IViewReference refs[] = persp.getViewReferences();
			ArrayList parts = new ArrayList(refs.length);
			for (int i = 0; i < refs.length; i++) {
				IWorkbenchPart part = refs[i].getPart(restore);
				if (part != null) {
					parts.add(part);
				}
			}
			IViewPart[] result = new IViewPart[parts.size()];
			return (IViewPart[]) parts.toArray(result);
		}
		return new IViewPart[0];
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IWorkbenchWindow getWorkbenchWindow() {
		return window;
	}

	/**
	 * Implements IWorkbenchPage
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#getWorkingSet()
	 * @since 2.0
	 * @deprecated individual views should store a working set if needed
	 */
	public IWorkingSet getWorkingSet() {
		return workingSet;
	}

	/**
	 * @see IWorkbenchPage
	 */
	public void hideActionSet(String actionSetID) {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			persp.removeActionSet(actionSetID);
			window.updateActionSets();
			window.firePerspectiveChanged(this, getPerspective(),
					CHANGE_ACTION_SET_HIDE);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.ui.IWorkbenchPage#hideView(org.eclipse.ui.IViewReference)
	 */
	public void hideView(IViewReference ref) {

		// Sanity check.
		if (ref == null) {
			return;
		}

		Perspective persp = getActivePerspective();
		if (persp == null) {
			return;
		}

		IViewPart view = ref.getView(false);
		if (view != null) {

			if (!certifyPart(view)) {
				return;
			}

			// Confirm.
			if (view instanceof ISaveablePart) {
				ISaveablePart saveable = (ISaveablePart) view;
				if (saveable.isSaveOnCloseNeeded()) {
					IWorkbenchWindow window = view.getSite()
							.getWorkbenchWindow();
					boolean success = EditorManager.saveAll(Collections
							.singletonList(view), true, true, false, window);
					if (!success) {
						// the user cancelled.
						return;
					}
				}
			}
		}

		// Notify interested listeners before the hide
		window.firePerspectiveChanged(this, persp.getDesc(), ref,
				CHANGE_VIEW_HIDE);

		// Hide the part.
		persp.hideView(ref);

		// Notify interested listeners after the hide
		window.firePerspectiveChanged(this, getPerspective(), CHANGE_VIEW_HIDE);
	}

	/* package */void refreshActiveView() {

	}

	/**
	 * See IPerspective
	 */
	public void hideView(IViewPart view) {
		hideView((IViewReference) getReference(view));
	}

	/**
	 * Initialize the page.
	 * 
	 * @param w
	 *            the parent window
	 * @param layoutID
	 *            may be <code>null</code> if restoring from file
	 * @param input
	 *            the page input
	 * @param openExtras
	 *            whether to process the perspective extras preference
	 */
	private void init(WorkbenchWindow w, String layoutID, IAdaptable input,
			boolean openExtras) throws WorkbenchException {
		// Save args.
		this.window = w;
		this.input = input;
		actionSets = new ActionSetManager(w);

		e4Window = w.getModelWindow();
		e4Context = e4Window.getContext();
		e4Context.set(IWorkbenchPage.class.getName(), this);
		e4Context.set(WorkbenchPage.class.getName(), this);
		selectionService = (ISelectionService) e4Context
				.get(ISelectionService.class.getName());
		partList = new WorkbenchPagePartList(selectionService);

		navigationHistory = new NavigationHistory(this);
		e4Context.set(INavigationHistory.class.getName(), navigationHistory);

		((Notifier) e4Window).eAdapters().add(
				new PartsEventTransformer(e4Context, partList));

		// Create presentation.
		// Get perspective descriptor.
		if (layoutID != null) {
			PerspectiveDescriptor desc = (PerspectiveDescriptor) WorkbenchPlugin
					.getDefault().getPerspectiveRegistry()
					.findPerspectiveWithId(layoutID);
			if (desc == null) {
				throw new WorkbenchException(
						NLS
								.bind(
										WorkbenchMessages.WorkbenchPage_ErrorCreatingPerspective,
										layoutID));
			}
			Perspective persp = findPerspective(desc);
			if (persp == null) {
				persp = createPerspective(desc, true);
			}
			perspList.setActive(persp);
			window.firePerspectiveActivated(this, desc);
		}

		// read model extensions
		ModelExtensionProcessor extProcessor = new ModelExtensionProcessor(
				e4Window);
		extProcessor.addModelExtensions();
		partEvents();
	}

	private void partEvents() {
		partList.getPartService().addPartListener(new IPartListener() {

			public void partOpened(IWorkbenchPart part) {
				// TODO Auto-generated method stub

			}

			public void partDeactivated(IWorkbenchPart part) {
				// TODO Auto-generated method stub

			}

			public void partClosed(IWorkbenchPart part) {
				// TODO Auto-generated method stub

			}

			public void partBroughtToTop(IWorkbenchPart part) {
				calculateActionSets(part);
			}

			public void partActivated(IWorkbenchPart part) {
				calculateActionSets(part);
			}
		});
	}

	private ArrayList oldActionSets = new ArrayList();

	void calculateActionSets(IWorkbenchPart part) {
		ArrayList newActionSets = new ArrayList();
		if (part != null) {
			IActionSetDescriptor[] partActionSets = WorkbenchPlugin
					.getDefault().getActionSetRegistry().getActionSetsFor(
							part.getSite().getId());
			for (int i = 0; i < partActionSets.length; i++) {
				newActionSets.add(partActionSets[i]);
			}
		}
		IEditorPart editor = partList.getActiveEditor();
		if (editor != null && editor != part) {
			IActionSetDescriptor[] editorActionSets = WorkbenchPlugin
					.getDefault().getActionSetRegistry().getActionSetsFor(
							editor.getSite().getId());
			for (int i = 0; i < editorActionSets.length; i++) {
				newActionSets.add(editorActionSets[i]);
			}
		}
		if (oldActionSets.equals(newActionSets)) {
			return;
		}
		IContextService service = (IContextService) window
				.getService(IContextService.class);
		try {
			service.deferUpdates(true);

			// show the new
			for (int i = 0; i < newActionSets.size(); i++) {
				actionSets.showAction((IActionSetDescriptor) newActionSets
						.get(i));
			}

			// hide the old
			for (int i = 0; i < oldActionSets.size(); i++) {
				actionSets.hideAction((IActionSetDescriptor) oldActionSets
						.get(i));
			}

			oldActionSets = newActionSets;

		} finally {
			service.deferUpdates(false);
		}
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return;
		}

		window.updateActionSets(); // this calls updateActionBars
		window.firePerspectiveChanged(WorkbenchPage.this, getPerspective(),
				CHANGE_ACTION_SET_SHOW);
	}

	/**
	 * Opens the perspectives specified in the PERSPECTIVE_BAR_EXTRAS preference
	 * (see bug 84226).
	 */
	public void openPerspectiveExtras() {
		String extras = PrefUtil.getAPIPreferenceStore().getString(
				IWorkbenchPreferenceConstants.PERSPECTIVE_BAR_EXTRAS);
		StringTokenizer tok = new StringTokenizer(extras, ", "); //$NON-NLS-1$
		ArrayList descs = new ArrayList();
		while (tok.hasMoreTokens()) {
			String id = tok.nextToken();
			IPerspectiveDescriptor desc = WorkbenchPlugin.getDefault()
					.getPerspectiveRegistry().findPerspectiveWithId(id);
			if (desc != null) {
				descs.add(desc);
			}
		}
		// HACK: The perspective switcher currently adds the button for a new
		// perspective to the beginning of the list.
		// So, we process the extra perspectives in reverse order here to have
		// their buttons appear in the order declared.
		for (int i = descs.size(); --i >= 0;) {
			PerspectiveDescriptor desc = (PerspectiveDescriptor) descs.get(i);
			if (findPerspective(desc) == null) {
				createPerspective(desc, true);
			}
		}
	}

	/**
	 * Finds and returns a part in the current perspective with the
	 * corresponding id.
	 * 
	 * @param partId
	 *            the id of the part, must not be <code>null</code>
	 * @return a part in the current perspective with the specified id
	 */
	private MPart findPartInCurrentPerspective(String partId) {
		Assert.isNotNull(partId);
		// retrieve the perspective stack from our window
		MPerspectiveStack perspStack = (MPerspectiveStack) ModeledPageLayout
				.findPart(e4Window, "PerspectiveStack"); //$NON-NLS-1$
		// get the active/current one
		MPerspective curPersp = (MPerspective) perspStack.getActiveChild();
		// try to find a child part
		return ModeledPageLayout.findPart(curPersp, partId);
	}

	/**
	 * See IWorkbenchPage.
	 */
	public boolean isPartVisible(IWorkbenchPart part) {
		if (part == null) {
			return false;
		}

		MPart modelPart = findPartInCurrentPerspective(part.getSite().getId());
		// couldn't find the part, return false
		if (modelPart == null) {
			return false;
		}

		MElementContainer<MUIElement> parent = modelPart.getParent();
		// no parent, probably not visible
		if (parent == null) {
			return false;
		}
		// return whether the parent's active child is us
		return parent.getActiveChild() == modelPart;
	}

	/**
	 * See IWorkbenchPage.
	 */
	public boolean isEditorAreaVisible() {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return false;
		}
		return persp.isEditorAreaVisible();
	}

	/**
	 * Returns whether the view is fast.
	 */
	public boolean isFastView(IViewReference ref) {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			return persp.isFastView(ref);
		} else {
			return false;
		}
	}

	/**
	 * Return whether the view is closeable or not.
	 * 
	 * @param ref
	 *            the view reference to check. Must not be <code>null</code>.
	 * @return true if the part is closeable.
	 * @since 3.1.1
	 */
	public boolean isCloseable(IViewReference ref) {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			return persp.isCloseable(ref);
		}
		return false;
	}

	/**
	 * Return whether the view is moveable or not.
	 * 
	 * @param ref
	 *            the view reference to check. Must not be <code>null</code>.
	 * @return true if the part is moveable.
	 * @since 3.1.1
	 */
	public boolean isMoveable(IViewReference ref) {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			return persp.isMoveable(ref);
		}
		return false;
	}

	/**
	 * Returns whether the layout of the active perspective is fixed.
	 */
	public boolean isFixedLayout() {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			return persp.isFixedLayout();
		} else {
			return false;
		}
	}

	/**
	 * Return the active fast view or null if there are no fast views or if
	 * there are all minimized.
	 */
	public IViewReference getActiveFastView() {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			return persp.getActiveFastView();
		} else {
			return null;
		}
	}

	/**
	 * Return true if the perspective has a dirty editor.
	 */
	protected boolean isSaveNeeded() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#isPageZoomed()
	 */
	public boolean isPageZoomed() {
		return false;
	}

	/**
	 * Returns whether the page is zoomed.
	 * 
	 * @return <code>true</code> if the page is zoomed.
	 * 
	 *         <strong>NOTE:</strong> As of 3.3 this method should always return
	 *         'false' when using the new min/max behavior. It is only used for
	 *         legacy 'zoom' handling.
	 * 
	 */
	public boolean isZoomed() {
		return false;
	}

	/**
	 * This method is called when the page is activated.
	 */
	protected void onActivate() {
		composite.setVisible(true);
		Perspective persp = getActivePerspective();

		if (persp != null) {
			persp.onActivate();
		}
	}

	/**
	 * This method is called when the page is deactivated.
	 */
	protected void onDeactivate() {
		if (getActivePerspective() != null) {
			getActivePerspective().onDeactivate();
		}
		composite.setVisible(false);
	}

	/**
	 * See IWorkbenchPage.
	 */
	public void reuseEditor(IReusableEditor editor, IEditorInput input) {

		// Rather than calling editor.setInput on the editor directly, we do it
		// through the part reference.
		// This case lets us detect badly behaved editors that are not firing a
		// PROP_INPUT event in response
		// to the input change... but if all editors obeyed their API contract,
		// the "else" branch would be
		// sufficient.
		IWorkbenchPartReference ref = getReference(editor);
		if (ref instanceof EditorReference) {
			EditorReference editorRef = (EditorReference) ref;

			editorRef.setInput(input);
		} else {
			editor.setInput(input);
		}
		navigationHistory.markEditor(editor);
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IEditorPart openEditor(IEditorInput input, String editorID)
			throws PartInitException {
		return openEditor(input, editorID, true, MATCH_INPUT);
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IEditorPart openEditor(IEditorInput input, String editorID,
			boolean activate) throws PartInitException {
		return openEditor(input, editorID, activate, MATCH_INPUT);
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IEditorPart openEditor(final IEditorInput input,
			final String editorID, final boolean activate, final int matchFlags)
			throws PartInitException {
		return openEditor(input, editorID, activate, matchFlags, null);
	}

	/**
	 * This is not public API but for use internally. editorState can be
	 * <code>null</code>.
	 */
	public IEditorPart openEditor(final IEditorInput input,
			final String editorID, final boolean activate,
			final int matchFlags, final IMemento editorState)
			throws PartInitException {
		if (input == null || editorID == null) {
			throw new IllegalArgumentException();
		}

		// Special handling for external editors (they have no tabs...)
		if ("org.eclipse.ui.systemExternalEditor".equals(editorID) //$NON-NLS-1$
				|| "org.eclipse.ui.browser.editorSupport".equals(editorID)) { //$NON-NLS-1$
			if (input instanceof IPathEditorInput) {
				IPathEditorInput fileInput = (IPathEditorInput) input;
				String fullPath = fileInput.getPath().toOSString();
				Program.launch(fullPath);
				return null;
			}
		}

		// retrieve the editor area
		MEditorSashContainer ea = (MEditorSashContainer) findPartInCurrentPerspective(ModeledPageLayout
				.internalGetEditorArea());

		// TBD need to add processing for other flags: MATCH_INPUT, MATCH_ID
		if (matchFlags != IWorkbenchPage.MATCH_NONE) {
			// Find a matching editor
			MEditor existingEditor = findEditor(ea, editorID, input);
			if (existingEditor != null && activate) {
				// Set the initial focus
				LegacyEditor le = (LegacyEditor) existingEditor.getObject();
				Object impl = le.getEditorWBPart();
				if (impl instanceof IWorkbenchPart) {
					activate((IWorkbenchPart) impl);
				} else {
					ea.setActiveChild(existingEditor);
				}

				// return the existing editor
				return (IEditorPart) impl;
			}
		}

		// No patching editor found, create one
		MEditor editorPart = MApplicationFactory.eINSTANCE.createEditor();
		editorPart.setURI(LegacyEditor.LEGACY_VIEW_URI);
		editorPart.setId(editorID);
		editorPart.setName(input.getName());
		// editor part icon will be set in LegacyViewFactory
		editorPart.setVisible(false);
		ea.getChildren().add(editorPart);
		editorPart.getContext().set(IEditorInput.class.getName(), input);
		editorPart.setVisible(true);

		// Manage the 'close' button
		final IEclipseContext editorContext = editorPart.getContext();
		final MEditor theEditor = editorPart;
		IValueFunction closeFunc = new IValueFunction() {
			public Object getValue() {
				Object impl = ((MPart) theEditor).getObject();
				if (impl instanceof EditorPart) {
					EditorPart edPart = (EditorPart) impl;
					boolean closed = closeEditor(edPart, true);
					return closed;
				}
				return new Boolean(true);
			}
		};
		editorContext.set("canCloseFunc", closeFunc); //$NON-NLS-1$

		LegacyEditor le = (LegacyEditor) editorPart.getObject();
		Object impl = le.getEditorWBPart();
		if (impl instanceof IWorkbenchPart) { // TBD this is always the case?
			IWorkbenchPart workbenchPart = (IWorkbenchPart) impl;
			if (activate)
				activate(workbenchPart);
			else
				bringToTop(workbenchPart);
		}

		return le.getEditorWBPart();
	}

	/**
	 * @param ea
	 * @param editorID
	 * @param input2
	 * @return
	 */
	private MEditor findEditor(MEditorSashContainer ea, String editorID,
			IEditorInput input) {
		MUIElement ed = ModeledPageLayout.findElementById(ea, editorID);
		if (ed instanceof MEditor) {
			MEditor editor = (MEditor) ed;
			IEditorInput e = (IEditorInput) editor.getContext().get(
					IEditorInput.class.getName());
			if (input.equals(e)) {
				return editor;
			}
		}
		return null;
	}

	/*
	 * Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
	 * external program. Opens a new editor using the given input and
	 * descriptor. (Normally, editors are opened using an editor ID and an
	 * input.)
	 */
	public IEditorPart openEditorFromDescriptor(final IEditorInput input,
			final IEditorDescriptor editorDescriptor, final boolean activate,
			final IMemento editorState) throws PartInitException {
		if (input == null || !(editorDescriptor instanceof EditorDescriptor)) {
			throw new IllegalArgumentException();
		}

		final IEditorPart result[] = new IEditorPart[1];
		final PartInitException ex[] = new PartInitException[1];
		BusyIndicator.showWhile(window.getWorkbench().getDisplay(),
				new Runnable() {
					public void run() {
						try {
							result[0] = busyOpenEditorFromDescriptor(input,
									(EditorDescriptor) editorDescriptor,
									activate, editorState);
						} catch (PartInitException e) {
							ex[0] = e;
						}
					}
				});
		if (ex[0] != null) {
			throw ex[0];
		}
		return result[0];
	}

	/*
	 * Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
	 * external program. See openEditorFromDescriptor().
	 */
	private IEditorPart busyOpenEditorFromDescriptor(IEditorInput input,
			EditorDescriptor editorDescriptor, boolean activate,
			IMemento editorState) throws PartInitException {

		final Workbench workbench = (Workbench) getWorkbenchWindow()
				.getWorkbench();
		workbench.largeUpdateStart();

		try {
			return busyOpenEditorFromDescriptorBatched(input, editorDescriptor,
					activate, editorState);

		} finally {
			workbench.largeUpdateEnd();
		}
	}

	/**
	 * Do not call this method. Use <code>busyOpenEditor</code>.
	 * 
	 * @see IWorkbenchPage#openEditor(IEditorInput, String, boolean)
	 */
	protected IEditorPart busyOpenEditorBatched(IEditorInput input,
			String editorID, boolean activate, int matchFlags,
			IMemento editorState) throws PartInitException {

		IEditorPart editor = null;
		// Otherwise, create a new one. This may cause the new editor to
		// become the visible (i.e top) editor.
		IEditorReference ref = null;
		try {
			partBeingOpened = true;
			ref = null; // open the editor, somehow
			if (ref != null) {
				editor = ref.getEditor(true);
			}
		} finally {
			partBeingOpened = false;
		}

		if (editor != null) {
			setEditorAreaVisible(true);
			if (activate) {
				if (editor instanceof AbstractMultiEditor) {
					activate(((AbstractMultiEditor) editor).getActiveEditor());
				} else {
					activate(editor);
				}
			} else {
				bringToTop(editor);
			}
			window.firePerspectiveChanged(this, getPerspective(), ref,
					CHANGE_EDITOR_OPEN);
			window.firePerspectiveChanged(this, getPerspective(),
					CHANGE_EDITOR_OPEN);
		}

		return editor;
	}

	/*
	 * Added to fix Bug 178235 [EditorMgmt] DBCS 3.3 - Cannot open file with
	 * external program. See openEditorFromDescriptor().
	 */
	private IEditorPart busyOpenEditorFromDescriptorBatched(IEditorInput input,
			EditorDescriptor editorDescriptor, boolean activate,
			IMemento editorState) throws PartInitException {

		IEditorPart editor = null;
		// Create a new one. This may cause the new editor to
		// become the visible (i.e top) editor.
		IEditorReference ref = null;
		ref = null; // open the editor somehow
		if (ref != null) {
			editor = ref.getEditor(true);
		}

		if (editor != null) {
			setEditorAreaVisible(true);
			if (activate) {
				if (editor instanceof AbstractMultiEditor) {
					activate(((AbstractMultiEditor) editor).getActiveEditor());
				} else {
					activate(editor);
				}
			} else {
				bringToTop(editor);
			}
			window.firePerspectiveChanged(this, getPerspective(), ref,
					CHANGE_EDITOR_OPEN);
			window.firePerspectiveChanged(this, getPerspective(),
					CHANGE_EDITOR_OPEN);
		}

		return editor;
	}

	public void openEmptyTab() {

	}

	protected void showEditor(boolean activate, IEditorPart editor) {
		setEditorAreaVisible(true);
		if (activate) {
			zoomOutIfNecessary(editor);
			activate(editor);
		} else {
			bringToTop(editor);
		}
	}

	/**
	 * See IWorkbenchPage.
	 */
	public boolean isEditorPinned(IEditorPart editor) {
		// TBD we need to add "pinned" attribute somewhere in the E4 model. The
		// code
		// below is just to work around a cast class exception
		IWorkbenchPartReference ref = getReference(editor);
		if (ref == null)
			return false;
		if (ref instanceof WorkbenchPartReference)
			return ((WorkbenchPartReference) ref).isPinned();
		return false;
	}

	/**
	 * Returns whether changes to a part will affect zoom. There are a few
	 * conditions for this .. - we are zoomed. - the part is contained in the
	 * main window. - the part is not the zoom part - the part is not a fast
	 * view - the part and the zoom part are not in the same editor workbook
	 */
	private boolean partChangeAffectsZoom(IWorkbenchPartReference ref) {
		PartPane pane = ((WorkbenchPartReference) ref).getPane();
		if (pane instanceof MultiEditorInnerPane) {
			pane = ((MultiEditorInnerPane) pane).getParentPane();
		}
		return getActivePerspective().getPresentation().partChangeAffectsZoom(
				pane);
	}

	/**
	 * Removes a fast view.
	 */
	public void removeFastView(IViewReference ref) {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return;
		}

		// Do real work.
		persp.removeFastView(ref);

		// Notify listeners.
		window.firePerspectiveChanged(this, getPerspective(), ref,
				CHANGE_FAST_VIEW_REMOVE);
		window.firePerspectiveChanged(this, getPerspective(),
				CHANGE_FAST_VIEW_REMOVE);
	}

	/**
	 * Removes an IPartListener from the part service.
	 */
	public void removePartListener(IPartListener l) {
		partList.getPartService().removePartListener(l);
	}

	/**
	 * Removes an IPartListener from the part service.
	 */
	public void removePartListener(IPartListener2 l) {
		partList.getPartService().removePartListener(l);
	}

	/**
	 * Implements IWorkbenchPage
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#removePropertyChangeListener(IPropertyChangeListener)
	 * @since 2.0
	 * @deprecated individual views should store a working set if needed and
	 *             register a property change listener directly with the working
	 *             set manager to receive notification when the view working set
	 *             is removed.
	 */
	public void removePropertyChangeListener(IPropertyChangeListener listener) {
		propertyChangeListeners.remove(listener);
	}

	/*
	 * (non-Javadoc) Method declared on ISelectionListener.
	 */
	public void removeSelectionListener(ISelectionListener listener) {
		selectionService.removeSelectionListener(listener);
	}

	/*
	 * (non-Javadoc) Method declared on ISelectionListener.
	 */
	public void removeSelectionListener(String partId,
			ISelectionListener listener) {
		selectionService.removeSelectionListener(partId, listener);
	}

	/*
	 * (non-Javadoc) Method declared on ISelectionListener.
	 */
	public void removePostSelectionListener(ISelectionListener listener) {
		selectionService.removePostSelectionListener(listener);
	}

	/*
	 * (non-Javadoc) Method declared on ISelectionListener.
	 */
	public void removePostSelectionListener(String partId,
			ISelectionListener listener) {
		selectionService.removePostSelectionListener(partId, listener);
	}

	/**
	 * This method is called when a part is activated by clicking within it. In
	 * response, the part, the pane, and all of its actions will be activated.
	 * <p>
	 * In the current design this method is invoked by the part pane when the
	 * pane, the part, or any children gain focus.
	 * </p>
	 * <p>
	 * If creating the part causes a forceFocus() well ignore this activation
	 * request.
	 * </p>
	 */
	public void requestActivation(IWorkbenchPart part) {
		// Sanity check.
		if (!certifyPart(part) || partBeingOpened) {
			return;
		}

		if (part instanceof AbstractMultiEditor) {
			part = ((AbstractMultiEditor) part).getActiveEditor();
		}

		// Real work.
	}

	/**
	 * Resets the layout for the perspective. The active part in the old layout
	 * is activated in the new layout for consistent user context.
	 */
	public void resetPerspective() {

	}

	/**
	 * Restore this page from the memento and ensure that the active perspective
	 * is equals the active descriptor otherwise create a new perspective for
	 * that descriptor. If activeDescriptor is null active the old perspective.
	 */
	public IStatus restoreState(IMemento memento,
			final IPerspectiveDescriptor activeDescriptor) {
		return Status.OK_STATUS;
	}

	/**
	 * See IWorkbenchPage
	 */
	public boolean saveAllEditors(boolean confirm) {
		return saveAllEditors(confirm, false);
	}

	/**
	 * @param confirm
	 * @param addNonPartSources
	 *            true if saveables from non-part sources should be saved too
	 * @return false if the user cancelled
	 * 
	 */
	public boolean saveAllEditors(boolean confirm, boolean addNonPartSources) {
		// TBD the code below is oversimplified. See 3.x version for all things
		// that have to be done:
		// return getEditorManager().saveAll(confirm, false, addNonPartSources);

		ISaveablePart[] dirtyParts = getDirtyParts();
		for (ISaveablePart part : dirtyParts) {
			part.doSave(new NullProgressMonitor());
		}

		return true;
	}

	/*
	 * Saves the workbench part.
	 */
	protected boolean savePart(ISaveablePart saveable, IWorkbenchPart part,
			boolean confirm) {
		saveable.doSave(new NullProgressMonitor());
		return true;
	}

	/**
	 * Saves an editors in the workbench. If <code>confirm</code> is
	 * <code>true</code> the user is prompted to confirm the command.
	 * 
	 * @param confirm
	 *            if user confirmation should be sought
	 * @return <code>true</code> if the command succeeded, or <code>false</code>
	 *         if the user cancels the command
	 */
	public boolean saveEditor(IEditorPart editor, boolean confirm) {
		return savePart(editor, editor, confirm);
	}

	/**
	 * Saves the current perspective.
	 */
	public void savePerspective() {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return;
		}

		// Always unzoom.
		if (isZoomed()) {
			zoomOut();
		}

		persp.saveDesc();
	}

	/**
	 * Saves the perspective.
	 */
	public void savePerspectiveAs(IPerspectiveDescriptor newDesc) {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return;
		}
		IPerspectiveDescriptor oldDesc = persp.getDesc();

		// Always unzoom.
		if (isZoomed()) {
			zoomOut();
		}

		persp.saveDescAs(newDesc);
		window.firePerspectiveSavedAs(this, oldDesc, newDesc);
	}

	/**
	 * Save the state of the page.
	 */
	public IStatus saveState(IMemento memento) {
		// We must unzoom to get correct layout.
		if (isZoomed()) {
			zoomOut();
		}

		// Close any open Fast View
		hideFastView();

		MultiStatus result = new MultiStatus(
				PlatformUI.PLUGIN_ID,
				IStatus.OK,
				NLS
						.bind(
								WorkbenchMessages.WorkbenchPage_unableToSavePerspective,
								getLabel()), null);

		// Save editor manager.
		IMemento childMem = memento
				.createChild(IWorkbenchConstants.TAG_EDITORS);
		result.merge(editorMgr.saveState(childMem));

		childMem = memento.createChild(IWorkbenchConstants.TAG_VIEWS);
		result.merge(getViewFactory().saveState(childMem));

		// Create persp block.
		childMem = memento.createChild(IWorkbenchConstants.TAG_PERSPECTIVES);
		if (getPerspective() != null) {
			childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PERSPECTIVE,
					getPerspective().getId());
		}
		if (getActivePart() != null) {
			if (getActivePart() instanceof IViewPart) {
				IViewReference ref = (IViewReference) getReference(getActivePart());
				if (ref != null) {
					childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
							ViewFactory.getKey(ref));
				}
			} else {
				childMem.putString(IWorkbenchConstants.TAG_ACTIVE_PART,
						getActivePart().getSite().getId());
			}
		}

		// Save each perspective in opened order
		Iterator itr = perspList.iterator();
		while (itr.hasNext()) {
			Perspective persp = (Perspective) itr.next();
			IMemento gChildMem = childMem
					.createChild(IWorkbenchConstants.TAG_PERSPECTIVE);
			result.merge(persp.saveState(gChildMem));
		}
		// Save working set if set
		if (workingSet != null) {
			memento.putString(IWorkbenchConstants.TAG_WORKING_SET, workingSet
					.getName());
		}

		IMemento workingSetMem = memento
				.createChild(IWorkbenchConstants.TAG_WORKING_SETS);
		for (int i = 0; i < workingSets.length; i++) {
			workingSetMem.createChild(IWorkbenchConstants.TAG_WORKING_SET,
					workingSets[i].getName());
		}

		if (aggregateWorkingSetId != null) {
			memento.putString(ATT_AGGREGATE_WORKING_SET_ID,
					aggregateWorkingSetId);
		}

		navigationHistory.saveState(memento
				.createChild(IWorkbenchConstants.TAG_NAVIGATION_HISTORY));

		// save the sticky activation state
		stickyViewMan.save(memento);

		return result;
	}

	/**
	 * See IWorkbenchPage.
	 */
	public void setEditorAreaVisible(boolean showEditorArea) {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return;
		}
		if (showEditorArea == persp.isEditorAreaVisible()) {
			return;
		}
		// If parts change always update zoom.
		if (isZoomed()) {
			zoomOut();
		}
		// Update editor area visibility.
		if (showEditorArea) {
			persp.showEditorArea();
			window.firePerspectiveChanged(this, getPerspective(),
					CHANGE_EDITOR_AREA_SHOW);
		} else {
			persp.hideEditorArea();
			window.firePerspectiveChanged(this, getPerspective(),
					CHANGE_EDITOR_AREA_HIDE);
		}
	}

	/**
	 * Sets the layout of the page. Assumes the new perspective is not null.
	 * Keeps the active part if possible. Updates the window menubar and toolbar
	 * if necessary.
	 */
	private void setPerspective(Perspective newPersp) {
		// Don't do anything if already active layout
		Perspective oldPersp = getActivePerspective();
		if (oldPersp == newPersp) {
			return;
		}

		window.largeUpdateStart();
		try {
			if (oldPersp != null) {
				// fire the pre-deactivate
				window.firePerspectivePreDeactivate(this, oldPersp.getDesc());
			}

			if (newPersp != null) {
				IStatus status = newPersp.restoreState();
				if (status.getSeverity() != IStatus.OK) {
					String title = WorkbenchMessages.WorkbenchPage_problemRestoringTitle;
					String msg = WorkbenchMessages.WorkbenchPage_errorReadingState;
					ErrorDialog.openError(getWorkbenchWindow().getShell(),
							title, msg, status);
				}
			}

			// Deactivate the old layout
			if (oldPersp != null) {
				oldPersp.onDeactivate();

				// Notify listeners of deactivation
				window.firePerspectiveDeactivated(this, oldPersp.getDesc());
			}

			// Activate the new layout
			perspList.setActive(newPersp);
			if (newPersp != null) {
				newPersp.onActivate();

				// Notify listeners of activation
				window.firePerspectiveActivated(this, newPersp.getDesc());
			}

			// Update the window
			window.updateActionSets();

			// Update sticky views
			stickyViewMan.update(oldPersp, newPersp);

		} finally {
			window.largeUpdateEnd();
			if (newPersp == null) {
				return;
			}
			IPerspectiveDescriptor desc = newPersp.getDesc();
			if (desc == null) {
				return;
			}
			if (dirtyPerspectives.remove(desc.getId())) {
				suggestReset();
			}
		}
	}

	void perspectiveActionSetChanged(Perspective perspective,
			IActionSetDescriptor descriptor, int changeType) {
		if (perspective == getActivePerspective()) {
			actionSets.change(descriptor, changeType);
		}
	}

	/**
	 * Sets the perspective.
	 * 
	 * @param desc
	 *            identifies the new perspective.
	 */
	public void setPerspective(final IPerspectiveDescriptor desc) {
		try {
			Perspective oldPersp = getActivePerspective();
			if ((oldPersp != null)
					&& oldPersp.getDesc().getId() == desc.getId())
				return;

			Perspective newPersp = findPerspective(desc);
			if (newPersp == null) {
				newPersp = new Perspective((PerspectiveDescriptor) desc, this);
				perspList.add(newPersp);
			}
			// TBD firePerspectivePreDeactivate
			if (oldPersp != null) {
				// TBD: exceptions due to null presentations
				// oldPersp.onDeactivate();
				// TBD firePerspectiveDeactivated
			}
			// Activate the new layout
			perspList.setActive(newPersp);
			// also need to let E4 know
			MPerspective e4perspective = findPerspectiveE4(e4Window, desc
					.getId());
			if (e4perspective != null
					&& e4perspective.getParent().getActiveChild() != e4perspective)
				e4perspective.getParent().setActiveChild(e4perspective);

			if (newPersp != null) {
				// TBD exceptions due to null presentations
				// newPersp.onActivate();
				// TBD firePerspectiveActivated(this, newPersp.getDesc());
			}
		} catch (WorkbenchException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * Allow access to the part service for this page ... used internally to
	 * propogate certain types of events to the page part listeners.
	 * 
	 * @return the part service for this page.
	 */
	public PartService getPartService() {
		return (PartService) partList.getPartService();
	}

	/**
	 * Restore the toolbar layout for the active perspective.
	 */
	protected void resetToolBarLayout() {
		ICoolBarManager2 mgr = (ICoolBarManager2) window.getCoolBarManager2();
		mgr.resetItemOrder();
	}

	/**
	 * Sets the active working set for the workbench page. Notifies property
	 * change listener about the change.
	 * 
	 * @param newWorkingSet
	 *            the active working set for the page. May be null.
	 * @since 2.0
	 * @deprecated individual views should store a working set if needed
	 */
	public void setWorkingSet(IWorkingSet newWorkingSet) {
		IWorkingSet oldWorkingSet = workingSet;

		workingSet = newWorkingSet;
		if (oldWorkingSet != newWorkingSet) {
			firePropertyChange(CHANGE_WORKING_SET_REPLACE, oldWorkingSet,
					newWorkingSet);
		}
		if (newWorkingSet != null) {
			WorkbenchPlugin
					.getDefault()
					.getWorkingSetManager()
					.addPropertyChangeListener(workingSetPropertyChangeListener);
		} else {
			WorkbenchPlugin.getDefault().getWorkingSetManager()
					.removePropertyChangeListener(
							workingSetPropertyChangeListener);
		}
	}

	/**
	 * @see IWorkbenchPage
	 */
	public void showActionSet(String actionSetID) {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			ActionSetRegistry reg = WorkbenchPlugin.getDefault()
					.getActionSetRegistry();

			IActionSetDescriptor desc = reg.findActionSet(actionSetID);
			if (desc != null) {
				persp.addActionSet(desc);
				window.updateActionSets();
				window.firePerspectiveChanged(this, getPerspective(),
						CHANGE_ACTION_SET_SHOW);
			}
		}
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IViewPart showView(String viewID) throws PartInitException {
		return showView(viewID, null, VIEW_ACTIVATE);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String,
	 * java.lang.String, int)
	 */
	public IViewPart showView(final String viewID, final String secondaryID,
			final int mode) throws PartInitException {

		if (secondaryID != null) {
			if (secondaryID.length() == 0
					|| secondaryID.indexOf(ViewFactory.ID_SEP) != -1) {
				throw new IllegalArgumentException(
						WorkbenchMessages.WorkbenchPage_IllegalSecondaryId);
			}
		}
		if (!certifyMode(mode)) {
			throw new IllegalArgumentException(
					WorkbenchMessages.WorkbenchPage_IllegalViewMode);
		}

		// Run op in busy cursor.
		final Object[] result = new Object[1];
		BusyIndicator.showWhile(null, new Runnable() {
			public void run() {
				try {
					result[0] = busyShowView(viewID, secondaryID, mode);
				} catch (PartInitException e) {
					result[0] = e;
				}
			}
		});
		if (result[0] instanceof IViewPart) {
			return (IViewPart) result[0];
		} else if (result[0] instanceof PartInitException) {
			throw (PartInitException) result[0];
		} else {
			throw new PartInitException(
					WorkbenchMessages.WorkbenchPage_AbnormalWorkbenchCondition);
		}
	}

	/**
	 * @param mode
	 *            the mode to test
	 * @return whether the mode is recognized
	 * @since 3.0
	 */
	private boolean certifyMode(int mode) {
		switch (mode) {
		case VIEW_ACTIVATE:
		case VIEW_VISIBLE:
		case VIEW_CREATE:
			return true;
		default:
			return false;
		}
	}

	/**
	 * Hides the active fast view. Has no effect if there is no fast view
	 * active.
	 */
	public void hideFastView() {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			IViewReference ref = persp.getActiveFastView();
			if (ref != null) {
				toggleFastView(ref);
			}
		}
	}

	/**
	 * Toggles the visibility of a fast view. If the view is active it is
	 * deactivated. Otherwise, it is activated.
	 */
	public void toggleFastView(IViewReference ref) {

	}

	/**
	 * Sets the state of the given part.
	 * 
	 * @param ref
	 *            part whose state should be modified (not null)
	 * @param newState
	 *            one of the IStackPresentationSite.STATE_* constants
	 */
	public void setState(IWorkbenchPartReference ref, int newState) {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return;
		}

		PartPane pane = ((WorkbenchPartReference) ref).getPane();

		// If target part is detached fire the zoom event. Note this doesn't
		// actually cause any changes in size and is required to support
		// intro state changes. We may want to introduce the notion of a zoomed
		// (fullscreen) detached view at a later time.
		if (!pane.isDocked()) {
			pane.setZoomed(newState == IStackPresentationSite.STATE_MAXIMIZED);
			return;
		}

		if (ref instanceof IViewReference
				&& persp.isFastView((IViewReference) ref)) {
			persp.setFastViewState(newState);
			return;
		}

		if (Perspective.useNewMinMax(persp)) {
			// set the container's state to the new one
			PartStack parent = ((PartStack) pane.getContainer());
			parent.setState(newState);
			return;
		}

		boolean wasZoomed = isZoomed();
		boolean isZoomed = newState == IStackPresentationSite.STATE_MAXIMIZED;

		// Update zoom status.
		if (wasZoomed && !isZoomed) {
			zoomOut();
		} else if (!wasZoomed && isZoomed) {
			persp.getPresentation().zoomIn(ref);
			activate(ref.getPart(true));
		}

		PartStack parent = ((PartStack) pane.getContainer());

		if (parent != null) {
			parent
					.setMinimized(newState == IStackPresentationSite.STATE_MINIMIZED);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seeorg.eclipse.ui.IWorkbenchPage#setPartState(org.eclipse.ui.
	 * IWorkbenchPartReference, int)
	 */
	public void setPartState(IWorkbenchPartReference ref, int state) {
		setState(ref, state);
	}

	/**
	 * Returns the maximized/minimized/restored state of the given part
	 * reference
	 * 
	 * @param ref
	 *            part to query (not null)
	 * @return one of the IStackPresentationSite.STATE_* constants
	 */
	int getState(IWorkbenchPartReference ref) {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return IStackPresentationSite.STATE_RESTORED;
		}

		// TBD concept not yet implemented in E4
		if (!(ref instanceof WorkbenchPartReference))
			return IStackPresentationSite.STATE_RESTORED;

		PartPane pane = ((WorkbenchPartReference) ref).getPane();

		if (ref instanceof IViewReference
				&& persp.isFastView((IViewReference) ref)) {
			return persp.getFastViewState();
		}

		PartStack parent = ((PartStack) pane.getContainer());

		if (parent != null) {
			return parent.getState();
		}

		return IStackPresentationSite.STATE_RESTORED;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seeorg.eclipse.ui.IWorkbenchPage#getPartState(org.eclipse.ui.
	 * IWorkbenchPartReference)
	 */
	public int getPartState(IWorkbenchPartReference ref) {
		return getState(ref);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seeorg.eclipse.ui.IWorkbenchPage#toggleZoom(org.eclipse.ui.
	 * IWorkbenchPartReference)
	 */
	public void toggleZoom(IWorkbenchPartReference ref) {
		int oldState = getState(ref);
		boolean shouldZoom = oldState != IStackPresentationSite.STATE_MAXIMIZED;
		int newState = shouldZoom ? IStackPresentationSite.STATE_MAXIMIZED
				: IStackPresentationSite.STATE_RESTORED;

		setState(ref, newState);
	}

	/**
	 * updateActionBars method comment.
	 */
	public void updateActionBars() {
		window.updateActionBars();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#zoomOut()
	 */
	public void zoomOut() {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			persp.getPresentation().zoomOut();
		}
	}

	/**
	 * Zooms out a zoomed in part if it is necessary to do so for the user to
	 * view the IWorkbenchPart that is the argument. Otherwise, does nothing.
	 * 
	 * @param part
	 *            the part to be made viewable
	 */
	private void zoomOutIfNecessary(IWorkbenchPart part) {
		if (isZoomed()
				&& partChangeAffectsZoom(((PartSite) part.getSite())
						.getPartReference())) {
			zoomOut();
		}
	}

	/**
     * 
     */
	public int getEditorReuseThreshold() {
		return ((TabBehaviour) Tweaklets.get(TabBehaviour.KEY))
				.getEditorReuseThreshold();
	}

	/**
     * 
     */
	public void setEditorReuseThreshold(int openEditors) {
	}

	/*
	 * Returns the editors in activation order (oldest first).
	 */
	public IEditorReference[] getSortedEditors() {
		return getEditorReferences();
	}

	/**
	 * @see IWorkbenchPage#getOpenPerspectives()
	 */
	public IPerspectiveDescriptor[] getOpenPerspectives() {
		Perspective opened[] = perspList.getOpenedPerspectives();
		IPerspectiveDescriptor[] result = new IPerspectiveDescriptor[opened.length];
		for (int i = 0; i < result.length; i++) {
			result[i] = opened[i].getDesc();
		}
		return result;
	}

	/**
	 * Return all open Perspective objects.
	 * 
	 * @return all open Perspective objects
	 * @since 3.1
	 */
	/* package */Perspective[] getOpenInternalPerspectives() {
		return perspList.getOpenedPerspectives();
	}

	/**
	 * Checks perspectives in the order they were activiated for the specfied
	 * part. The first sorted perspective that contains the specified part is
	 * returned.
	 * 
	 * @param part
	 *            specified part to search for
	 * @return the first sorted perspespective containing the part
	 * @since 3.1
	 */
	/* package */Perspective getFirstPerspectiveWithView(IViewPart part) {
		Perspective[] perspectives = perspList.getSortedPerspectives();
		for (int i = perspectives.length - 1; i >= 0; i--) {
			if (perspectives[i].containsView(part)) {
				return perspectives[i];
			}
		}
		// we should never get here
		return null;
	}

	/**
	 * Returns the perspectives in activation order (oldest first).
	 */
	public IPerspectiveDescriptor[] getSortedPerspectives() {
		Perspective sortedArray[] = perspList.getSortedPerspectives();
		IPerspectiveDescriptor[] result = new IPerspectiveDescriptor[sortedArray.length];
		for (int i = 0; i < result.length; i++) {
			result[i] = sortedArray[i].getDesc();
		}
		return result;
	}

	/*
	 * Returns the parts in activation order (oldest first).
	 */
	public IWorkbenchPartReference[] getSortedParts() {
		return new IWorkbenchPartReference[0];
	}

	/**
	 * Returns the reference to the given part, or <code>null</code> if it has
	 * no reference (i.e. it is not a top-level part in this workbench page).
	 * 
	 * @param part
	 *            the part
	 * @return the part's reference or <code>null</code> if the given part does
	 *         not belong to this workbench page
	 */
	public IWorkbenchPartReference getReference(IWorkbenchPart part) {
		if (part == null) {
			return null;
		}
		IWorkbenchPartSite site = part.getSite();
		if (!(site instanceof PartSite)) {
			return null;
		}
		PartSite partSite = ((PartSite) site);
		PartPane pane = partSite.getPane();
		if (pane instanceof MultiEditorInnerPane) {
			MultiEditorInnerPane innerPane = (MultiEditorInnerPane) pane;
			return innerPane.getParentPane().getPartReference();
		}
		return partSite.getPartReference();
	}

	/**
	 * Helper class to keep track of all opened perspective. Both the opened and
	 * used order is kept.
	 */
	private class PerspectiveList {
		/**
		 * List of perspectives in the order they were opened;
		 */
		private List openedList;

		/**
		 * List of perspectives in the order they were used. Last element is the
		 * most recently used, and first element is the least recently used.
		 */
		private List usedList;

		/**
		 * The perspective explicitly set as being the active one
		 */
		private Perspective active;

		/**
		 * Creates an empty instance of the perspective list
		 */
		public PerspectiveList() {
			openedList = new ArrayList();
			usedList = new ArrayList();
		}

		/**
		 * Return all perspectives in the order they were activated.
		 * 
		 * @return an array of perspectives sorted by activation order, least
		 *         recently activated perspective last.
		 */
		public Perspective[] getSortedPerspectives() {
			Perspective[] result = new Perspective[usedList.size()];
			return (Perspective[]) usedList.toArray(result);
		}

		/**
		 * Adds a perspective to the list. No check is done for a duplicate when
		 * adding.
		 * 
		 * @param perspective
		 *            the perspective to add
		 * @return boolean <code>true</code> if the perspective was added
		 */
		public boolean add(Perspective perspective) {
			openedList.add(perspective);
			usedList.add(0, perspective);
			// It will be moved to top only when activated.
			return true;
		}

		/**
		 * Returns an iterator on the perspective list in the order they were
		 * opened.
		 */
		public Iterator iterator() {
			return openedList.iterator();
		}

		/**
		 * Returns an array with all opened perspectives
		 */
		public Perspective[] getOpenedPerspectives() {
			Perspective[] result = new Perspective[openedList.size()];
			return (Perspective[]) openedList.toArray(result);
		}

		/**
		 * Returns whether the list contains any perspectives
		 */
		public boolean isEmpty() {
			return openedList.isEmpty();
		}

		/**
		 * Returns the most recently used perspective in the list.
		 */
		public Perspective getActive() {
			return active;
		}

		/**
		 * Marks the specified perspective as the most recently used one in the
		 * list.
		 */
		public void setActive(Perspective perspective) {
			if (perspective == active) {
				return;
			}

			updateActionSets(active, perspective);
			active = perspective;

			if (perspective != null) {
				usedList.remove(perspective);
				usedList.add(perspective);
			}
		}

		private void updateActionSets(Perspective oldPersp, Perspective newPersp) {
			// Update action sets

			IContextService service = (IContextService) window
					.getService(IContextService.class);
			try {
				service.deferUpdates(true);
				if (newPersp != null) {
					IActionSetDescriptor[] newAlwaysOn = newPersp
							.getAlwaysOnActionSets();
					for (int i = 0; i < newAlwaysOn.length; i++) {
						IActionSetDescriptor descriptor = newAlwaysOn[i];

						actionSets.showAction(descriptor);
					}

					IActionSetDescriptor[] newAlwaysOff = newPersp
							.getAlwaysOffActionSets();
					for (int i = 0; i < newAlwaysOff.length; i++) {
						IActionSetDescriptor descriptor = newAlwaysOff[i];

						actionSets.maskAction(descriptor);
					}
				}

				if (oldPersp != null) {
					IActionSetDescriptor[] newAlwaysOn = oldPersp
							.getAlwaysOnActionSets();
					for (int i = 0; i < newAlwaysOn.length; i++) {
						IActionSetDescriptor descriptor = newAlwaysOn[i];

						actionSets.hideAction(descriptor);
					}

					IActionSetDescriptor[] newAlwaysOff = oldPersp
							.getAlwaysOffActionSets();
					for (int i = 0; i < newAlwaysOff.length; i++) {
						IActionSetDescriptor descriptor = newAlwaysOff[i];

						actionSets.unmaskAction(descriptor);
					}
				}
			} finally {
				service.deferUpdates(false);
			}
		}
	}

	// for dynamic UI
	protected void addPerspective(Perspective persp) {
		perspList.add(persp);
		window.firePerspectiveOpened(this, persp.getDesc());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#getViewStack(org.eclipse.ui.IViewPart)
	 */
	public IViewPart[] getViewStack(IViewPart part) {
		// check to make sure this part is in the current perspective
		MPart modelPart = findPartInCurrentPerspective(part.getSite().getId());
		if (modelPart == null) {
			// if not, return null
			return null;
		}

		List<IViewPart> stack = new ArrayList<IViewPart>();
		// retrieve the parent stack
		MElementContainer<MUIElement> viewStack = modelPart.getParent();
		// get the contents of the stack
		for (MUIElement child : viewStack.getChildren()) {
			if (child instanceof MContribution) {
				Object object = ((MContribution) child).getObject();
				// queue it up if it's a view
				if (object instanceof IViewPart) {
					stack.add((IViewPart) object);
				}
			}
		}
		return stack.toArray(new IViewPart[stack.size()]);
	}

	/**
	 * Allow for programmatically resizing a part.
	 * <p>
	 * <em>EXPERIMENTAL</em>
	 * </p>
	 * <p>
	 * Known limitations:
	 * <ul>
	 * <li>currently applies only to views</li>
	 * <li>has no effect when view is zoomed</li>
	 * </ul>
	 */
	public void resizeView(IViewPart part, int width, int height) {
		SashInfo sashInfo = new SashInfo();
		PartPane pane = ((PartSite) part.getSite()).getPane();
		ILayoutContainer container = pane.getContainer();
		LayoutTree tree = getPerspectivePresentation().getLayout().root
				.find(((ViewStack) container));

		// retrieve our layout sashes from the layout tree
		findSashParts(tree, pane.findSashes(), sashInfo);

		// first set the width
		float deltaWidth = width - pane.getBounds().width;
		if (sashInfo.right != null) {
			Rectangle rightBounds = sashInfo.rightNode.getBounds();
			// set the new ratio
			sashInfo.right
					.setRatio(((deltaWidth + sashInfo.right.getBounds().x) - rightBounds.x)
							/ rightBounds.width);
			// complete the resize
			sashInfo.rightNode.setBounds(rightBounds);
		} else if (sashInfo.left != null) {
			Rectangle leftBounds = sashInfo.leftNode.getBounds();
			// set the ratio
			sashInfo.left
					.setRatio(((sashInfo.left.getBounds().x - deltaWidth) - leftBounds.x)
							/ leftBounds.width);
			// complete the resize
			sashInfo.leftNode.setBounds(sashInfo.leftNode.getBounds());
		}

		// next set the height
		float deltaHeight = height - pane.getBounds().height;
		if (sashInfo.bottom != null) {
			Rectangle bottomBounds = sashInfo.bottomNode.getBounds();
			// set the new ratio
			sashInfo.bottom.setRatio(((deltaHeight + sashInfo.bottom
					.getBounds().y) - bottomBounds.y)
					/ bottomBounds.height);
			// complete the resize
			sashInfo.bottomNode.setBounds(bottomBounds);
		} else if (sashInfo.top != null) {
			Rectangle topBounds = sashInfo.topNode.getBounds();
			// set the ratio
			sashInfo.top
					.setRatio(((sashInfo.top.getBounds().y - deltaHeight) - topBounds.y)
							/ topBounds.height);
			// complete the resize
			sashInfo.topNode.setBounds(topBounds);
		}

	}

	// provides sash information for the given pane
	private class SashInfo {
		private LayoutPartSash right;

		private LayoutPartSash left;

		private LayoutPartSash top;

		private LayoutPartSash bottom;

		private LayoutTreeNode rightNode;

		private LayoutTreeNode leftNode;

		private LayoutTreeNode topNode;

		private LayoutTreeNode bottomNode;
	}

	private void findSashParts(LayoutTree tree, PartPane.Sashes sashes,
			SashInfo info) {
		LayoutTree parent = tree.getParent();
		if (parent == null) {
			return;
		}

		if (parent.part instanceof LayoutPartSash) {
			// get the layout part sash from this tree node
			LayoutPartSash sash = (LayoutPartSash) parent.part;
			// make sure it has a sash control
			Control control = sash.getControl();
			if (control != null) {
				// check for a vertical sash
				if (sash.isVertical()) {
					if (sashes.left == control) {
						info.left = sash;
						info.leftNode = parent.findSash(sash);
					} else if (sashes.right == control) {
						info.right = sash;
						info.rightNode = parent.findSash(sash);
					}
				}
				// check for a horizontal sash
				else {
					if (sashes.top == control) {
						info.top = sash;
						info.topNode = parent.findSash(sash);
					} else if (sashes.bottom == control) {
						info.bottom = sash;
						info.bottomNode = parent.findSash(sash);
					}
				}
			}
		}
		// recursive call to continue up the tree
		findSashParts(parent, sashes, info);
	}

	/**
	 * Returns all parts that are owned by this page
	 * 
	 * @return all open parts, including non-participating editors.
	 */
	IWorkbenchPartReference[] getAllParts() {
		ArrayList<IWorkbenchPartReference> result = new ArrayList<IWorkbenchPartReference>();
		getContainedPartRefs(result, e4Window);
		IWorkbenchPartReference[] typedResult = new IWorkbenchPartReference[result
				.size()];
		result.toArray(typedResult);
		return typedResult;
	}

	// TBD this code repeats multiple times in variations (get editors, get
	// views, get parts). When typically callers filter them some more (isDirty,
	// isVisble, etc.).
	// This needs to be a generic utility
	private void getContainedPartRefs(
			ArrayList<IWorkbenchPartReference> result,
			MElementContainer<?> container) {
		for (MUIElement child : container.getChildren()) {
			if (child instanceof MPart) {
				MPart contributedChild = (MPart) child;
				if (contributedChild.isVisible()) {
					Object object = contributedChild.getObject();
					if (object instanceof IWorkbenchPart)
						result.add(new ModelReference(contributedChild, this));
				}
			}
			if (child instanceof MElementContainer<?>)
				getContainedPartRefs(result, (MElementContainer<?>) child);
		}
	}

	/**
	 * Returns all open parts that are owned by this page (that is, all parts
	 * for which a part opened event would have been sent -- these would be
	 * activated parts whose controls have already been created.
	 */
	IWorkbenchPartReference[] getOpenParts() {
		IWorkbenchPartReference[] refs = getAllParts();
		List result = new ArrayList();

		for (int i = 0; i < refs.length; i++) {
			IWorkbenchPartReference reference = refs[i];

			IWorkbenchPart part = reference.getPart(false);
			if (part != null) {
				result.add(reference);
			}
		}

		return (IWorkbenchPartReference[]) result
				.toArray(new IWorkbenchPartReference[result.size()]);
	}

	/**
	 * Sanity-checks the objects in this page. Throws an Assertation exception
	 * if an object's internal state is invalid. ONLY INTENDED FOR USE IN THE UI
	 * TEST SUITES.
	 */
	public void testInvariants() {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#getExtensionTracker()
	 */
	public IExtensionTracker getExtensionTracker() {
		if (tracker == null) {
			tracker = new UIExtensionTracker(getWorkbenchWindow()
					.getWorkbench().getDisplay());
		}
		return tracker;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#getNewWizardShortcuts()
	 */
	public String[] getNewWizardShortcuts() {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return new String[0];
		}
		return persp.getNewWizardShortcuts();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#getPerspectiveShortcuts()
	 */
	public String[] getPerspectiveShortcuts() {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return new String[0];
		}
		return persp.getPerspectiveShortcuts();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPage#getShowViewShortcuts()
	 */
	public String[] getShowViewShortcuts() {
		Perspective persp = getActivePerspective();
		if (persp == null) {
			return new String[0];
		}
		return persp.getShowViewShortcuts();
	}

	/**
	 * @since 3.1
	 */
	private void suggestReset() {
		final IWorkbench workbench = getWorkbenchWindow().getWorkbench();
		workbench.getDisplay().asyncExec(new Runnable() {
			public void run() {
				Shell parentShell = null;

				IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
				if (window == null) {
					if (workbench.getWorkbenchWindowCount() == 0) {
						return;
					}
					window = workbench.getWorkbenchWindows()[0];
				}

				parentShell = window.getShell();

				if (MessageDialog.openQuestion(parentShell,
						WorkbenchMessages.Dynamic_resetPerspectiveTitle,
						WorkbenchMessages.Dynamic_resetPerspectiveMessage)) {
					IWorkbenchPage page = window.getActivePage();
					if (page == null) {
						return;
					}
					page.resetPerspective();
				}
			}
		});

	}

	public boolean isPartVisible(IWorkbenchPartReference reference) {
		IWorkbenchPart part = reference.getPart(false);
		// Can't be visible if it isn't created yet
		if (part == null) {
			return false;
		}

		return isPartVisible(part);
	}

	public IWorkingSet[] getWorkingSets() {
		return workingSets;
	}

	public void setWorkingSets(IWorkingSet[] newWorkingSets) {
		if (newWorkingSets != null) {
			WorkbenchPlugin
					.getDefault()
					.getWorkingSetManager()
					.addPropertyChangeListener(workingSetPropertyChangeListener);
		} else {
			WorkbenchPlugin.getDefault().getWorkingSetManager()
					.removePropertyChangeListener(
							workingSetPropertyChangeListener);
		}

		if (newWorkingSets == null) {
			newWorkingSets = new IWorkingSet[0];
		}

		IWorkingSet[] oldWorkingSets = workingSets;

		// filter out any duplicates if necessary
		if (newWorkingSets.length > 1) {
			Set setOfSets = new HashSet();
			for (int i = 0; i < newWorkingSets.length; i++) {
				if (newWorkingSets[i] == null) {
					throw new IllegalArgumentException();
				}
				setOfSets.add(newWorkingSets[i]);
			}
			newWorkingSets = (IWorkingSet[]) setOfSets
					.toArray(new IWorkingSet[setOfSets.size()]);
		}

		workingSets = newWorkingSets;
		if (!Arrays.equals(oldWorkingSets, newWorkingSets)) {
			firePropertyChange(CHANGE_WORKING_SETS_REPLACE, oldWorkingSets,
					newWorkingSets);
			if (aggregateWorkingSet != null) {
				aggregateWorkingSet.setComponents(workingSets);
			}
		}
	}

	public IWorkingSet getAggregateWorkingSet() {
		if (aggregateWorkingSet == null) {
			IWorkingSetManager workingSetManager = PlatformUI.getWorkbench()
					.getWorkingSetManager();
			aggregateWorkingSet = (AggregateWorkingSet) workingSetManager
					.getWorkingSet(getAggregateWorkingSetId());
			if (aggregateWorkingSet == null) {
				aggregateWorkingSet = (AggregateWorkingSet) workingSetManager
						.createAggregateWorkingSet(
								getAggregateWorkingSetId(),
								WorkbenchMessages.WorkbenchPage_workingSet_default_label,
								getWorkingSets());
				workingSetManager.addWorkingSet(aggregateWorkingSet);
			}
		}
		return aggregateWorkingSet;
	}

	private String getAggregateWorkingSetId() {
		if (aggregateWorkingSetId == null) {
			aggregateWorkingSetId = "Aggregate for window " + System.currentTimeMillis(); //$NON-NLS-1$
		}
		return aggregateWorkingSetId;
	}

	public void showEditor(IEditorReference ref) {
	}

	public void hideEditor(IEditorReference ref) {
		// partList.removePart((WorkbenchPartReference)ref);
	}

	public IEditorReference[] openEditors(final IEditorInput[] inputs,
			final String[] editorIDs, final int matchFlags)
			throws MultiPartInitException {
		if (inputs == null)
			throw new IllegalArgumentException();
		if (editorIDs == null)
			throw new IllegalArgumentException();
		if (inputs.length != editorIDs.length)
			throw new IllegalArgumentException();

		ArrayList refs = new ArrayList();

		for (int i = 0; i < inputs.length; i++) {
			IEditorPart ed = null;
			try {
				// brute force approach
				ed = openEditor(inputs[i], editorIDs[i], true, matchFlags);
			} catch (PartInitException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (ed != null) {
				refs.add(((PartSite) ed.getSite()).getPartReference());
			}
		}

		return (IEditorReference[]) refs.toArray(new IEditorReference[refs
				.size()]);
	}

	public void resetHiddenEditors() {
		IEditorReference[] refs = (IEditorReference[]) removedEditors
				.toArray(new IEditorReference[removedEditors.size()]);
		for (int i = 0; i < refs.length; i++) {
			showEditor(refs[i]);
		}
	}

	public MWindow getModelWindow() {
		return e4Window;
	}

	// TBD this code repeats multiple times in variations (get editors, get
	// views, get parts). When typically callers filter them some more (isDirty,
	// isVisble, etc.).
	// This needs to be a generic utility
	private MPerspective findPerspectiveE4(MWindow e4Window, String id) {
		MUIElement pe = ModeledPageLayout.findElementById(e4Window, id);
		if (pe instanceof MPerspective)
			return (MPerspective) pe;
		return null;
	}
}
