/*******************************************************************************
 * 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.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.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.e4.core.services.context.IEclipseContext;
import org.eclipse.e4.ui.model.application.ApplicationFactory;
import org.eclipse.e4.ui.model.application.MContributedPart;
import org.eclipse.e4.ui.model.application.MPart;
import org.eclipse.e4.ui.model.application.MWindow;
import org.eclipse.e4.ui.model.workbench.MPerspective;
import org.eclipse.e4.workbench.ui.api.ModeledPageLayout;
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.osgi.util.NLS;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.Rectangle;
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.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.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.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$

	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 (!certifyPart(part)) {
			return;
		}

		if (window.isClosing()) {
			return;
		}

		if (composite != null
				&& composite.isVisible()
				&& !((GrabFocus) Tweaklets.get(GrabFocus.KEY))
						.grabFocusAllowed(part)) {
			return;
		}
	}

	/**
	 * 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;
		}
	}

	/**
	 * 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((WorkbenchPartReference) ref);
		}

		// 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) {
	}

	/**
	 * 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) {
	}

	/**
	 * 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(WorkbenchPartReference ref) {
		disposePart(ref);
	}

	private void disposePart(WorkbenchPartReference ref) {
		partList.removePart(ref);
		ref.dispose();

	}

	/**
	 * 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() {
		return true;
	}

	/**
	 * 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) {
		// TODO search the model for the view and return a "ref"
		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() {

		return new IActionSetDescriptor[0];
	}

	/**
	 * @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) {
		return null;
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IEditorReference[] findEditors(IEditorInput input, String editorId,
			int matchFlags) {
		return new IEditorReference[0];
	}

	/**
	 * See IWorkbenchPage.
	 */
	public IEditorReference[] getEditorReferences() {
		return new IEditorReference[0];
	}

	/**
	 * 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);

		// 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);
		}

	}

	/**
	 * 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);
			}
		}
	}

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

	/**
	 * 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();
		}

		MPerspective<?> curPersp = (MPerspective<?>) e4Window.getActiveChild();
		MPart ea = ModeledPageLayout.findPart(curPersp, ModeledPageLayout
				.internalGetEditorArea());
		MContributedPart<MPart<?>> editorPart = findEditor(ea, editorID, input);
		if (editorPart == null) {
			editorPart = ApplicationFactory.eINSTANCE.createMContributedPart();
			editorPart.setId(editorID);
			editorPart.setName(input.getName());
			ea.getChildren().add(editorPart);
			editorPart.getContext().set(IEditorInput.class.getName(), input);
		}
		ea.setActiveChild(editorPart);
		return (IEditorPart) editorPart.getObject();
	}

	/**
	 * @param ea
	 * @param editorID
	 * @param input2
	 * @return
	 */
	private MContributedPart<MPart<?>> findEditor(MPart ea, String editorID,
			IEditorInput input) {
		final Iterator i = ea.getChildren().iterator();
		while (i.hasNext()) {
			MContributedPart<MPart<?>> part = (MContributedPart<MPart<?>>) i
					.next();
			if (editorID.equals(part.getId())) {
				IEditorInput e = (IEditorInput) part.getContext().get(
						IEditorInput.class.getName());
				if (input.equals(e)) {
					return part;
				}
			}
		}
		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) {
		WorkbenchPartReference ref = (WorkbenchPartReference) getReference(editor);
		return ref != null && ref.isPinned();
	}

	/**
	 * 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) {
		return true;
	}

	/*
	 * Saves the workbench part.
	 */
	protected boolean savePart(ISaveablePart saveable, IWorkbenchPart part,
			boolean confirm) {
		// Do not certify part do allow editors inside a multipageeditor to
		// call this.
		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) {
		if (Util.equals(getPerspective(), desc)) {
			return;
		}

	}

	/**
	 * 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;
		}

		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) {
		return null;
	}

	/**
	 * 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 allParts = new ArrayList();

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

	/**
	 * 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();

		final IEditorReference[] results = new IEditorReference[inputs.length];
		return results;
	}

	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;
	}
}
