/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.ui.internal;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.CoolBarManager;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.ListenerList;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
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.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IEditorRegistry;
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.IPerspectiveRegistry;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.ISaveablePart;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.SubActionBars;
import org.eclipse.ui.WorkbenchException; 
import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
import org.eclipse.ui.internal.misc.UIStats;
import org.eclipse.ui.internal.registry.IActionSetDescriptor;
import org.eclipse.ui.internal.registry.IStickyViewDescriptor;
import org.eclipse.ui.internal.registry.IViewRegistry;
import org.eclipse.ui.internal.registry.PerspectiveDescriptor;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.part.MultiEditor;

/**
 * A collection of views and editors in a workbench.
 */
public class WorkbenchPage extends CompatibleWorkbenchPage implements IWorkbenchPage {
	private WorkbenchWindow window;
	private IAdaptable input;
	private IWorkingSet workingSet;
	private Composite composite;
	private ControlListener resizeListener;
	private IWorkbenchPart activePart;
	//Could be delete. This information is in the active part list;
	private ActivationList activationList = new ActivationList();
	private IEditorPart lastActiveEditor;
	private EditorManager editorMgr;
	private EditorAreaHelper editorPresentation;
	private PartListenerList partListeners = new PartListenerList();
	private PartListenerList2 partListeners2 = new PartListenerList2();
	private ListenerList propertyChangeListeners = new ListenerList();
	private PageSelectionService selectionService =
		new PageSelectionService(this);
	private IActionBars actionBars;
	private ViewFactory viewFactory;
	private PerspectiveList perspList = new PerspectiveList();
	private PerspectiveDescriptor deferredActivePersp;
	private NavigationHistory navigationHistory = new NavigationHistory(this);
	//for dynamic UI - saving state for editors, views and perspectives
	private HashMap stateMap = new HashMap();
	private IPropertyChangeListener propertyChangeListener =
		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)
				&& event.getOldValue().equals(workingSet)) {
				setWorkingSet(null);
			} else if (LayoutPart.PROP_VISIBILITY.equals(property)) {
				WorkbenchPartReference ref =
					(WorkbenchPartReference) ((PartPane) event.getSource())
						.getPartReference();
				//Make sure the new visible part is restored.
				ref.getPart(Boolean.TRUE.equals(event.getNewValue()));
				if (ref == null)
					return;
				if (Boolean.TRUE.equals(event.getNewValue())) {
					String label = "visible::" + ref.getTitle(); //$NON-NLS-1$
					try {
						UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
						partListeners2.firePartVisible(ref);
					} finally {
						UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
					}
				} else {
					String label = "hidden::" + ref.getTitle(); //$NON-NLS-1$
					try {
						UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
						partListeners2.firePartHidden(ref);
					} finally {
						UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
					}
				}
			}
		}
	};
	
	// a set of perspectives in which sticky views have already been created.
	private Set stickyPerspectives = new HashSet(7);
	
	private ActionSwitcher actionSwitcher = new ActionSwitcher();
	/**
	 * Manages editor contributions and action set part associations.
	 */
	private class ActionSwitcher {
		private IWorkbenchPart activePart;
		private IEditorPart topEditor;
		private ArrayList actionSets = new ArrayList();

		/**
		 * Updates the contributions given the new part as the active part.
		 * 
		 * @param newPart
		 *            the new active part, may be <code>null</code>
		 */
		public void updateActivePart(IWorkbenchPart newPart) {
			if (activePart == newPart)
				return;

			boolean isNewPartAnEditor = newPart instanceof IEditorPart;
			if (isNewPartAnEditor) {
				String oldId = null;
				if (topEditor != null)
					oldId = topEditor.getSite().getId();
				String newId = newPart.getSite().getId();

				// if the active part is an editor and the new editor
				// is the same kind of editor, then we don't have to do
				// anything
				if (activePart == topEditor && newId.equals(oldId))
					return;

				// remove the contributions of the old editor
				// if it is a different kind of editor
				if (oldId != null && !oldId.equals(newId))
					deactivateContributions(topEditor, true);

				// if a view was the active part, disable its contributions
				if (activePart != null && activePart != topEditor)
					deactivateContributions(activePart, true);

				// show (and enable) the contributions of the new editor
				// if it is a different kind of editor or if the
				// old active part was a view
				if (!newId.equals(oldId) || activePart != topEditor)
					activateContributions(newPart, true);

			} else if (newPart == null) {
				if (activePart != null)
					// remove all contributions
					deactivateContributions(activePart, true);
			} else {
				// new part is a view

				// if old active part is a view, remove all contributions,
				// but if old part is an editor only disable
				if (activePart != null)
					deactivateContributions(
						activePart,
						activePart instanceof IViewPart);

				activateContributions(newPart, true);
			}

			ArrayList newActionSets = null;
			if (isNewPartAnEditor
				|| (activePart == topEditor && newPart == null))
				newActionSets = calculateActionSets(newPart, null);
			else
				newActionSets = calculateActionSets(newPart, topEditor);

			if (!updateActionSets(newActionSets))
				updateActionBars();

			if (isNewPartAnEditor) {
				topEditor = (IEditorPart) newPart;
			} else if (activePart == topEditor && newPart == null) {
				// since we removed all the contributions, we clear the top
				// editor
				topEditor = null;
			}

			activePart = newPart;
		}

		/**
		 * Updates the contributions given the new part as the topEditor.
		 * 
		 * @param newEditor
		 *            the new top editor, may be <code>null</code>
		 */
		public void updateTopEditor(IEditorPart newEditor) {
			if (topEditor == newEditor)
				return;

			String oldId = null;
			if (topEditor != null)
				oldId = topEditor.getSite().getId();
			String newId = null;
			if (newEditor != null)
				newId = newEditor.getSite().getId();
			if (oldId == null ? newId == null : oldId.equals(newId)) {
				// we don't have to change anything
				topEditor = newEditor;
				return;
			}

			// Remove the contributions of the old editor
			if (topEditor != null)
				deactivateContributions(topEditor, true);

			// Show (disabled) the contributions of the new editor
			if (newEditor != null)
				activateContributions(newEditor, false);

			ArrayList newActionSets =
				calculateActionSets(activePart, newEditor);
			if (!updateActionSets(newActionSets))
				updateActionBars();

			topEditor = newEditor;
		}

		/**
		 * Activates the contributions of the given part. If <code>enable</code>
		 * is <code>true</code> the contributions are visible and enabled,
		 * otherwise they are disabled.
		 * 
		 * @param part
		 *            the part whose contributions are to be activated
		 * @param enable
		 *            <code>true</code> the contributions are to be enabled,
		 *            not just visible.
		 */
		private void activateContributions(
			IWorkbenchPart part,
			boolean enable) {
			PartSite site = (PartSite) part.getSite();
			SubActionBars actionBars = (SubActionBars) site.getActionBars();
			actionBars.activate(enable);
		}

		/**
		 * Deactivates the contributions of the given part. If <code>remove</code>
		 * is <code>true</code> the contributions are removed, otherwise they
		 * are disabled.
		 * 
		 * @param part
		 *            the part whose contributions are to be deactivated
		 * @param remove
		 *            <code>true</code> the contributions are to be removed,
		 *            not just disabled.
		 */
		private void deactivateContributions(
			IWorkbenchPart part,
			boolean remove) {
			PartSite site = (PartSite) part.getSite();
			SubActionBars actionBars = (SubActionBars) site.getActionBars();
			actionBars.deactivate(remove);
		}

		/**
		 * Calculates the action sets to show for the given part and editor
		 * 
		 * @param part
		 *            the active part, may be <code>null</code>
		 * @param editor
		 *            the current editor, may be <code>null</code>, may be
		 *            the active part
		 * @return the new action sets
		 */
		private ArrayList calculateActionSets(
			IWorkbenchPart part,
			IEditorPart editor) {
			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]);
				}
			}
			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]);
				}
			}
			return newActionSets;
		}

		/**
		 * Updates the actions we are showing for the active part and current
		 * editor.
		 * 
		 * @param newActionSets
		 *            the action sets to show
		 * @return <code>true</code> if the action sets changed
		 */
		private boolean updateActionSets(ArrayList newActionSets) {
			if (actionSets.equals(newActionSets))
				return false;

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

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

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

			actionSets = newActionSets;

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

	}

	/**
	 * 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
	 */
	public WorkbenchPage(WorkbenchWindow w, String layoutID, IAdaptable input)
		throws WorkbenchException {
		super();
		if (layoutID == null)
			throw new WorkbenchException(WorkbenchMessages.getString("WorkbenchPage.UndefinedPerspective")); //$NON-NLS-1$
		init(w, layoutID, input);
	}
	/**
	 * 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
	 */
	public WorkbenchPage(WorkbenchWindow w, IAdaptable input)
		throws WorkbenchException {
		super();
		init(w, null, input);
	}

	/**
	 * 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 zoomed, unzoom.
		if (isZoomed() && partChangeAffectsZoom(getReference(part)))
			zoomOut();

		if (part instanceof MultiEditor) {
			part = ((MultiEditor) part).getActiveEditor();
		}
		// Activate part.
		if (window.getActivePage() == this) {
			bringToTop(part);
			setActivePart(part);
		} else {
			activationList.setActive(part);
			activePart = part;
		}
	}

	/**
	 * Activates a part. The part is given focus, the pane is hilighted.
	 */
	private void activatePart(final IWorkbenchPart part) {
		Platform.run(new SafeRunnable(WorkbenchMessages.getString("WorkbenchPage.ErrorActivatingView")) { //$NON-NLS-1$
			public void run() {
				if (part != null) {
					part.setFocus();
					PartSite site = (PartSite) part.getSite();
					site.getPane().showFocus(true);
					updateTabList(part);
					SubActionBars bars = (SubActionBars) site.getActionBars();
					bars.partChanged(part);
				}
			}
		});
	}
	/**
	 * Add a fast view.
	 */
	public void addFastView(IViewReference ref) {
		Perspective persp = getActivePerspective();
		if (persp == null)
			return;

		// If view is zoomed unzoom.
		if (isZoomed() && partChangeAffectsZoom(ref))
			zoomOut();

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

		// The view is now invisible.
		// If it is active then deactivate it.
		if (ref.getPart(false) == activePart) {
			activate(activationList.getActive());
		}

		// Notify listeners.
		window.updateFastViewBar();
		window.firePerspectiveChanged(
			this,
			getPerspective(),
			CHANGE_FAST_VIEW_ADD);
	}
	/**
	 * Adds an IPartListener to the part service.
	 */
	public void addPartListener(IPartListener l) {
		partListeners.addPartListener(l);
	}
	/**
	 * Adds an IPartListener to the part service.
	 */
	public void addPartListener(IPartListener2 l) {
		partListeners2.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.
	 * 
	 * @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 zoomed then ignore.
		if (isZoomed() && partChangeAffectsZoom(getReference(part)))
			return;

		String label = part != null ? part.getTitle() : "none"; //$NON-NLS-1$
		boolean broughtToTop = false;
		try {
			UIStats.start(UIStats.BRING_PART_TO_TOP, label);
			// Move part.
			if (part instanceof IEditorPart) {
				IEditorReference ref = (IEditorReference) getReference(part);
				broughtToTop = getEditorManager().setVisibleEditor(ref, false);
				actionSwitcher.updateTopEditor((IEditorPart) part);
				if (broughtToTop) {
					lastActiveEditor = null;
				}
			} else if (part instanceof IViewPart) {
				IViewReference ref = (IViewReference) getReference(part);
				broughtToTop = persp.bringToTop(ref);
			}

			if (broughtToTop) {
				// Need to make sure that the part lists are sorted correctly.
				activationList.setActive(part);
				firePartBroughtToTop(part);
			}
		} finally {
			UIStats.end(UIStats.BRING_PART_TO_TOP, label);
		}
	}
	/**
	 * Resets the layout for the perspective. The active part in the old layout
	 * is activated in the new layout for consistent user context.
	 * 
	 * Assumes the busy cursor is active.
	 */
	private void busyResetPerspective() {

	    ViewIntroAdapterPart introViewAdapter = ((WorkbenchIntroManager)getWorkbenchWindow().getWorkbench().getIntroManager()).getViewIntroAdapterPart();
	    PartPane introPane = null;
	    boolean introFullScreen = false;
	    if (introViewAdapter != null) {
	        introPane = ((PartSite)introViewAdapter.getSite()).getPane();
	        introViewAdapter.setHandleZoomEvents(false);
	        introFullScreen = introPane.isZoomed();
	    }
	    
	    //try to prevent intro flicker.
	    if (introFullScreen)
	        window.getShell().setRedraw(false);
	    
	    try {
	        
			// Always unzoom
			if (isZoomed())
				zoomOut();
	
			// Get the current perspective.
			// This describes the working layout of the page and differs from
			// the original template.
			Perspective oldPersp = getActivePerspective();
	
			// Map the current perspective to the original template.
			// If the original template cannot be found then it has been deleted.
			// In
			// that case just return. (PR#1GDSABU).
			IPerspectiveRegistry reg =
				WorkbenchPlugin.getDefault().getPerspectiveRegistry();
			PerspectiveDescriptor desc =
				(PerspectiveDescriptor) reg.findPerspectiveWithId(
					oldPersp.getDesc().getId());
			if (desc == null)
				desc =
					(PerspectiveDescriptor) reg.findPerspectiveWithId(
						((PerspectiveDescriptor) oldPersp.getDesc())
							.getOriginalId());
			if (desc == null)
				return;
	
			IContributionItem item =
				window.findPerspectiveShortcut(oldPersp.getDesc(), this);
			if (item == null)
				return;
	
			// Notify listeners that we are doing a reset.
			window.firePerspectiveChanged(this, desc, CHANGE_RESET);
	
			// Create new persp from original template.
			Perspective newPersp = createPerspective(desc);
			if (newPersp == null) {
				// We're not going through with the reset, so it is complete.
				window.firePerspectiveChanged(this, desc, CHANGE_RESET_COMPLETE);
				return;
			}
	
			// Update the perspective list and shortcut
			perspList.swap(oldPersp, newPersp);
	
			((PerspectiveBarContributionItem) item).setPerspective(newPersp.getDesc());
	
			// Install new persp.
			setPerspective(newPersp);
	
			// Destroy old persp.
			disposePerspective(oldPersp);
	
			// Update the Coolbar layout.
			resetToolBarLayout();
			
			// restore the maximized intro
			if (introViewAdapter != null) {
			    if (introFullScreen) 		    
				    toggleZoom(introPane.getPartReference());
			    // we want the intro back to a normal state before we fire the event
			    introViewAdapter.setHandleZoomEvents(true);
			}
			// Notify listeners that we have completed our reset.
			window.firePerspectiveChanged(this, desc, CHANGE_RESET_COMPLETE);
	    }
	    finally {
	        // reset the handling of zoom events (possibly for the second time) in case there was 
	        // an exception thrown
	        if (introViewAdapter != null)
	            introViewAdapter.setHandleZoomEvents(true);

	        if (introFullScreen)
	            window.getShell().setRedraw(true);
	    }
		
	}
	/**
	 * Implements <code>setPerspective</code>.
	 * 
	 * Assumes that busy cursor is active.
	 * 
	 * @param persp
	 *            identifies the new perspective.
	 */
	private void busySetPerspective(IPerspectiveDescriptor desc) {
		// Create new layout.
		String label = desc.getId();
		try {
			UIStats.start(UIStats.SWITCH_PERSPECTIVE, label);
			PerspectiveDescriptor realDesc = (PerspectiveDescriptor) desc;
			Perspective newPersp = findPerspective(realDesc);
			if (newPersp == null) {
				newPersp = createPerspective(realDesc);
				if (newPersp == null)
					return;
				window.addPerspectiveShortcut(realDesc, this);
			}

			// Change layout.
			setPerspective(newPersp);
		} finally {
			UIStats.end(UIStats.SWITCH_PERSPECTIVE, label);
		}
	}
	/**
	 * Shows a view.
	 * 
	 * Assumes that a busy cursor is active.
	 */
	private 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) {
			if (mode == VIEW_ACTIVATE)			
				activate(view);
			else if (mode == VIEW_VISIBLE)
				bringToTop(view);
			return view;
		}

		// Show the view.
		view = persp.showView(viewID, secondaryID);
		if (view != null) {
			zoomOutIfNecessary(view);
			if (mode == VIEW_ACTIVATE)			
				activate(view);
			else if (mode == VIEW_VISIBLE)
				bringToTop(view);
			window.firePerspectiveChanged(
				this,
				getPerspective(),
				CHANGE_VIEW_SHOW);
			// Just in case view was fast.
			window.updateFastViewBar();
		}
		return view;
	}
	/**
	 * 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;

		if (part instanceof IEditorPart) {
			IEditorReference ref = (IEditorReference) getReference(part);
			return getEditorManager().containsEditor(ref);
		}
		if (part instanceof IViewPart) {
			Perspective persp = getActivePerspective();
			return persp != null && persp.containsView((IViewPart) part);
		}
		return false;
	}
	/**
	 * 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[] editorRefs, boolean save) {
		if (save) {
			// Intersect the dirty editors with the editors that are closing
			IEditorPart[] dirty = getDirtyEditors();
			List intersect = new ArrayList();
			for (int i = 0; i < editorRefs.length; i++) {
				IEditorReference reference = editorRefs[i];
				IEditorPart refPart = reference.getEditor(false);
				if (refPart != null) {
					for (int j = 0; j < dirty.length; j++) {
						if (refPart.equals(dirty[j])) {
							intersect.add(refPart);
							break;
						}
					}
				}
			}
			// Save parts, exit the method if cancel is pressed.
			if (intersect.size() > 0) {
				if (!EditorManager.saveAll(intersect, true, getWorkbenchWindow()))
					return false;
			}
		}
		
		// If the user has not cancelled a possible save request 
		// and if part is added or removed always unzoom.
		if (isZoomed())
			zoomOut();


		// Deactivate part if the active part is being closed.
		boolean deactivated = false;
		for (int i=0 ; i < editorRefs.length ; i++) {
			IWorkbenchPart part = editorRefs[i].getPart(false);
			if (part == activePart) {
				deactivated = true;
				setActivePart(null);
			}
			if (lastActiveEditor == part) {
				lastActiveEditor = null;
				actionSwitcher.updateTopEditor(null);
			}
		}
		
		// Close all editors.
		for (int i = 0; i < editorRefs.length; i++) {
			IEditorReference ref = editorRefs[i];
			getEditorManager().closeEditor(ref);
			activationList.remove(ref);
			firePartClosed(ref);
			disposePart(ref);
		}

		if (!window.isClosing() && deactivated) {
			activate(activationList.getActive());
		}

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

		// Return true on success.
		return true;
	}
	
	/**
	 * See IWorkbenchPage#closeEditor
	 */
	public boolean closeEditor(IEditorReference editorRef, boolean save) {
		IEditorPart editor = editorRef.getEditor(false);
		if (editor != null)
			return closeEditor(editor, save);
		getEditorManager().closeEditor(editorRef);
		activationList.remove(editorRef);
		firePartClosed(editorRef);
		return true;
	}
	/**
	 * See IWorkbenchPage#closeEditor
	 */
	public boolean closeEditor(IEditorPart editor, boolean save) {
		// Sanity check.
		if (!certifyPart(editor))
			return false;

		// Save part.
		if (save && !getEditorManager().saveEditor(editor, true))
			return false;

		boolean partWasVisible = (editor == getActiveEditor());
		IEditorReference ref = (IEditorReference) getReference(editor);
		activationList.remove(ref);
		boolean partWasActive = (editor == activePart);

		// Removing following lines to fix:
		// http://dev.eclipse.org/bugs/show_bug.cgi?id=28031
		//	// Deactivate part.
		//	if (partWasActive)
		//		setActivePart(null);
		//	if (lastActiveEditor == editor) {
		//		actionSwitcher.updateTopEditor(null);
		//		lastActiveEditor = null;
		//	}

		// Close the part.
		getEditorManager().closeEditor(ref);
		firePartClosed(ref);
		disposePart(ref);
		// Notify interested listeners
		window.firePerspectiveChanged(
			this,
			getPerspective(),
			CHANGE_EDITOR_CLOSE);

		// Activate new part.
		if (partWasActive) {
			IWorkbenchPart top = activationList.getTopEditor();
			zoomOutIfNecessary(top);
			if (top == null) {
				// Fix for bug #31122 (side effect from fix 28031 above)
				actionSwitcher.updateTopEditor(null);
				if (lastActiveEditor == editor)
					lastActiveEditor = null;
				// End - Fix for bug #31122
				top = activationList.getActive();
			}
			if (top != null)
				activate(top);
			else
				setActivePart(null);
		} else if (partWasVisible) {
			IEditorPart top = activationList.getTopEditor();
			zoomOutIfNecessary(top);

			// The editor we are bringing to top may already the visible
			// editor (due to editor manager behavior when it closes and
			// editor).
			// If this is the case, bringToTop will not call
			// firePartBroughtToTop.
			// We must fire it from here.
			if (top != null) {
				boolean isTop = editorMgr.getVisibleEditor() == top;
				bringToTop(top);
				if (isTop)
					firePartBroughtToTop(top);
			} else
				actionSwitcher.updateTopEditor(top);
		}

		// Return true on success.
		return true;
	}
	/**
	 * Closes the specified perspective. If last perspective, then entire page
	 * is closed.
	 * 
	 * @param desc
	 *            the descriptor of the perspective to be closed
	 * @param save
	 *            whether the page's editors should be save if last perspective
	 */
	/* package */
	void closePerspective(IPerspectiveDescriptor desc, boolean save) {
		Perspective persp = findPerspective(desc);
		if (persp != null)
			closePerspective(persp, save, true);
	}

	/**
	 * Closes the specified perspective. If last perspective, then entire page
	 * is closed.
	 * 
	 * @param persp
	 *            the perspective to be closed
	 * @param save
	 *            whether the page's editors should be save if last perspective
	 */
	/* package */
	void closePerspective(Perspective persp, boolean save, boolean closePage) {

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

		// Close all editors on last perspective close
		if (perspList.size() == 1 && getEditorManager().getEditorCount() > 0) {
			// Close all editors
			if (!closeAllEditors(save))
				return;
		}

		// Dispose of the perspective
		boolean isActive = (perspList.getActive() == persp);
		window.removePerspectiveShortcut(persp.getDesc(), this);
		if (isActive)
			setPerspective(perspList.getNextActive());
		disposePerspective(persp);
		if (closePage && perspList.size() == 0)
			close();
	}

	/**
	 * Closes all perspectives in the page. The page is kept so as not to lose
	 * the input.
	 * 
	 * @param save
	 *            whether the page's editors should be saved
	 */
	/* package */
	void closeAllPerspectives() {

		if (perspList.isEmpty())
			return;

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

		// Close all editors
		if (!closeAllEditors(true))
			return;

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

		// Close each perspective in turn
		PerspectiveList oldList = perspList;
		perspList = new PerspectiveList();
		Iterator enum = oldList.iterator();
		while (enum.hasNext())
			closePerspective((Perspective) enum.next(), false, false);
		close();
	}
	/**
	 * Creates the client composite.
	 */
	private void createClientComposite() {
		final Composite parent = window.getPageComposite();
		composite = new Composite(parent, SWT.NONE);
		composite.setVisible(false); // Make visible on activate.
		composite.setBounds(parent.getClientArea());
		resizeListener = new ControlAdapter() {
			public void controlResized(ControlEvent e) {
				composite.setBounds(parent.getClientArea());
			}
		};
		parent.addControlListener(resizeListener);
	}
	/**
	 * Creates a new view set. Return null on failure.
	 */
	private Perspective createPerspective(PerspectiveDescriptor desc) {
		String label = desc.getId();
		try {
			UIStats.start(UIStats.CREATE_PERSPECTIVE, label);
			Perspective persp = new Perspective(desc, this);
			perspList.add(persp);
			window.firePerspectiveOpened(this, desc);
			IViewReference refs[] = persp.getViewReferences();
			for (int i = 0; i < refs.length; i++) {
				IViewReference ref = refs[i];
				if (ref != null)
					addPart(ref);
			}
			return persp;
		} catch (WorkbenchException e) {
			if (!((Workbench) window.getWorkbench()).isStarting()) {
				MessageDialog.openError(window.getShell(), WorkbenchMessages.getString("Error"), //$NON-NLS-1$
				WorkbenchMessages.format("Workbench.showPerspectiveError", new String[] { desc.getId()})); //$NON-NLS-1$
			}
			return null;
		} finally {
			UIStats.end(UIStats.CREATE_PERSPECTIVE, label);
		}
	}
	/**
	 * Open the tracker to allow the user to move the specified part using
	 * keyboard.
	 */
	public void openTracker(ViewPane pane) {
		Perspective persp = getActivePerspective();
		if (persp != null)
			persp.openTracker(pane);
	}
	/**
	 * Add a part to the activation list.
	 */
	protected void addPart(IWorkbenchPartReference ref) {
		activationList.add(ref);
	}
	/**
	 * Remove a part from the activation list.
	 */
	protected void removePart(IWorkbenchPartReference ref) {
		activationList.remove(ref);
	}
	/**
	 * Deactivates a part. The pane is unhilighted.
	 */
	private void deactivatePart(IWorkbenchPart part) {
		if (part != null) {
			PartSite site = (PartSite) part.getSite();
			site.getPane().showFocus(false);
		}
	}
	private void disposePart(IWorkbenchPartReference ref) {
		final WorkbenchPartReference ref0 = (WorkbenchPartReference) ref;
		Platform.run(new SafeRunnable() {
			public void run() {
				ref0.dispose();
			}
			public void handleException(Throwable e) {
				//Exception has already being logged by Core. Do nothing.
			}
		});
	}
	/**
	 * Cleanup.
	 */
	public void dispose() {

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

		// Close and dispose the editors.
		closeAllEditors(false);

		// Capture views.
		IViewReference refs[] = viewFactory.getViews();

		// Get rid of perspectives. This will close the views.
		Iterator enum = perspList.iterator();
		while (enum.hasNext()) {
			Perspective perspective = (Perspective) enum.next();
			window.removePerspectiveShortcut(perspective.getDesc(), this);
			window.firePerspectiveClosed(this, perspective.getDesc());
			perspective.dispose();
		}
		perspList = new PerspectiveList();

		// Dispose views.
		final int errors[] = { 0 };
		for (int i = 0; i < refs.length; i++) {
			final WorkbenchPartReference ref = (WorkbenchPartReference) refs[i];
			firePartClosed(refs[i]);
			Platform.run(new SafeRunnable() {
				public void run() {
					ref.dispose();
				}
				public void handleException(Throwable e) {
					errors[0]++;
				}
			});
		}
		if (errors[0] > 0) {
			String message;
			if (errors[0] == 1)
				message = WorkbenchMessages.getString("WorkbenchPage.oneErrorClosingPage"); //$NON-NLS-1$
			else
				message = WorkbenchMessages.getString("WorkbenchPage.multipleErrorsClosingPage"); //$NON-NLS-1$
			MessageDialog.openError(null, WorkbenchMessages.getString("Error"), message); //$NON-NLS-1$
		}
		activePart = null;
		activationList = new ActivationList();

		// Get rid of editor presentation.
		editorPresentation.dispose();

		// Get rid of composite.
		window.getPageComposite().removeControlListener(resizeListener);
		composite.dispose();

		navigationHistory.dispose();
		
		stickyPerspectives.clear();
	}
	/**
	 * Dispose a perspective.
	 */
	private void disposePerspective(Perspective persp) {
		// Get views.
		IViewReference refs[] = persp.getViewReferences();

		// Get rid of perspective.
		perspList.remove(persp);
		window.firePerspectiveClosed(this, persp.getDesc());
		persp.dispose();

		// Loop through the views.
		for (int i = 0; i < refs.length; i++) {
			IViewReference ref = refs[i];

			//If the part is no longer reference then dispose it.
			boolean exists = viewFactory.hasView(ref);
			if (!exists) {
				firePartClosed(ref);
				activationList.remove(ref);
				disposePart(ref);
			}
		}
		stickyPerspectives.remove(persp.getDesc());
	}
	/**
	 * @return NavigationHistory
	 */
	public INavigationHistory getNavigationHistory() {
		return navigationHistory;
	}

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

		// Create list dialog.
		CustomizePerspectiveDialog dlg =
			new CustomizePerspectiveDialog(window.getShell(), 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 enum = perspList.iterator();
		while (enum.hasNext()) {
			Perspective mgr = (Perspective) enum.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;

		// Create the control first - needed for fast views only
		IViewPart view = ref.getView(true);
		ViewPane pane = (ViewPane) ((WorkbenchPartReference) ref).getPane();
		Control ctrl = pane.getControl();
		if (ctrl == null)
			pane.createControl(getClientComposite());
		return view;
	}
	
	/* (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) {
		Perspective persp = getActivePerspective();
		if (persp == null)
			return null;
		return persp.findView(viewId, secondaryId);
	}

	/**
	 * Fire part activation out.
	 */
	private void firePartActivated(IWorkbenchPart part) {
		String label = "activate::" + (part != null ? part.getTitle() : "none"); //$NON-NLS-1$ //$NON-NLS-2$
		try {
			UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
			partListeners.firePartActivated(part);
			partListeners2.firePartActivated(getReference(part));
			selectionService.partActivated(part);
		} finally {
			UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
		}
	}
	/**
	 * Fire part brought to top out.
	 */
	private void firePartBroughtToTop(IWorkbenchPart part) {
		String label = "bringToTop::" + (part != null ? part.getTitle() : "none"); //$NON-NLS-1$ //$NON-NLS-2$
		try {
			UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
			partListeners.firePartBroughtToTop(part);
			partListeners2.firePartBroughtToTop(getReference(part));
			selectionService.partBroughtToTop(part);
		} finally {
			UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
		}
	}
	/**
	 * Fire part close out.
	 */
	private void firePartClosed(IWorkbenchPartReference ref) {
		String label = "close" + ref.getTitle(); //$NON-NLS-1$
		try {
			UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
			IWorkbenchPart part = ref.getPart(false);
			if (part != null) {
				partListeners.firePartClosed(part);
				selectionService.partClosed(part);
			}
			partListeners2.firePartClosed(ref);
		} finally {
			UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
		}
	}
	/**
	 * Fire part deactivation out.
	 */
	private void firePartDeactivated(IWorkbenchPart part) {
		String label = "deactivate" + (part != null ? part.getTitle() : "none"); //$NON-NLS-1$ //$NON-NLS-2$
		try {
			UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
			partListeners.firePartDeactivated(part);
			partListeners2.firePartDeactivated(getReference(part));
			selectionService.partDeactivated(part);
		} finally {
			UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
		}
	}
	/**
	 * Fire part open out.
	 */
	public void firePartOpened(IWorkbenchPart part) {
		String label = "deactivate" + (part != null ? part.getTitle() : "none"); //$NON-NLS-1$ //$NON-NLS-2$
		try {
			UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
			partListeners.firePartOpened(part);
			partListeners2.firePartOpened(getReference(part));
			selectionService.partOpened(part);
		} finally {
			UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
		}
	}
	/**
	 * Fire part input changed out.
	 */
	private void firePartInputChanged(IWorkbenchPart part) {
		String label = "inputChanged" + (part != null ? part.getTitle() : "none"); //$NON-NLS-1$ //$NON-NLS-2$
		try {
			UIStats.start(UIStats.NOTIFY_PART_LISTENERS, label);
			partListeners2.firePartInputChanged(getReference(part));
			selectionService.partInputChanged(part);
		} finally {
			UIStats.end(UIStats.NOTIFY_PART_LISTENERS, label);
		}
	}
	/**
	 * 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) {
		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() {
		Perspective persp = getActivePerspective();
		if (persp != null)
			return persp.getActionSets();
		else
			return new IActionSetDescriptor[0];
	}
	
	/**
	 * @see IWorkbenchPage
	 */
	public IEditorPart getActiveEditor() {
		return getEditorManager().getVisibleEditor();
	}
	/*
	 * (non-Javadoc) Method declared on IPartService
	 */
	public IWorkbenchPart getActivePart() {
		return activePart;
	}
	/*
	 * (non-Javadoc) Method declared on IPartService
	 */
	public IWorkbenchPartReference getActivePartReference() {
		return getReference(activePart);
	}
	/**
	 * 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 editor manager for this window.
	 */
// for dynamic UI - change access from private to protected
	protected EditorManager getEditorManager() {
		return editorMgr;
	}
	/**
	 * Answer the perspective presentation.
	 */
	public PerspectiveHelper getPerspectivePresentation() {
		if (getActivePerspective() != null)
			return getActivePerspective().getPresentation();
		return null;
	}
	/**
	 * Answer the editor presentation.
	 */
	public EditorAreaHelper getEditorPresentation() {
		return editorPresentation;
	}
	/**
	 * 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 getEditorManager().getDirtyEditors();
	}
	public IEditorPart findEditor(IEditorInput input) {
		return getEditorManager().findEditor(input);
	}
	/**
	 * See IWorkbenchPage.
	 */
	public IEditorReference[] getEditorReferences() {
		return getEditorManager().getEditors();
	}
	/**
	 * 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.getString("WorkbenchPage.UnknownLabel"); //$NON-NLS-1$
		if (input != null) {
			IWorkbenchAdapter adapter =
				(IWorkbenchAdapter) input.getAdapter(IWorkbenchAdapter.class);
			if (adapter != null)
				label = adapter.getLabel(input);
		}
		Perspective persp = getActivePerspective();
		if (persp != null)
			label = WorkbenchMessages.format("WorkbenchPage.PerspectiveFormat", new Object[] { label, persp.getDesc().getLabel()}); //$NON-NLS-1$
		else if (deferredActivePersp != null)
			label = WorkbenchMessages.format("WorkbenchPage.PerspectiveFormat", new Object[] { label, deferredActivePersp.getLabel()}); //$NON-NLS-1$	
		return label;
	}
	/**
	 * Returns the new wizard actions the page. This is List of Strings.
	 */
	public ArrayList getNewWizardActionIds() {
		Perspective persp = getActivePerspective();
		if (persp != null)
			return persp.getNewWizardActionIds();
		else
			return new ArrayList();
	}
	/**
	 * Returns the perspective.
	 */
	public IPerspectiveDescriptor getPerspective() {
		if (deferredActivePersp != null)
			return deferredActivePersp;
		Perspective persp = getActivePerspective();
		if (persp != null)
			return persp.getDesc();
		else
			return null;
	}
	/**
	 * Returns the perspective actions for this page. This is List of Strings.
	 */
	public ArrayList getPerspectiveActionIds() {
		Perspective persp = getActivePerspective();
		if (persp != null)
			return persp.getPerspectiveActionIds();
		else
			return new ArrayList();
	}
	/*
	 * (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 show view actions the page. This is a List of Strings.
	 */
	public ArrayList getShowViewActionIds() {
		Perspective persp = getActivePerspective();
		if (persp != null)
			return persp.getShowViewActionIds();
		else
			return new ArrayList();
	}
	/**
	 * Returns the unprotected window.
	 */
	protected WorkbenchWindow getUnprotectedWindow() {
		return window;
	}
	/*
	 * 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() {
		Perspective 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(true);
				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.hideActionSet(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) {
		if (ref == null)
			return;
		IWorkbenchPart part = ref.getPart(false);
		if (part != null) {
			hideView((IViewPart) part);
		} else {
			hideView(getActivePerspective(), ref);
		}		
	}
	
	/* package */ void refreshActiveView() {
		IWorkbenchPart nextActive = activationList.getActive();
		
		if (nextActive != activePart) {
			if (nextActive != null) {
				activate(nextActive);
			} else {
				setActivePart(null);
			}
		}
	}
	
	/**
	 * See IPerspective
	 */
	public void hideView(IViewPart view) {
		// Sanity check.
		Perspective persp = getActivePerspective();
		if (persp == null || !certifyPart(view))
			return;

		// If part is added / removed always unzoom.
		IViewReference ref = (IViewReference) getReference(view);
		if (isZoomed() && !isFastView(ref))
			zoomOut();

		// Confirm.
		if (!persp.canCloseView(view))
			return;

		// Activate new part.
		if (view == activePart) {
			IWorkbenchPart prevActive = activationList.getPreviouslyActive();
			if (prevActive != null)
				activate(prevActive);
			else
				setActivePart(null);
		}

		hideView(persp, ref);

	}
	private void hideView(Perspective persp, IViewReference ref) {
		// Hide the part.
		persp.hideView(ref);

		// If the part is no longer reference then dispose it.
		boolean exists = viewFactory.hasView(ref);
		if (!exists) {
			firePartClosed(ref);
			disposePart(ref);
			activationList.remove(ref);

			/*
			 * Bug 42684. A ViewPane instance has been disposed, but an attempt
			 * is then made to remove focus from it. This happens because the
			 * ViewPane is still viewed as the active part. The activePart
			 * should always be modified when the view is changed. activePart
			 * isn't really needed anymore (see declaration).
			 */
			activePart = activationList.getActive();
		}

		// Notify interested listeners
		window.firePerspectiveChanged(this, getPerspective(), CHANGE_VIEW_HIDE);

		// Just in case view was fast.
		window.updateFastViewBar();

		//if it was the last part, close the perspective
//		lastPartClosePerspective();
	}

	/**
	 * Initialize the page.
	 * 
	 * @param w
	 *            the parent window
	 * @param layoutID
	 *            may be <code>null</code> if restoring from file
	 * @param input
	 *            the page input
	 */
	private void init(WorkbenchWindow w, String layoutID, IAdaptable input)
		throws WorkbenchException {
		// Save args.
		this.window = w;
		this.input = input;

		// Create presentation.
		createClientComposite();
		editorPresentation = new EditorAreaHelper(this);
		editorMgr = new EditorManager(window, this, editorPresentation);

		// Get perspective descriptor.
		if (layoutID != null) {
			PerspectiveDescriptor desc =
				(PerspectiveDescriptor) WorkbenchPlugin
					.getDefault()
					.getPerspectiveRegistry()
					.findPerspectiveWithId(layoutID);
			if (desc == null)
				throw new WorkbenchException(WorkbenchMessages.getString("WorkbenchPage.ErrorRecreatingPerspective")); //$NON-NLS-1$
			Perspective persp = createPerspective(desc);
			if (persp == null)
				return;
			perspList.setActive(persp);
			window.firePerspectiveActivated(this, desc);
		}
	}
	/**
	 * See IWorkbenchPage.
	 */
	public boolean isPartVisible(IWorkbenchPart part) {
		return ((PartSite) part.getSite()).getPane().isVisible();
	}
	/**
	 * 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;
	}
	/**
	 * 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 getEditorManager().isSaveAllNeeded();
	}
	/**
	 * Returns whether the page is zoomed.
	 */
	public boolean isZoomed() {
		Perspective persp = getActivePerspective();
		if (persp == null)
			return false;
		if (persp.getPresentation() == null)
			return false;
		return persp.getPresentation().isZoomed();
	}
	/**
	 * Returns <code>true</code> if the window needs to unzoom for the given
	 * IWorkbenchPart to be seen by the user. Returns false otherwise.
	 * 
	 * @param part
	 *            the part whose visibility is to be determined
	 * @return <code>true</code> if the window needs to unzoom for the given
	 *         IWorkbenchPart to be seen by the user, <code>false</code>
	 *         otherwise.
	 */
	private boolean needToZoomOut(IWorkbenchPart part) {
		// part is an editor
		if (part instanceof IEditorPart) {
			if (getActivePart() instanceof IViewPart) {
				return true;
			}
			EditorSite site = (EditorSite) part.getSite();
			EditorPane pane = (EditorPane) site.getPane();
			EditorStack book = pane.getWorkbook();
			return !book.equals(book.getEditorArea().getActiveWorkbook());
		}
		// part is a view
		if (part instanceof IViewPart) {
			if (isFastView((IViewReference) getReference(part))
				|| part.equals(getActivePart()))
				return false;
			else
				return true;
		}

		return true;
	}
	/**
	 * This method is called when the page is activated.
	 */
	protected void onActivate() {
		Iterator enum = perspList.iterator();
		while (enum.hasNext()) {
			Perspective perspective = (Perspective) enum.next();
			window.addPerspectiveShortcut(perspective.getDesc(), this);
		}
		composite.setVisible(true);
		Perspective persp = getActivePerspective();

		if (persp != null) {
			window.selectPerspectiveShortcut(persp.getDesc(), this, true);
			persp.onActivate();
			updateVisibility(null, persp);
		}
		if (activePart == null && persp != null) {
			IViewReference refs[] = persp.getViewReferences();
			for (int i = 0; i < refs.length; i++) {
				IViewReference ref = refs[i];
				if (ref != null) {
					activePart = ref.getPart(false);
					if (activePart != null)
						break;
				}
			}
		}
		if (activePart != null) {
			activationList.setActive(activePart);

			activatePart(activePart);
			actionSwitcher.updateActivePart(activePart);
			if (activePart instanceof IEditorPart) {
				lastActiveEditor = (IEditorPart) activePart;
				actionSwitcher.updateTopEditor((IEditorPart) activePart);
			} else {
				IEditorPart editor = editorMgr.getVisibleEditor();
				if (editor != null) {
					actionSwitcher.updateTopEditor(editor);

					// inform the site's action bars of the current editor
					// (important that this occur during page opening).
					PartSite site = (PartSite) editor.getSite();
					SubActionBars bars = (SubActionBars) site.getActionBars();
					bars.partChanged(editor);
				}
			}
			firePartActivated(activePart);
		} else {
			composite.setFocus();
		}
	}
	/**
	 * This method is called when the page is deactivated.
	 */
	protected void onDeactivate() {
		if (activePart != null) {
			deactivatePart(activePart);
			actionSwitcher.updateActivePart(null);
			firePartDeactivated(activePart);
		}
		actionSwitcher.updateTopEditor(null);
		lastActiveEditor = null;
		if (getActivePerspective() != null)
			getActivePerspective().onDeactivate();
		composite.setVisible(false);
		Iterator enum = perspList.iterator();
		while (enum.hasNext()) {
			Perspective perspective = (Perspective) enum.next();
			window.removePerspectiveShortcut(perspective.getDesc(), this);
		}
	}
	/**
	 * See IWorkbenchPage.
	 */
	public void reuseEditor(IReusableEditor editor, IEditorInput input) {
		editor.setInput(input);
		firePartInputChanged(editor);
	}
	/**
	 * See IWorkbenchPage.
	 */
	public IEditorPart openEditor(IEditorInput input, String editorID)
		throws PartInitException {
		return openEditor(input, editorID, true);
	}
	/**
	 * See IWorkbenchPage.
	 */
	public IEditorPart openEditor(
		final IEditorInput input,
		final String editorID,
		final boolean activate)
		throws PartInitException {
		if (input == null || editorID == null) {
			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] = busyOpenEditor(input, editorID, activate);
				} catch (PartInitException e) {
					ex[0] = e;
				}
			}
		});
		if (ex[0] != null)
			throw ex[0];
		return result[0];
	}
	/**
	 * See IWorkbenchPage.openEditor
	 */
	private IEditorPart busyOpenEditor(
		IEditorInput input,
		String editorID,
		boolean activate)
		throws PartInitException {
		// If an editor already exists for the input use it.
		IEditorPart editor = getEditorManager().findEditor(input);
		if (editor != null) {
			if (IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID.equals(editorID)) {
				if (editor.isDirty()) {
						MessageDialog dialog = new MessageDialog(getWorkbenchWindow().getShell(), WorkbenchMessages.getString("Save"), //$NON-NLS-1$
		null, // accept the default window icon
	WorkbenchMessages.format("WorkbenchPage.editorAlreadyOpenedMsg", new String[] { input.getName()}), //$NON-NLS-1$
					MessageDialog.QUESTION,
						new String[] {
							IDialogConstants.YES_LABEL,
							IDialogConstants.NO_LABEL,
							IDialogConstants.CANCEL_LABEL },
						0);
					int saveFile = dialog.open();
					if (saveFile == 0) {
						try {
							final IEditorPart editorToSave = editor;
							getWorkbenchWindow()
								.run(false, false, new IRunnableWithProgress() {
								public void run(IProgressMonitor monitor)
									throws
										InvocationTargetException,
										InterruptedException {
									editorToSave.doSave(monitor);
								}
							});
						} catch (InvocationTargetException e) {
							throw (RuntimeException) e.getTargetException();
						} catch (InterruptedException e) {
							return null;
						}
					} else if (saveFile == 2) {
						return null;
					}
				}
			} else {
				showEditor(activate, editor);
				return editor;
			}
		}

		// Disabled turning redraw off, because it causes setFocus
		// in activate(editor) to fail.
		// getClientComposite().setRedraw(false);

		// Remember the old visible editor
		IEditorPart oldVisibleEditor = getEditorManager().getVisibleEditor();

		// Otherwise, create a new one. This may cause the new editor to
		// become the visible (i.e top) editor.
		IEditorReference ref = null;
		ref = getEditorManager().openEditor(editorID, input, true);
		if (ref != null) {
			editor = ref.getEditor(true);
			addPart(ref);
		}

		if (editor != null) {
			//firePartOpened(editor);
			zoomOutIfNecessary(editor);
			setEditorAreaVisible(true);
			if (activate) {
				if (editor instanceof MultiEditor)
					activate(((MultiEditor) editor).getActiveEditor());
				else
					activate(editor);
			} else {
				activationList.setActive(editor);
				if (activePart != null) {
					// ensure the activation list is in a valid state
					activationList.setActive(activePart);
				}
				// The previous openEditor call may create a new editor
				// and make it visible, so send the notification.
				IEditorPart visibleEditor =
					getEditorManager().getVisibleEditor();
				if ((visibleEditor == editor)
					&& (oldVisibleEditor != editor)) {
					actionSwitcher.updateTopEditor(editor);
					firePartBroughtToTop(editor);
				} else {
					bringToTop(editor);
				}
			}
			window.firePerspectiveChanged(
				this,
				getPerspective(),
				CHANGE_EDITOR_OPEN);
		}

		//	getClientComposite().setRedraw(true);

		return editor;
	}
	private void showEditor(boolean activate, IEditorPart editor) {
		zoomOutIfNecessary(editor);
		setEditorAreaVisible(true);
		if (activate)
			activate(editor);
		else
			bringToTop(editor);
	}
	/**
	 * See IWorkbenchPage.
	 */
	public boolean isEditorPinned(IEditorPart editor) {
		return !((EditorSite) editor.getEditorSite()).getReuseEditor();
	}
	/**
	 * 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;

		// If parts change always update zoom.
		if (isZoomed())
			zoomOut();

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

		// Notify listeners.
		window.updateFastViewBar();
		window.firePerspectiveChanged(
			this,
			getPerspective(),
			CHANGE_FAST_VIEW_REMOVE);
	}
	/**
	 * Removes an IPartListener from the part service.
	 */
	public void removePartListener(IPartListener l) {
		partListeners.removePartListener(l);
	}
	/**
	 * Removes an IPartListener from the part service.
	 */
	public void removePartListener(IPartListener2 l) {
		partListeners2.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.
	 * 
	 * In the current design this method is invoked by the part pane when the
	 * pane, the part, or any children gain focus.
	 */
	public void requestActivation(IWorkbenchPart part) {
		// Sanity check.
		if (!certifyPart(part))
			return;

		// Real work.
		setActivePart(part);
	}
	/**
	 * 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() {
		// Run op in busy cursor.
		// Use set redraw to eliminate the "flash" that can occur in the
		// coolbar as the perspective is reset.
		CoolBarManager mgr = window.getCoolBarManager();
		try {
			mgr.getControl().setRedraw(false);
			BusyIndicator.showWhile(null, new Runnable() {
				public void run() {
					busyResetPerspective();
				}
			});
		} finally {
			mgr.getControl().setRedraw(true);
		}
	}
	/**
	 * 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,
		IPerspectiveDescriptor activeDescritor) {
		// Restore working set
		String pageName = memento.getString(IWorkbenchConstants.TAG_LABEL);
		String label = pageName == null ? "" : "::" + pageName; //$NON-NLS-1$ //$NON-NLS-2$

		try {
			UIStats.start(UIStats.RESTORE_WORKBENCH, "WorkbenchPage" + label); //$NON-NLS-1$
			if (pageName == null)
				pageName = ""; //$NON-NLS-1$
			MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.format("WorkbenchPage.unableToRestorePerspective", new String[] { pageName }), //$NON-NLS-1$
			null);

			String workingSetName =
				memento.getString(IWorkbenchConstants.TAG_WORKING_SET);
			if (workingSetName != null) {
				WorkingSetManager workingSetManager =
					(WorkingSetManager) getWorkbenchWindow()
						.getWorkbench()
						.getWorkingSetManager();
				setWorkingSet(workingSetManager.getWorkingSet(workingSetName));
			}

			// Restore editor manager.
			IMemento childMem =
				memento.getChild(IWorkbenchConstants.TAG_EDITORS);
			result.merge(getEditorManager().restoreState(childMem));

			childMem = memento.getChild(IWorkbenchConstants.TAG_VIEWS);
			if (childMem != null)
				result.merge(getViewFactory().restoreState(childMem));

			// Get persp block.
			childMem = memento.getChild(IWorkbenchConstants.TAG_PERSPECTIVES);
			String activePartID =
				childMem.getString(IWorkbenchConstants.TAG_ACTIVE_PART);
			String activePerspectiveID =
				childMem.getString(IWorkbenchConstants.TAG_ACTIVE_PERSPECTIVE);

			// Restore perspectives.
			IMemento perspMems[] =
				childMem.getChildren(IWorkbenchConstants.TAG_PERSPECTIVE);
			Perspective activePerspective = null;
			for (int i = 0; i < perspMems.length; i++) {
				try {
					Perspective persp = new Perspective(null, this);
					result.merge(persp.restoreState(perspMems[i]));
					IPerspectiveDescriptor desc = persp.getDesc();
					if (desc.equals(activeDescritor))
						activePerspective = persp;
					else if (
						(activePerspective == null)
							&& desc.getId().equals(activePerspectiveID))
						activePerspective = persp;
					perspList.add(persp);
				} catch (WorkbenchException e) {
				}
			}
			boolean restoreActivePerspective = false;
			if (activeDescritor == null)
				restoreActivePerspective = true;
			else if (
				activePerspective != null
					&& activePerspective.getDesc().equals(activeDescritor)) {
				restoreActivePerspective = true;
			} else {
				restoreActivePerspective = false;
				activePerspective =
					createPerspective((PerspectiveDescriptor) activeDescritor);
				if (activePerspective == null) {
					result.merge(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, WorkbenchMessages.format("Workbench.showPerspectiveError", new String[] { activeDescritor.getId()}), //$NON-NLS-1$
					null));
				}
			}

			perspList.setActive(activePerspective);

			// Make sure we have a valid perspective to work with,
			// otherwise return.
			activePerspective = perspList.getActive();
			if (activePerspective == null) {
				activePerspective = perspList.getNextActive();
				perspList.setActive(activePerspective);
				result.merge(activePerspective.restoreState());
			}
			if (activePerspective != null && restoreActivePerspective)
				result.merge(activePerspective.restoreState());

			if (activePerspective != null) {
				window.firePerspectiveActivated(
					this,
					activePerspective.getDesc());

				// Restore active part.
				if (activePartID != null) {
					IViewReference ref =
						activePerspective.findView(activePartID);
					IViewPart view = null;
					if (ref != null)
						view = ref.getView(true);
					if (view != null)
						activePart = view;
				}
			}

			childMem =
				memento.getChild(IWorkbenchConstants.TAG_NAVIGATION_HISTORY);
			if (childMem != null)
				navigationHistory.restoreState(childMem);
			else if (getActiveEditor() != null)
				navigationHistory.markEditor(getActiveEditor());
			return result;
		} finally {
			UIStats.end(UIStats.RESTORE_WORKBENCH, "WorkbenchPage" + label); //$NON-NLS-1$
		}
	}
	/**
	 * See IWorkbenchPage
	 */
	public boolean saveAllEditors(boolean confirm) {
		return getEditorManager().saveAll(confirm, false);
	}
	/*
	 * 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 getEditorManager().savePart(saveable, part, confirm);
	}
	/**
	 * 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.updatePerspectiveShortcut(oldDesc, newDesc, this);
	}
	/**
	 * Save the state of the page.
	 */
	public IStatus saveState(IMemento memento) {
		// We must unzoom to get correct layout.
		if (isZoomed())
			zoomOut();

		MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.format("WorkbenchPage.unableToSavePerspective", new String[] { getLabel()}), //$NON-NLS-1$
		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)
			childMem.putString(
				IWorkbenchConstants.TAG_ACTIVE_PART,
				getActivePart().getSite().getId());

		// Save each perspective in opened order
		Iterator enum = perspList.iterator();
		while (enum.hasNext()) {
			Perspective persp = (Perspective) enum.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());
		}

		navigationHistory.saveState(
			memento.createChild(IWorkbenchConstants.TAG_NAVIGATION_HISTORY));
		return result;
	}
	/**
	 * Sets the active part.
	 */
	private void setActivePart(IWorkbenchPart newPart) {
		// Optimize it.
		if (activePart == newPart)
			return;

		//No need to change the history if the active editor is becoming the
		// active part
		boolean markLocation = newPart != lastActiveEditor;
		String label = newPart != null ? newPart.getTitle() : "none"; //$NON-NLS-1$
		try {
			UIStats.start(UIStats.ACTIVATE_PART, label);
			// Notify perspective. It may deactivate fast view.
			Perspective persp = getActivePerspective();
			if (persp != null)
				persp.partActivated(newPart);

			// Deactivate old part
			IWorkbenchPart oldPart = activePart;
			if (oldPart != null) {
				deactivatePart(oldPart);
			}

			// Set active part.
			activePart = newPart;
			if (newPart != null) {
				activationList.setActive(newPart);
				if (newPart instanceof IEditorPart) {
					lastActiveEditor = (IEditorPart) newPart;
					IEditorReference ref =
						(IEditorReference) getReference(lastActiveEditor);
					editorMgr.setVisibleEditor(ref, true);
				}
			}
			activatePart(activePart);

			if (markLocation
				&& activePart != null
				&& activePart instanceof IEditorPart)
				navigationHistory.markEditor((IEditorPart) activePart);

			// Fire notifications
			if (oldPart != null)
				firePartDeactivated(oldPart);

			// Update actions now so old actions have heard part deactivated
			// and
			// new actions can hear part activated.
			actionSwitcher.updateActivePart(newPart);
			if (newPart != null)
				firePartActivated(newPart);
		} finally {
			UIStats.end(UIStats.ACTIVATE_PART, label);
		}
	}
	/**
	 * 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();
			if (activePart instanceof IEditorPart) {
				IEditorPart e = (IEditorPart) activePart;
				setActivePart(null);
				// preserve editor contributions
				actionSwitcher.updateTopEditor(e);
			}
			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;

		if (newPersp != null) {
			IStatus status = newPersp.restoreState();
			if (status.getSeverity() != IStatus.OK) {
				String title = WorkbenchMessages.getString("WorkbenchPage.problemRestoringTitle"); //$NON-NLS-1$
				String msg = WorkbenchMessages.getString("WorkbenchPage.errorReadingState"); //$NON-NLS-1$
				ErrorDialog.openError(
					getWorkbenchWindow().getShell(),
					title,
					msg,
					status);
			}
		}

		// Deactivate active part.

		// ensure the switcher is not showing any action sets
		// so it will reshow them in the new perspective
		actionSwitcher.updateTopEditor(null);

		IWorkbenchPart oldActivePart = activePart;
		setActivePart(null);

		// Deactivate the old layout
		if (oldPersp != null) {
			oldPersp.onDeactivate();
			window.selectPerspectiveShortcut(oldPersp.getDesc(), this, false);
		}

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

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

			// Update the shortcut
			window.selectPerspectiveShortcut(newPersp.getDesc(), this, true);
		} else {
			// No need to remember old active part since there
			// is no new active perspective to activate it in.
			oldActivePart = null;
		}

		// Update the window
		window.updateActionSets();
		window.updateFastViewBar();

		updateVisibility(oldPersp, newPersp);

		// Reactivate active part.
		if (oldActivePart != null) {
			String id = oldActivePart.getSite().getId();
			oldPersp.setOldPartID(id);
			if (oldActivePart instanceof IEditorPart
				&& isEditorAreaVisible()) {
				activate(oldActivePart);
			} else if (oldActivePart instanceof IViewPart) {
				IEditorPart ed = editorMgr.getVisibleEditor();
				if (ed != null)
					actionSwitcher.updateTopEditor(ed);
				if (findView(id) != null) {
					activate(oldActivePart);
				} else {
					activateOldPart(newPersp);
				}
			} else {
				activateOldPart(newPersp);
			}
		} else { //no active part
			IEditorPart ed = editorMgr.getVisibleEditor();
			if (ed != null) {
				actionSwitcher.updateTopEditor(ed);
			} else {
				activateOldPart(newPersp);
			}
		}
		if (getActivePart() == null && activationList.getActive() != null) {
			activate(activationList.getActive());
		}
		if (editorPresentation != null)
			editorPresentation.showVisibleEditor();
		
		if (newPersp != null && oldPersp != null ) {
			if (!stickyPerspectives.contains(newPersp.getDesc())) {
			    IViewRegistry viewReg = WorkbenchPlugin.getDefault().getViewRegistry();
			    IStickyViewDescriptor [] stickyDescs = viewReg.getStickyViews();
			    for (int i = 0; i < stickyDescs.length; i++) {
			        try {
			            // show a sticky view if it was in the last perspective
                        if (oldPersp.findView(stickyDescs[i].getId()) != null) {
                            showView(stickyDescs[i].getId(), null, IWorkbenchPage.VIEW_CREATE);
                        }
			        }
                    catch (PartInitException e) {
    					WorkbenchPlugin.log("Could not open view :" + stickyDescs[i].getId(), new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH, IStatus.ERROR, "Could not open view :" + stickyDescs[i].getId(), e));	//$NON-NLS-1$ //$NON-NLS-2$
    				}
                }
				stickyPerspectives.add(newPersp.getDesc());
			}
		}
	}
	/*
	 * Update visibility state of all views.
	 */
	private void updateVisibility(Perspective oldPersp, Perspective newPersp) {
		HashSet set = new HashSet();
		IWorkbenchPartReference[] refs;
		if (oldPersp != null) {
			refs = oldPersp.getViewReferences();
			for (int i = 0; i < refs.length; i++) {
				PartPane pane = ((WorkbenchPartReference) refs[i]).getPane();
				if (pane != null)
					set.add(pane);
			}
		}
		if (newPersp != null) {
			refs = newPersp.getViewReferences();
			for (int i = 0; i < refs.length; i++) {
				PartPane pane = ((WorkbenchPartReference) refs[i]).getPane();
				if (pane != null)
					set.add(pane);
			}
			PerspectiveHelper pres = newPersp.getPresentation();
			for (Iterator iter = set.iterator(); iter.hasNext();) {
				PartPane pane = (PartPane) iter.next();
				String secondaryId = null;
				if (pane instanceof ViewPane) {
					ViewPane vp = (ViewPane) pane;
					IViewReference ref = (IViewReference)vp.getPartReference();
					secondaryId = ref.getSecondaryId();
				}
				boolean isVisible = pres.isPartVisible(pane.getID(), secondaryId);
				pane.setVisible(isVisible);
			}
		} else {
			for (Iterator iter = set.iterator(); iter.hasNext();) {
				PartPane pane = (PartPane) iter.next();
				pane.setVisible(false);
			}
		}
	}

	private void activateOldPart(Perspective newPersp) {
		if (window.isClosing())
			return;
		if (newPersp != null) {
			String oldID = newPersp.getOldPartID();
			IWorkbenchPart prevOldPart = null;
			if (oldID != null)
				prevOldPart = findView(oldID);
			if (prevOldPart != null)
				activate(prevOldPart);
			else if (isEditorAreaVisible())
				activate(getActiveEditor());
		}
	}
	/**
	 * Sets the perspective.
	 * 
	 * @param persp
	 *            identifies the new perspective.
	 */
	public void setPerspective(final IPerspectiveDescriptor desc) {
		// Going from multiple to single rows can make the coolbar
		// and its adjacent views appear jumpy as perspectives are
		// switched. Turn off redraw to help with this.
		CoolBarManager mgr = window.getCoolBarManager();
		try {
			mgr.getControl().setRedraw(false);
			getClientComposite().setRedraw(false);
			// Run op in busy cursor.
			BusyIndicator.showWhile(null, new Runnable() {
				public void run() {
					busySetPerspective(desc);
				}
			});
		} finally {
			getClientComposite().setRedraw(true);
			mgr.getControl().setRedraw(true);
			IWorkbenchPart part = getActivePart();
			if (part != null)
				part.setFocus();
		}
	}
	/**
	 * Restore the toolbar layout for the active perspective.
	 */
	protected void resetToolBarLayout() {
		window.getCoolBarManager().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(
				propertyChangeListener);
		} else {
			WorkbenchPlugin
				.getDefault()
				.getWorkingSetManager()
				.removePropertyChangeListener(propertyChangeListener);
		}
	}
	/**
	 * @see IWorkbenchPage
	 */
	public void showActionSet(String actionSetID) {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			persp.showActionSet(actionSetID);
			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 (!certifyMode(mode)) 
			throw new IllegalArgumentException(WorkbenchMessages.getString("WorkbenchPage.IllegalViewMode")); //$NON-NLS-1$
		
		// 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.getString("WorkbenchPage.AbnormalWorkbenchCondition")); //$NON-NLS-1$
	}
	/**
	 * @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) {
		Perspective persp = getActivePerspective();
		if (persp != null) {
			persp.toggleFastView(ref);
			// if the fast view has been deactivated
			if (ref != persp.getActiveFastView()) {
				IWorkbenchPart previouslyActive =
					activationList.getPreviouslyActive();
				IEditorPart activeEditor = getActiveEditor();
				if (activeEditor != null
					&& previouslyActive instanceof IEditorPart)
					setActivePart(activeEditor);
				else
					setActivePart(previouslyActive);
			}
		}
	}
	/**
	 * Zoom in on a part. If the part is already in zoom then zoom out.
	 */
	public void toggleZoom(IWorkbenchPartReference ref) {
		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.getWindow() instanceof DetachedWindow) {
		    pane.setZoomed(!pane.isZoomed());
			return;
		}

		if (ref instanceof IViewReference && persp.isFastView((IViewReference)ref)) {
			persp.toggleFastViewZoom();
			return;
		}
				
		// Update zoom status.
		if (isZoomed()) {
			zoomOut();
		
			return;
		} else {
			persp.getPresentation().zoomIn(ref);
			activate(ref.getPart(true));			
		}
	}
	/**
	 * updateActionBars method comment.
	 */
	public void updateActionBars() {
		window.updateActionBars();
	}

	/**
	 * Sets the tab list of this page's composite appropriately when a part is
	 * activated.
	 */
	private void updateTabList(IWorkbenchPart part) {
		PartSite site = (PartSite) part.getSite();
		PartPane pane = site.getPane();
		if (pane instanceof ViewPane) {
			ViewPane viewPane = (ViewPane) pane;
			Control[] tabList = viewPane.getTabList();
			if (pane.getWindow() instanceof DetachedWindow) {
				viewPane.getControl().getShell().setTabList(tabList);
			} else {
				getClientComposite().setTabList(tabList);
			}
		} else if (pane instanceof EditorPane) {
			EditorSashContainer ea = ((EditorPane) pane).getWorkbook().getEditorArea();
			ea.updateTabList();
			getClientComposite().setTabList(new Control[] { ea.getParent()});
		}
	}

	/**
	 * The title of the given part has changed. For views, updates the fast
	 * view button if necessary.
	 */
	public void updateTitle(IViewReference ref) {
		if (isFastView(ref)) {
			// Would be more efficient to just update label of single tool item
			// but we don't have access to it from here.
			window.updateFastViewBar();
		}
	}
	/**
	 * Zooms out a zoomed in part.
	 */
	/* package */
	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() && needToZoomOut(part))
			zoomOut();
	}
	/**
	 * @see IPageLayout.
	 */
	public int getEditorReuseThreshold() {
		IPreferenceStore store =
			WorkbenchPlugin.getDefault().getPreferenceStore();
		return store.getInt(IPreferenceConstants.REUSE_EDITORS);
	}
	/**
	 * @see IPageLayout.
	 */
	public void setEditorReuseThreshold(int openEditors) {
	}
	/*
	 * Returns the editors in activation order (oldest first).
	 */
	public IEditorReference[] getSortedEditors() {
		return activationList.getEditors();
	}
	/**
	 * Returns an iterator over the opened perspectives
	 */
	protected IPerspectiveDescriptor[] getOpenedPerspectives() {
		Perspective opened[] = perspList.getSortedPerspectives();
		IPerspectiveDescriptor[] result =
			new IPerspectiveDescriptor[opened.length];
		for (int i = 0; i < result.length; i++) {
			result[i] = opened[i].getDesc();
		}
		return result;
	}
	/*
	 * Returns the perspectives in activation order (oldest first).
	 */
	protected 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 activationList.getParts();
	}

	public IWorkbenchPartReference getReference(IWorkbenchPart part) {
		if (part == null)
			return null;
		PartPane pane = ((PartSite) part.getSite()).getPane();
		if (pane instanceof MultiEditorInnerPane) {
			MultiEditorInnerPane innerPane = (MultiEditorInnerPane) pane;
			return innerPane.getParentPane().getPartReference();
		}
		if (pane == null) {
			/*
			 * An error has occurred while creating the view.
			 */
			IViewReference refs[] = getViewReferences();
			for (int i = 0; i < refs.length; i++) {
				if (refs[i].getPart(false) == part)
					return refs[i];
			}
			return null;
		}
		return pane.getPartReference();
	}

	private class ActivationList {
		//List of parts in the activation order (oldest first)
		List parts = new ArrayList();

		/*
		 * Add/Move the active part to end of the list;
		 */
		void setActive(IWorkbenchPart part) {
			if (parts.size() <= 0)
				return;
			PartPane pane = ((PartSite) part.getSite()).getPane();
			if (pane instanceof MultiEditorInnerPane) {
				MultiEditorInnerPane innerPane = (MultiEditorInnerPane) pane;
				setActive(
					innerPane.getParentPane().getPartReference().getPart(true));
			} else {
				IWorkbenchPartReference ref = getReference(part);
				if (ref == parts.get(parts.size() - 1))
					return;
				parts.remove(ref);
				parts.add(ref);
			}
			pane.addPropertyChangeListener(propertyChangeListener);
		}
		/*
		 * Add/Move the active part to end of the list;
		 */
		void setActive(IWorkbenchPartReference ref) {
			setActive(ref.getPart(true));
		}
		/*
		 * Add the active part to the beginning of the list.
		 */
		void add(IWorkbenchPartReference ref) {
			if (parts.indexOf(ref) >= 0)
				return;

			IWorkbenchPart part = ref.getPart(false);
			if (part != null) {
				PartPane pane = ((PartSite) part.getSite()).getPane();
				if (pane instanceof MultiEditorInnerPane) {
					MultiEditorInnerPane innerPane =
						(MultiEditorInnerPane) pane;
					add(innerPane.getParentPane().getPartReference());
					return;
				}
			}
			PartPane pane = ((WorkbenchPartReference) ref).getPane();
			if (pane != null)
				pane.addPropertyChangeListener(propertyChangeListener);
			parts.add(0, ref);
		}
		/*
		 * Return the active part. Filter fast views.
		 */
		IWorkbenchPart getActive() {
			if (parts.isEmpty())
				return null;
			return getActive(parts.size() - 1);
		}
		/*
		 * Return the previously active part. Filter fast views.
		 */
		IWorkbenchPart getPreviouslyActive() {
			if (parts.size() < 2)
				return null;
			return getActive(parts.size() - 2);
		}
		/*
		 * Find a part in the list starting from the end and filter fast views
		 * and views from other perspectives.
		 */
		private IWorkbenchPart getActive(int start) {
			IWorkbenchPartReference[] views = getViewReferences();
			for (int i = start; i >= 0; i--) {
				IWorkbenchPartReference ref =
					(IWorkbenchPartReference) parts.get(i);
				
				// Skip parts whose containers have disabled auto-focus
				IWorkbenchPart part = ref.getPart(false);
				
				if (part != null) {
					IWorkbenchPartSite site = part.getSite();
					if (site instanceof PartSite) {
						PartSite partSite = (PartSite)site;
						
						ILayoutContainer container = partSite.getPane().getContainer();
						if ((container != null) && (!container.allowsAutoFocus())) {
							continue;
						}
					}
				}
				
				// Skip fastviews
				if (ref instanceof IViewReference) {
					if (!((IViewReference) ref).isFastView()  ) {
						for (int j = 0; j < views.length; j++) {
							if (views[j] == ref) {
								return ref.getPart(true);
							}
						}
					}
				} else {
					return ref.getPart(true);
				}
			}
			return null;
		}
		/*
		 * Retuns the index of the part within the activation list. The higher
		 * the index, the more recent it was used.
		 */
		int indexOf(IWorkbenchPart part) {
			return parts.indexOf(getReference(part));
		}
		/*
		 * Remove a part from the list
		 */
		boolean remove(IWorkbenchPartReference ref) {
			PartPane pane = ((WorkbenchPartReference) ref).getPane();
			if (pane != null)
				pane.removePropertyChangeListener(propertyChangeListener);
			return parts.remove(ref);
		}
		/*
		 * Returns the editors in activation order (oldest first).
		 */
		private IEditorReference[] getEditors() {
			ArrayList editors = new ArrayList(parts.size());
			for (Iterator i = parts.iterator(); i.hasNext();) {
				IWorkbenchPartReference part =
					(IWorkbenchPartReference) i.next();
				if (part instanceof IEditorReference) {
					editors.add(part);
				}
			}
			return (IEditorReference[]) editors.toArray(
				new IEditorReference[editors.size()]);
		}
		/*
		 * Return a list with all parts (editors and views).
		 */
		private IWorkbenchPartReference[] getParts() {
			IWorkbenchPartReference[] views = getViewReferences();
			ArrayList resultList = new ArrayList(parts.size());
			for (Iterator iterator = parts.iterator(); iterator.hasNext();) {
				IWorkbenchPartReference ref =
					(IWorkbenchPartReference) iterator.next();
				if (ref instanceof IViewReference) {
					//Filter views from other perspectives
					for (int i = 0; i < views.length; i++) {
						if (views[i] == ref) {
							resultList.add(ref);
							break;
						}
					}
				} else {
					resultList.add(ref);
				}
			}
			IWorkbenchPartReference[] result =
				new IWorkbenchPartReference[resultList.size()];
			return (IWorkbenchPartReference[]) resultList.toArray(result);
		}
		/*
		 * Returns the topmost editor on the stack, or null if none.
		 */
		IEditorPart getTopEditor() {
			IEditorReference editors[] = getEditors();
			if (editors.length > 0) {
				return editors[editors.length - 1].getEditor(true);
			}
			return null;
		}
	}

	/**
	 * 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(15);
			usedList = new ArrayList(15);
		}
		/**
		 * Return all perspectives in the order they were activated.
		 */
		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.
		 */
		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);
		}
		/**
		 * Removes a perspective from the list.
		 */
		public boolean remove(Perspective perspective) {
			if (active == perspective)
				active = null;
			usedList.remove(perspective);
			return openedList.remove(perspective);
		}

		/**
		 * Swap the opened order of old perspective with the new perspective.
		 */
		public void swap(
			Perspective oldPerspective,
			Perspective newPerspective) {
			int oldIndex = openedList.indexOf(oldPerspective);
			int newIndex = openedList.indexOf(newPerspective);

			if (oldIndex < 0 || newIndex < 0)
				return;

			openedList.set(oldIndex, newPerspective);
			openedList.set(newIndex, oldPerspective);
		}

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

		/**
		 * Returns the next most recently used perspective in the list.
		 */
		public Perspective getNextActive() {
			if (active == null) {
				if (usedList.isEmpty())
					return null;
				else
					return (Perspective) usedList.get(usedList.size() - 1);
			} else {
				if (usedList.size() < 2)
					return null;
				else
					return (Perspective) usedList.get(usedList.size() - 2);
			}
		}

		/**
		 * Returns the number of perspectives opened
		 */
		public int size() {
			return openedList.size();
		}

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

			active = perspective;

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

	//for dynamic UI
	protected HashMap getStateMap() {
		return stateMap;
	}

	//for dynamic UI
	protected void addPerspective(Perspective persp) {
		perspList.add(persp);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.IWorkbenchPage#getViewStack(org.eclipse.ui.IViewPart)
	 */
	public IViewPart [] getViewStack(IViewPart part) {
		// Sanity check.
		Perspective persp = getActivePerspective();
		if (persp == null || !certifyPart(part))
			return null;		
		
		ILayoutContainer container = ((PartSite)part.getSite()).getPane().getContainer();
		if (container instanceof ViewStack) {
			ViewStack folder = (ViewStack) container;
			final ArrayList list = new ArrayList(folder.getChildren().length);
			for (int i = 0; i < folder.getChildren().length; i++) {
				LayoutPart layoutPart = folder.getChildren()[i];
				if (layoutPart instanceof ViewPane) {					
					IViewPart view = findView(((ViewPane)layoutPart).getViewReference().getId());
					if (view != null)
						list.add(view);
				}
			}

			// sort the list by activation order
			Collections.sort(list, new Comparator() {
                public int compare(Object o1, Object o2) {
                    int pos1 = (-1) * activationList.indexOf((IWorkbenchPart) o1);
                    int pos2 = (-1) * activationList.indexOf((IWorkbenchPart) o2);
                    return pos1 - pos2;
                }});
			
			return (IViewPart []) list.toArray(new IViewPart [list.size()]);
		}
		
		return new IViewPart [] {part};
	}
	/**
	 * 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(
				((float) ((deltaWidth + sashInfo.right.getBounds().x) - rightBounds.x))
					/ ((float) 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(
				(float) ((sashInfo.left.getBounds().x - deltaWidth) - leftBounds.x)
					/ ((float) 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(
				((float) ((deltaHeight + sashInfo.bottom.getBounds().y) - bottomBounds.y))
					/ ((float) 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(
				(float) ((sashInfo.top.getBounds().y - deltaHeight) - topBounds.y)
					/ ((float) 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);		
	}
}
