//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.editors;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.EventObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.command.UnexecutableCommand;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.CreateChildCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.DelegatingWrapperItemProvider;
import org.eclipse.emf.edit.provider.IChangeNotifier;
import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.ViewerNotification;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
import org.eclipse.emf.edit.ui.action.CommandActionHandler;
import org.eclipse.emf.edit.ui.action.CopyAction;
import org.eclipse.emf.edit.ui.action.CutAction;
import org.eclipse.emf.edit.ui.action.DeleteAction;
import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor;
import org.eclipse.emf.edit.ui.action.PasteAction;
import org.eclipse.emf.edit.ui.dnd.LocalTransfer;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.actions.IWorkbenchPartAction;
import org.eclipse.epf.authoring.ui.actions.LibraryValidateAction;
import org.eclipse.epf.authoring.ui.actions.MethodLibraryActionBarContributor;
import org.eclipse.epf.authoring.ui.actions.ProcessAutoSynchronizeAction;
import org.eclipse.epf.authoring.ui.actions.SynchronizationAction;
import org.eclipse.epf.authoring.ui.actions.UpdateSuppressionFromBaseAction;
import org.eclipse.epf.authoring.ui.dialogs.DialogHelper;
import org.eclipse.epf.authoring.ui.dialogs.UserDefinedDiagramDialog;
import org.eclipse.epf.authoring.ui.dnd.EditingDomainTableTreeViewerDropAdapter;
import org.eclipse.epf.authoring.ui.forms.DeliveryProcessDescription;
import org.eclipse.epf.authoring.ui.forms.IExtensionFormPage;
import org.eclipse.epf.authoring.ui.forms.ProcessBreakdownStructureFormPage;
import org.eclipse.epf.authoring.ui.forms.ProcessDescription;
import org.eclipse.epf.authoring.ui.preferences.ApplicationPreferenceConstants;
import org.eclipse.epf.authoring.ui.properties.EPFPropertySheetPage;
import org.eclipse.epf.authoring.ui.providers.ProcessEditorPageProvider;
import org.eclipse.epf.authoring.ui.util.UIHelper;
import org.eclipse.epf.authoring.ui.views.LibraryView;
import org.eclipse.epf.authoring.ui.views.ProcessViewer;
import org.eclipse.epf.authoring.ui.views.ViewHelper;
import org.eclipse.epf.diagram.add.part.ActivityDetailDiagramEditorPlugin;
import org.eclipse.epf.diagram.core.part.DiagramEditorInput;
import org.eclipse.epf.diagram.core.part.util.DiagramEditorUtil;
import org.eclipse.epf.diagram.core.services.DiagramHelper;
import org.eclipse.epf.diagram.model.util.GraphicalDataHelper;
import org.eclipse.epf.diagram.model.util.GraphicalDataManager;
import org.eclipse.epf.diagram.wpdd.part.WPDDiagramEditorPlugin;
import org.eclipse.epf.diagramming.part.EPFDiagramEditorPlugin;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.ILibraryServiceListener;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.ProcessAuthoringConfigurator;
import org.eclipse.epf.library.edit.IAdapterFactoryProvider;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.CommandStackChangedEvent;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.command.ResourceAwarePasteFromClipboardCommand;
import org.eclipse.epf.library.edit.process.ActivityWrapperItemProvider;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.process.command.ActivityDropCommand;
import org.eclipse.epf.library.edit.process.command.ContributeToActivityCommand;
import org.eclipse.epf.library.edit.process.command.LocallyReplaceAndDeepCopyCommand;
import org.eclipse.epf.library.edit.process.command.ReplaceActivityCommand;
import org.eclipse.epf.library.edit.ui.IActionTypeProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.ConfigurableComposedAdapterFactory;
import org.eclipse.epf.library.edit.util.EditingDomainComposedAdapterFactory;
import org.eclipse.epf.library.edit.util.ExposedAdapterFactory;
import org.eclipse.epf.library.edit.util.IDiagramManager;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.util.Suppression.SuppressionCommand;
import org.eclipse.epf.library.edit.validation.DependencyChecker;
import org.eclipse.epf.library.events.ILibraryChangeListener;
import org.eclipse.epf.library.prefs.PreferenceUtil;
import org.eclipse.epf.library.ui.LibraryUIImages;
import org.eclipse.epf.library.ui.actions.LibraryLockingOperationRunner;
import org.eclipse.epf.library.ui.actions.ProcessDeleteAction;
import org.eclipse.epf.library.util.ResourceUtil;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.persistence.MultiFileXMIResourceImpl;
import org.eclipse.epf.persistence.refresh.RefreshJob;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.Diagram;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.Milestone;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.edit.domain.TraceableAdapterFactoryEditingDomain;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.epf.validation.LibraryEValidator;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.BaseSelectionListenerAction;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.forms.editor.IFormPage;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.PropertySheet;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;

import com.ibm.icu.util.StringTokenizer;

/**
 * Editor for process authoring.
 * 
 * @author Phong Nguyen Le
 * @author Shilpa Toraskar
 * @author Jinhua Xi
 * @since 1.0
 */
public class ProcessEditor extends MethodElementEditor implements
		IEditingDomainProvider, IMenuListener, ISelectionProvider,
		IViewerProvider, ITabbedPropertySheetPageContributor {

	/**
	 * The editor ID.
	 */
	public static final String EDITOR_ID = ProcessEditor.class.getName();

	public static final String WORKFLOW_EDITOR_ID = GraphicalWorkflowEditor.class
			.getName();

	public static final String ACTIVITY_DETAIL_DIAGRAM_EDITOR_ID = ActivityDetailDiagramEditor.class
			.getName();

	public static final String WPDEPENDENCY_EDITOR_ID = GraphicalWPDependencyEditor.class
			.getName();

	/** Column descriptor constants */
	public static final ColumnDescriptor COL_DESC_NAME = new ColumnDescriptor(
			IBSItemProvider.COL_NAME, ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_NAME),
			3, 200, true, ColumnDescriptor.CELL_EDITOR_TYPE_TEXT);

	public static final ColumnDescriptor COL_DESC_ID = new ColumnDescriptor(
			IBSItemProvider.COL_ID, ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_ID),
			0, 40, true, ColumnDescriptor.CELL_EDITOR_TYPE_NONE);

	public static final ColumnDescriptor COL_DESC_PREFIX = new ColumnDescriptor(
			IBSItemProvider.COL_PREFIX,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_PREFIX), 0, 80, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT);

	public static final ColumnDescriptor COL_DESC_MODEL_INFO = new ColumnDescriptor(
			IBSItemProvider.COL_MODEL_INFO,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_MODEL_INFO), 0, 120, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_NONE); 

	public static final ColumnDescriptor COL_DESC_TYPE = new ColumnDescriptor(
			IBSItemProvider.COL_TYPE, ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_TYPE),
			0, 80, true, ColumnDescriptor.CELL_EDITOR_TYPE_NONE);

	public static final ColumnDescriptor COL_DESC_PREDECESSORS = new ColumnDescriptor(
			IBSItemProvider.COL_PREDECESSORS,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_PREDECESSORS), 2, 100, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT); 

	public static final ColumnDescriptor COL_DESC_IS_REPEATABLE = new ColumnDescriptor(
			IBSItemProvider.COL_IS_REPEATABLE,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_IS_REPEATABLE), 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_CHECK_BOOLEAN); 

	public static final ColumnDescriptor COL_DESC_IS_ONGOING = new ColumnDescriptor(
			IBSItemProvider.COL_IS_ONGOING,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_IS_ONGOING), 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_CHECK_BOOLEAN);

	public static final ColumnDescriptor COL_DESC_IS_EVENT_DRIVEN = new ColumnDescriptor(
			IBSItemProvider.COL_IS_EVENT_DRIVEN,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_IS_EVENT_DRIVEN), 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_CHECK_BOOLEAN); 

	public static final ColumnDescriptor COL_DESC_TEAM = new ColumnDescriptor(
			IBSItemProvider.COL_TEAMS, ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_TEAMS),
			1, 100, true, ColumnDescriptor.CELL_EDITOR_TYPE_TEXT);

	public static final ColumnDescriptor COL_DESC_ENTRY_STATE = new ColumnDescriptor(
			IBSItemProvider.COL_ENTRY_STATE,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_ENTRY_STATE), 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT); 

	public static final ColumnDescriptor COL_DESC_EXIT_STATE = new ColumnDescriptor(
			IBSItemProvider.COL_EXIT_STATE,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_EXIT_STATE), 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT); 

	public static final ColumnDescriptor COL_DESC_PRESENTATION_NAME = new ColumnDescriptor(
			IBSItemProvider.COL_PRESENTATION_NAME,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_PRESENTATION_NAME), 3, 200, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT); 

	public static final ColumnDescriptor COL_DESC_DELIVERABLE = new ColumnDescriptor(
			IBSItemProvider.COL_DELIVERABLE,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_DELIVERABLE), 1, 100, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT); 

	public static final ColumnDescriptor COL_DESC_IS_OPTIONAL = new ColumnDescriptor(
			IBSItemProvider.COL_IS_OPTIONAL,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_IS_OPTIONAL), 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_CHECK_BOOLEAN); 

	public static final ColumnDescriptor COL_DESC_IS_PLANNED = new ColumnDescriptor(
			IBSItemProvider.COL_IS_PLANNED,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_IS_PLANNED), 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_CHECK_BOOLEAN);

	public static final ColumnDescriptor COL_DESC_HAS_MULTIPLE_OCCURRENCES = new ColumnDescriptor(
			IBSItemProvider.COL_HAS_MULTIPLE_OCCURRENCES,
			ProcessUtil.getColumnDisplayName(IBSItemProvider.COL_HAS_MULTIPLE_OCCURRENCES), 1, 60,
			true, ColumnDescriptor.CELL_EDITOR_TYPE_CHECK_BOOLEAN); 

	public static final String WBS_FORM_ID = "wbs"; //$NON-NLS-1$

	public static final String TA_FORM_ID = "tbs"; //$NON-NLS-1$

	public static final String WPBS_FORM_ID = "wpbs"; //$NON-NLS-1$

	public static final String CONSOLIDATED_FORM_ID = "consolidated"; //$NON-NLS-1$

	// change the default order based on 152867 - Publish option and prefrences
	/* WBS: Presentation Name, Index, Predecessors, Model Info, Type, Planned,
			Repeatable, Multiple Occurrences, Ongoing, Event-driven, Optional
		TA: Presentation Name, Model Info, Team, Type, Planned, Multiple
			Occurrences, Optional
		Work Product Usage: Presentation Name, Model Info, Entry State, Exit State, 
			Deliverable, Type, Planned, Multiple Occurrences, Optional
	*/
	// Jinhua Xi, 08/21/2006
	
	// the default list must be available in the library plugin as well.
	// duplicate definition for now, will need to merge together later
	// see PreferenceConstants.org.eclipse.epf.library.prefs
	
	public static final List DEFAULT_TBS_COLUMNS = Arrays
			.asList(new ColumnDescriptor[] {
					COL_DESC_PRESENTATION_NAME,
					// COL_DESC_ID,
					//COL_DESC_PREFIX, 
					COL_DESC_MODEL_INFO, COL_DESC_TEAM, COL_DESC_TYPE,
					COL_DESC_IS_PLANNED,
					COL_DESC_HAS_MULTIPLE_OCCURRENCES, COL_DESC_IS_OPTIONAL });

	public static final List DEFAULT_WPBS_COLUMNS = Arrays
			.asList(new ColumnDescriptor[] {
					COL_DESC_PRESENTATION_NAME,
					// COL_DESC_ID,
					//COL_DESC_PREFIX, 
					COL_DESC_MODEL_INFO, COL_DESC_ENTRY_STATE,
					COL_DESC_EXIT_STATE, 
					COL_DESC_DELIVERABLE, COL_DESC_TYPE, 
					COL_DESC_IS_PLANNED, COL_DESC_HAS_MULTIPLE_OCCURRENCES, COL_DESC_IS_OPTIONAL });

	public static final List DEFAULT_WBS_COLUMNS = Arrays
			.asList(new ColumnDescriptor[] { COL_DESC_PRESENTATION_NAME,
					COL_DESC_ID, 
					//COL_DESC_PREFIX, 
					COL_DESC_PREDECESSORS, COL_DESC_MODEL_INFO,
					COL_DESC_TYPE, COL_DESC_IS_PLANNED, 
					COL_DESC_IS_REPEATABLE, COL_DESC_HAS_MULTIPLE_OCCURRENCES, COL_DESC_IS_ONGOING,
					COL_DESC_IS_EVENT_DRIVEN, COL_DESC_IS_OPTIONAL
					 });

	 
	public static final List ALL_WBS_COLUMNS = new ArrayList(
			DEFAULT_WBS_COLUMNS);

	public static final List ALL_TBS_COLUMNS = new ArrayList(
			DEFAULT_TBS_COLUMNS);

	public static final List ALL_WPBS_COLUMNS = new ArrayList(
			DEFAULT_WPBS_COLUMNS);

	public static final Map idToColumnDescriptorMap = new HashMap();
	static {
		ALL_WBS_COLUMNS.add(COL_DESC_PREFIX);
		ALL_TBS_COLUMNS.add(COL_DESC_PREFIX);
		ALL_WPBS_COLUMNS.add(COL_DESC_PREFIX);
		
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_NAME.id,
				COL_DESC_NAME);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_ID.id, COL_DESC_ID);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_PREFIX.id,
				COL_DESC_PREFIX);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_MODEL_INFO.id,
				COL_DESC_MODEL_INFO);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_TYPE.id,
				COL_DESC_TYPE);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_PREDECESSORS.id,
				COL_DESC_PREDECESSORS);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_IS_REPEATABLE.id,
				COL_DESC_IS_REPEATABLE);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_IS_ONGOING.id,
				COL_DESC_IS_ONGOING);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_IS_EVENT_DRIVEN.id,
				COL_DESC_IS_EVENT_DRIVEN);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_TEAM.id,
				COL_DESC_TEAM);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_ENTRY_STATE.id,
				COL_DESC_ENTRY_STATE);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_EXIT_STATE.id,
				COL_DESC_EXIT_STATE);
		ProcessEditor.idToColumnDescriptorMap.put(
				COL_DESC_PRESENTATION_NAME.id, COL_DESC_PRESENTATION_NAME);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_DELIVERABLE.id,
				COL_DESC_DELIVERABLE);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_IS_OPTIONAL.id,
				COL_DESC_IS_OPTIONAL);
		ProcessEditor.idToColumnDescriptorMap.put(COL_DESC_IS_PLANNED.id,
				COL_DESC_IS_PLANNED);
		ProcessEditor.idToColumnDescriptorMap.put(
				COL_DESC_HAS_MULTIPLE_OCCURRENCES.id,
				COL_DESC_HAS_MULTIPLE_OCCURRENCES);

		ALL_WBS_COLUMNS.add(COL_DESC_NAME);
		ALL_TBS_COLUMNS.add(COL_DESC_NAME);
		ALL_WPBS_COLUMNS.add(COL_DESC_NAME);
	}

	private static boolean addAdapterFactoryListeners = false;

	/**
	 * Action bar contribtutor for process editor
	 * 
	 *
	 */
	public static class BSActionBarContributor extends
			MethodLibraryActionBarContributor {
		private Collection registeredActions = new ArrayList();

		private boolean locked;

		private IAction rollupAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_RollUp) { 

			public void run() {
				boolean wasRolledUp = bsItemProvider.isRolledUp();
				bsItemProvider.setRolledUp(!bsItemProvider.isRolledUp());
				((IChangeNotifier) bsItemProvider)
						.fireNotifyChanged(new ViewerNotification(
								new ENotificationImpl(
										(InternalEObject) selectedActivity,
										Notification.ADD, null, null, null,
										false), selectedActivity, true, false));
				
				if (bsItemProvider instanceof DelegatingWrapperItemProvider) {
					// Refreshing for green activities during rollup
					DelegatingWrapperItemProvider provider = (DelegatingWrapperItemProvider) bsItemProvider;
					provider.fireNotifyChanged(new ViewerNotification(
						new NotificationImpl(Notification.SET, provider,
								provider), provider, true, false));
				}
				if (wasRolledUp) {
					ProcessViewer viewer = (ProcessViewer) ((ProcessEditor) activeEditor).currentViewer;
					viewer.expandToLevel(selectedActivity,
							AbstractTreeViewer.ALL_LEVELS);

					// eventhough we switched off creating new activities in
					// WBS,
					// user can still create thru AD. Hence we need to update
					// IDs
					// afterwards
					doRefresh();
				}
			}

		};

		private IAction moveUpAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_MoveUp,
				AuthoringUIPlugin.getDefault().getImageDescriptor(
						"full/etool16/move_up.gif")) { //$NON-NLS-1$   
			public void run() {	
				bsItemProvider.moveUp(selectedBreakdownElement,
						getActionManager());
				refreshMoveButtonActions();
			}
		};

		private IAction moveDownAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_MoveDown,
				AuthoringUIPlugin.getDefault().getImageDescriptor(
						"full/etool16/move_down.gif")) { //$NON-NLS-1$   
			public void run() {
				bsItemProvider.moveDown(selectedBreakdownElement,
						getActionManager());
				refreshMoveButtonActions();
			}
		};
		
		private IAction preferenceAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Preferences) {
			public void run() {
				// open process preference page
				org.eclipse.ui.dialogs.PreferencesUtil
						.createPreferenceDialogOn(
								getActiveEditor().getEditorSite().getShell(),
								"org.eclipse.epf.authoring.ui.preferences.ProcessEditorPreferencePage",   //$NON-NLS-1$
								null, null).open();
			}
		};
		

		private IAction openBaseActivity = new Action(
				AuthoringUIResources.ProcessEditor_Action_OpenBaseActivity) { 
			public void run() {
				VariabilityElement base = selectedActivity
						.getVariabilityBasedOnElement();
				Process proc = TngUtil
						.getOwningProcess((BreakdownElement) base);
				try {
					int id = ((ProcessEditor) activeEditor).getActivePage();
					ISelection selection = new StructuredSelection(base);

					// ProcessEditorInput input = new ProcessEditorInput(
					// (MethodElement) proc.eContainer());
					// input.setInitialSelection(selection);
					// input.setActivePage(id);
					//					
					// ProcessEditor editor = (ProcessEditor)
					// getPage().findEditor(input);
					// if(editor != null) {
					// // select the base activity after the editor is opened
					// //
					// Viewer viewer = editor.bsPages[id].getViewer();
					// getPage().activate(editor);
					// editor.setActivePage(id);
					// viewer.setSelection(selection, true);
					// }
					// else {
					// editor = (ProcessEditor) getPage().openEditor(input,
					// EDITOR_ID);
					// }

					IEditorInput input = new MethodElementEditorInput(
							(MethodElement) proc.eContainer());
					ProcessEditor editor = (ProcessEditor) getPage()
							.openEditor(input, EDITOR_ID);
					editor.setActivePage(id);
					editor.bsPages[id - 1].getViewer().setSelection(selection,
							true);
				} catch (PartInitException e) {
					AuthoringUIPlugin.getDefault().getLogger().logError(e);
				}
			}
		};

		private IAction openWorkflowEditorAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_OpenActivityDiagram) { 
			public void run() {
				try {
					try {
						IEditorPart parent = getPage().getActiveEditor();
						IEditorInput input = new GraphicalWorkflowEditor.EditorInput(
								selectedObject, getSuppression());
						IEditorPart part = getPage().openEditor(input,
								WORKFLOW_EDITOR_ID);
						if (part instanceof AbstractDiagramEditor) {
							AbstractDiagramEditor editor = (AbstractDiagramEditor) part;
							editor.setParentEditor(parent);
						}
					} catch (PartInitException exception) {
						AuthoringUIPlugin.getDefault().getLogger().logError(
								exception);
					}
				} catch (RuntimeException e) {
					AuthoringUIPlugin.getDefault().getLogger().logError(e);
				}
			}
		};
		private IAction newActivityDiagramEditor = new Action(AuthoringUIResources.
				ProcessEditor_Action_OpenActivityDiagram
				) { 
			public void run() {
				openDiagram(IDiagramManager.ACTIVITY_DIAGRAM);
			}			
		};

		private IAction newActivityDetailDiagramEditor = new Action(
				AuthoringUIResources.ProcessEditor_Action_OpenActivityDetailDiagram) { 
			public void run() {
				openDiagram(IDiagramManager.ACTIVITY_DETAIL_DIAGRAM);
			}
		};
		
		private IAction newWPDiagramEditor = new Action(
				AuthoringUIResources.ProcessEditor_Action_OpenWorkProductDependencyDiagram) { 
			public void run() {
				openDiagram(IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM);
			}
		};

		// Open workflow detail action
		//
		private IAction openWorkflowDetailEditorAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_OpenActivityDetailDiagram) { 
			public void run() {
				try {
					try {
						IEditorPart parent = getPage().getActiveEditor();
						IEditorInput input = new ActivityDetailDiagramEditor.EditorInput(
								selectedObject, getSuppression());
						IEditorPart part = getPage().openEditor(input,
								ACTIVITY_DETAIL_DIAGRAM_EDITOR_ID);
						if (part instanceof AbstractDiagramEditor) {
							AbstractDiagramEditor editor = (AbstractDiagramEditor) part;
							editor.setParentEditor(parent);
						}
					} catch (PartInitException exception) {
						exception.printStackTrace();
					}
				} catch (RuntimeException e) {
					e.printStackTrace();
				}

			}
		};

		private IAction openWPDependencyEditorAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_OpenWorkProductDependencyDiagram) { 
			public void run() {
				try {
					try {
						IEditorPart parent = getPage().getActiveEditor();
						MethodElementEditorInput input = new BreakdownElementEditorInput(
								selectedObject, getSuppression()) {
						};
						IEditorPart part = getPage().openEditor(input,
								WPDEPENDENCY_EDITOR_ID);
						if (part instanceof AbstractDiagramEditor) {
							AbstractDiagramEditor editor = (AbstractDiagramEditor) part;
							editor.setParentEditor(parent);
						}
					} catch (PartInitException exception) {
						exception.printStackTrace();
					}
				} catch (RuntimeException e) {
					e.printStackTrace();
				}
			}
		};

		private IAction replaceAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Replace) { 
			public void run() {
				IResourceAwareCommand cmd = null;
				try {
					cmd = new ReplaceActivityCommand(
							(BreakdownElementWrapperItemProvider) bsItemProvider);
					getActionManager().execute(cmd);
				} catch (Exception e) {
					AuthoringUIPlugin.getDefault().getLogger().logError(e);
				} finally {
					if (cmd != null) {
						try {
							cmd.dispose();
						} catch (Exception e) {
							AuthoringUIPlugin.getDefault().getLogger()
									.logError(e);
						}
					}
				}
			}
		};

		private IAction localReplacementAndDeepCopy = new Action(
				LibraryEditResources.localReplacementAndDeepCopy_text) {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.action.Action#run()
			 */
			public void run() {
				Runnable runnable = new Runnable() {

					public void run() {
						IResourceAwareCommand cmd = null;
						try {
							cmd = new LocallyReplaceAndDeepCopyCommand(
									(BreakdownElementWrapperItemProvider) bsItemProvider);
							getActionManager().execute(cmd);
						} catch (Exception e) {
							AuthoringUIPlugin.getDefault().getLogger()
									.logError(e);
						} finally {
							if (cmd != null) {
								try {
									cmd.dispose();
								} catch (Exception e) {
									AuthoringUIPlugin.getDefault().getLogger()
											.logError(e);
								}
							}
						}
					}

				};

				UserInteractionHelper.runInUI(runnable, getText());
			}
		};

		private IAction contributeAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Contribute) { 
			public void run() {
				IResourceAwareCommand cmd = null;
				try {
					cmd = new ContributeToActivityCommand(
							(BreakdownElementWrapperItemProvider) bsItemProvider);
					getActionManager().execute(cmd);
					// ProcessUtil.contributeToActivity((BreakdownElementWrapperItemProvider)bsItemProvider,
					// ((ProcessFormEditor)activeEditor).editingDomain.getAdapterFactory());
				} catch (Exception e) {
					AuthoringUIPlugin.getDefault().getLogger().logError(e);
				} finally {
					if (cmd != null) {
						try {
							cmd.dispose();
						} catch (Exception e) {
							AuthoringUIPlugin.getDefault().getLogger()
									.logError(e);
						}
					}
				}
			}
		};

		private class EditorSuppressionCommand extends SuppressionCommand {
			EditorSuppressionCommand(Suppression suppression, List selection,
					boolean suppressed) {
				super(suppression, selection, suppressed);
			}

			private void refresh() {
				if (!getResult().isEmpty()) {
					ProcessEditor editor = (ProcessEditor) getActiveEditor();
					if (isReadOnlyElementAffected()) {
						if (hasInherited(selection)) {
							editor.refreshAllProcessEditors();
						} else {
							editor.doRefreshAll(false);
						}
					}
					editor.firePropertyChange(PROP_DIRTY);
					
					// Do Diagram Editors refresh
					List list = new ArrayList();
					for (Iterator iter = selection.iterator(); iter.hasNext();) {
						Object element = iter.next();
						UIHelper.closeDiagramEditors(element, list);
						UIHelper.refreshOpenDiagramEditorsOfParent(element, list);
						list.clear();
					}
				}
			}

			/**
			 * @see org.eclipse.epf.library.edit.util.Suppression.SuppressionCommand#didExecute()
			 */
			protected void didExecute() {
				refresh();
			}

			/**
			 * @see org.eclipse.epf.library.edit.util.Suppression.SuppressionCommand#didUndo()
			 */
			protected void didUndo() {
				refresh();
			}

		}

		private IAction suppressTaskAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Suppress_Task) { 

			public void run() {
				// check if suppressing the selected elements will cause
				// duplicate descriptors.
				// If so, prompt user to delete the duplicates before
				// continuing.
				//
				
				final List taskDescriptors = ProcessUtil.getTaskDescriptors(selection);
				Collection duplicates = ProcessUtil
						.getDuplicateDescriptorsAfterSuppress(taskDescriptors);
				if (!duplicates.isEmpty()) {
					MultiStatus status = new MultiStatus(AuthoringUIPlugin
							.getDefault().getId(), 0, "", null); //$NON-NLS-1$
					for (Iterator iter = duplicates.iterator(); iter.hasNext();) {
						Descriptor desc = (Descriptor) iter.next();
						String descTxt = TngUtil.getTypeText(desc)
								+ ": " + desc.getPresentationName(); //$NON-NLS-1$
						status.add(new Status(IStatus.INFO, AuthoringUIPlugin
								.getDefault().getId(), 0, descTxt, null));
					}
					if (AuthoringUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayConfirmation(
									getText(),
									AuthoringUIResources.ProcessEditor_promptToDeleteBeforeSuppress, 
									status) == Dialog.CANCEL) {
						return;
					}

					// delete duplicate descriptors
					Command cmd = null;
					try {
						cmd = ProcessDeleteAction.delete(duplicates);
					} catch (OperationCanceledException e) {
						return;
					}
					finally {
						if(cmd != null)
							try { cmd.dispose(); } catch(Exception e) {}
					}
				}

				BusyIndicator.showWhile(getActiveEditor().getEditorSite()
						.getShell().getDisplay(), new Runnable() {

					public void run() {
						EditorSuppressionCommand cmd = new EditorSuppressionCommand(
								getSuppression(), taskDescriptors, true);
						cmd.setLabel(getText());
						getActionManager().execute(cmd);
					}
				});

				boolean show = true;
				// update context bar menu after performing suppress
				if (getAdapterFactory() == TngAdapterFactory.INSTANCE
						.getWBS_ComposedAdapterFactory()) {
					for (int i = 0; i < selection.size(); i++) {
						if (!(selection.get(i) instanceof Activity || selection
								.get(i) instanceof ActivityWrapperItemProvider))
							show = false;
					}
				} else
					show = false;
				
				revealTaskAction.setEnabled(show);
				suppressTaskAction.setEnabled(show);

				// enable synchronize actions correctly
				autoSynchronize.setEnabled(autoSynchronize
						.updateSelection(new StructuredSelection(selection
								.toArray())));
				manualSynchronizeAction.setEnabled(manualSynchronizeAction
						.updateSelection(new StructuredSelection(selection
								.toArray())));
			}
		};

		private IAction suppressAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Suppress) { 

			public void run() {
				// check if suppressing the selected elements will cause
				// duplicate descriptors.
				// If so, prompt user to delete the duplicates before
				// continuing.
				//
				Collection duplicates = ProcessUtil
						.getDuplicateDescriptorsAfterSuppress(selection);
				if (!duplicates.isEmpty()) {
					MultiStatus status = new MultiStatus(AuthoringUIPlugin
							.getDefault().getId(), 0, "", null); //$NON-NLS-1$
					for (Iterator iter = duplicates.iterator(); iter.hasNext();) {
						Descriptor desc = (Descriptor) iter.next();
						String descTxt = TngUtil.getTypeText(desc)
								+ ": " + desc.getPresentationName(); //$NON-NLS-1$
						status.add(new Status(IStatus.INFO, AuthoringUIPlugin
								.getDefault().getId(), 0, descTxt, null));
					}
					if (AuthoringUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayConfirmation(
									getText(),
									AuthoringUIResources.ProcessEditor_promptToDeleteBeforeSuppress, 
									status) == Dialog.CANCEL) {
						return;
					}

					// delete duplicate descriptors
					Command cmd = null;
					try {
						cmd = ProcessDeleteAction.delete(duplicates);
					} catch (OperationCanceledException e) {
						return;
					}
					finally {
						if(cmd != null)
							try { cmd.dispose(); } catch(Exception e) {}
					}
				}

				// final ProcessEditor editor = (ProcessEditor)
				// getActiveEditor();

				BusyIndicator.showWhile(getActiveEditor().getEditorSite()
						.getShell().getDisplay(), new Runnable() {

					public void run() {
						// if (getSuppression().suppress(selection)) {
						// if (hasInherited(selection)) {
						// editor.refreshAllProcessEditors();
						// } else {
						// editor.doRefreshAll(false);
						// }
						// }
						// editor.firePropertyChange(PROP_DIRTY);

						EditorSuppressionCommand cmd = new EditorSuppressionCommand(
								getSuppression(), selection, true);
						cmd.setLabel(getText());
						getActionManager().execute(cmd);
					}

				});

				// update context bar menu after performing suppress
				revealAction.setEnabled(getSuppression().canReveal(selection));
				suppressAction.setEnabled(getSuppression().canSuppress(
						selection));

				// enable synchronize actions correctly
				autoSynchronize.setEnabled(autoSynchronize
						.updateSelection(new StructuredSelection(selection
								.toArray())));
				manualSynchronizeAction.setEnabled(manualSynchronizeAction
						.updateSelection(new StructuredSelection(selection
								.toArray())));
			}
		};
		
		private UpdateSuppressionFromBaseAction updateSuppressionFromBaseAction = new UpdateSuppressionFromBaseAction();

		private IAction revealAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Reveal) { 

			public void run() {
				if (canReveal(selection, getAdapterFactory(), getSuppression())) {
					// final ProcessEditor editor = (ProcessEditor)
					// getActiveEditor();

					BusyIndicator.showWhile(getActiveEditor().getEditorSite()
							.getShell().getDisplay(), new Runnable() {

						public void run() {
							// if (getSuppression().reveal(selection)) {
							// if (hasInherited(selection)) {
							// editor.refreshAllProcessEditors();
							// } else {
							// editor.doRefreshAll(false);
							// }
							// }
							// editor.firePropertyChange(PROP_DIRTY);

							EditorSuppressionCommand cmd = new EditorSuppressionCommand(
									getSuppression(), selection, false);
							cmd.setLabel(getText());
							getActionManager().execute(cmd);
						}

					});
					// update context bar menu after performing reveal
					revealAction.setEnabled(getSuppression().canReveal(
							selection));
					suppressAction.setEnabled(getSuppression().canSuppress(
							selection));
					// enable synchronize actions correctly
					autoSynchronize.setEnabled(autoSynchronize
							.updateSelection(new StructuredSelection(selection
									.toArray())));
					manualSynchronizeAction.setEnabled(manualSynchronizeAction
							.updateSelection(new StructuredSelection(selection
									.toArray())));
				}
			}
		};
		
		private IAction revealTaskAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Reveal_Task) { 

			public void run() {
				final List taskDescriptors = ProcessUtil.getTaskDescriptors(selection);
				if (canReveal(taskDescriptors, getAdapterFactory(), getSuppression())) {
					
					BusyIndicator.showWhile(getActiveEditor().getEditorSite()
							.getShell().getDisplay(), new Runnable() {

						public void run() {
							EditorSuppressionCommand cmd = new EditorSuppressionCommand(
									getSuppression(), taskDescriptors, false);
							cmd.setLabel(getText());
							getActionManager().execute(cmd);
						}

					});
					
					// enable synchronize actions correctly
					autoSynchronize.setEnabled(autoSynchronize
							.updateSelection(new StructuredSelection(selection
									.toArray())));
					manualSynchronizeAction.setEnabled(manualSynchronizeAction
							.updateSelection(new StructuredSelection(selection
									.toArray())));
				}
			}
		};

		private IBSItemProvider bsItemProvider = null;

		private Object selectedElement = null;

		private Activity selectedActivity = null;

		private BreakdownElement selectedBreakdownElement = null;

		private List selection;

		private IAction suppressDiagramAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Suppress2) { 
			public boolean isEnabled() {
				if (!super.isEnabled()) {
					return false;
				}
				return !(bsItemProvider instanceof BreakdownElementWrapperItemProvider && ((BreakdownElementWrapperItemProvider) bsItemProvider)
						.isReadOnly());
			}

			public void run() {
				if (!promptSaveActiveEditor()) {
					return;
				}

				IStructuredContentProvider contentProvider = new ArrayContentProvider();

				ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
						TngUtil.umaItemProviderAdapterFactory) {
					public String getColumnText(Object object, int columnIndex) {
						return GraphicalDataHelper
								.getDiagramTypeText((Diagram) object);
					}
				};

				Collection diagrams = GraphicalDataHelper
						.getDiagrams(selectedActivity);
				ArrayList unsuppressedDiagrams = new ArrayList();
				for (Iterator iter = diagrams.iterator(); iter.hasNext();) {
					Diagram diagram = (Diagram) iter.next();
					if (!diagram.getSuppressed().booleanValue()) {
						unsuppressedDiagrams.add(diagram);
					}
				}

				ListSelectionDialog dlg = new ListSelectionDialog(
						activeEditor.getEditorSite().getShell(),
						diagrams,
						contentProvider,
						labelProvider,
						AuthoringUIResources.ProcessEditor_SuppressDialog_Message); 
				dlg.setInitialElementSelections(unsuppressedDiagrams);
				dlg
						.setTitle(AuthoringUIResources.ProcessEditor_SuppressDialog_Title); 
				dlg.setBlockOnOpen(true);
				dlg.open();

				Object[] diagramsToReveal = dlg.getResult();

				if (diagramsToReveal == null) {
					return;
				}

				boolean changed = true;

				// check if there is really any change
				//
				if (diagramsToReveal.length == unsuppressedDiagrams.size()) {
					for (int i = 0; i < diagramsToReveal.length; i++) {
						if (!unsuppressedDiagrams.contains(diagramsToReveal[i])) {
							changed = false;
							break;
						}
					}
				}

				if (changed) {
					for (Iterator iter = diagrams.iterator(); iter.hasNext();) {
						Diagram diagram = (Diagram) iter.next();
						diagram.setSuppressed(Boolean.TRUE);
					}

					for (int i = 0; i < diagramsToReveal.length; i++) {
						Diagram diagram = (Diagram) diagramsToReveal[i];
						diagram.setSuppressed(Boolean.FALSE);
					}

					// save the editor
					//
					saveActiveEditor();
				}
			}
		};
		
		
		
		private IAction newSuppressDiagramAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Suppress2) { 
			public boolean isEnabled() {
				if (!super.isEnabled()) {
					return false;
				}
				return !(bsItemProvider instanceof BreakdownElementWrapperItemProvider && ((BreakdownElementWrapperItemProvider) bsItemProvider)
						.isReadOnly());
			}

			public void run() {
				if (!promptSaveActiveEditor()) {
					return;
				}

				IStructuredContentProvider contentProvider = new ArrayContentProvider();

				ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
						TngUtil.umaItemProviderAdapterFactory) {
					public String getColumnText(Object object, int columnIndex) {
						//TODO: Change to exact string.
						return DiagramHelper.getDiagramTypeString((org.eclipse.gmf.runtime.notation.Diagram)object);
					}
				};

				Collection diagrams = DiagramHelper.getDiagrams(selectedActivity);
				ArrayList unsuppressedDiagrams = new ArrayList();
				for (Iterator iter = diagrams.iterator(); iter.hasNext();) {
					org.eclipse.gmf.runtime.notation.Diagram diagram = (org.eclipse.gmf.runtime.notation.Diagram) iter.next();
					
					//TODO: do get Unsuppressed list.
					
//					if (!diagram.getSuppressed().booleanValue()) {
//						unsuppressedDiagrams.add(diagram);
//					}
				}

				ListSelectionDialog dlg = new ListSelectionDialog(
						activeEditor.getEditorSite().getShell(),
						diagrams,
						contentProvider,
						labelProvider,
						AuthoringUIResources.ProcessEditor_SuppressDialog_Message); 
				dlg.setInitialElementSelections(unsuppressedDiagrams);
				dlg
						.setTitle(AuthoringUIResources.ProcessEditor_SuppressDialog_Title); 
				dlg.setBlockOnOpen(true);
				dlg.open();

				Object[] diagramsToReveal = dlg.getResult();

				if (diagramsToReveal == null) {
					return;
				}

				boolean changed = true;

				// check if there is really any change
				//
				if (diagramsToReveal.length == unsuppressedDiagrams.size()) {
					for (int i = 0; i < diagramsToReveal.length; i++) {
						if (!unsuppressedDiagrams.contains(diagramsToReveal[i])) {
							changed = false;
							break;
						}
					}
				}

				if (changed) {
					for (Iterator iter = diagrams.iterator(); iter.hasNext();) {
						org.eclipse.gmf.runtime.notation.Diagram diagram = (org.eclipse.gmf.runtime.notation.Diagram) iter.next();
						//TODO: set Suppression.
						//diagram.setSuppressed(Boolean.TRUE);
					}

					for (int i = 0; i < diagramsToReveal.length; i++) {
						org.eclipse.gmf.runtime.notation.Diagram diagram = (org.eclipse.gmf.runtime.notation.Diagram) diagramsToReveal[i];
						//TODO: set Suppression.
						//diagram.setSuppressed(Boolean.FALSE);
					}

					// save the editor
					//
					saveActiveEditor();
				}
			}
		};
		
		
		private IAction newAssignUserDiagram = new Action(
				AuthoringUIResources.ProcessEditor_Action_AssignUserDiagram) { 
			/**
			 * @see org.eclipse.jface.action.Action#run()
			 */
			public void run() {
				//TODO: necessary changes UserDefinedDiagramDialog's DiagramInfo.
				UserDefinedDiagramDialog dialog = new UserDefinedDiagramDialog(
						Display.getCurrent().getActiveShell(), activeEditor,
						selectedActivity, getProcess().getDefaultContext(), TngUtil.isWrapped(selectedObject));
				dialog.open();
			}
		};
		
		private IAction newSuppressAllDiagrams = new Action(
				AuthoringUIResources.ProcessEditor_Action_SuppressAll) { 
			public void run() {
				newSetAllDiagramSuppressed(true);
			}
		};

		private IAction newRevealAllDiagrams = new Action(
				AuthoringUIResources.ProcessEditor_Action_RevealAll) { 
			public void run() {
				newSetAllDiagramSuppressed(false);
			}
		};
		
		

		private IAction suppressAllDiagrams = new Action(
				AuthoringUIResources.ProcessEditor_Action_SuppressAll) { 
			public void run() {
				setAllDiagramSuppressed(true);
			}
		};

		private IAction revealAllDiagrams = new Action(
				AuthoringUIResources.ProcessEditor_Action_RevealAll) { 
			public void run() {
				setAllDiagramSuppressed(false);
			}
		};

		private IAction addAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Add) { 
			public void run() {
				LibraryLockingOperationRunner runner = new LibraryLockingOperationRunner();
				runner.run(new IRunnableWithProgress() {

					public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
						AdapterFactory adapterFactory = getAdapterFactory();
						if (adapterFactory != null) {
							MethodConfiguration config = LibraryService.getInstance()
									.getCurrentMethodConfiguration();
							if (config == null) {
								config = TngUtil.getOwningProcess(
										selectedBreakdownElement).getDefaultContext();
							}
							List selection = DialogHelper.selectElementsFor(
									selectedBreakdownElement, config, adapterFactory);

							if (selection == null || selection.isEmpty()) {
								return;
							}

							Object adapter = adapterFactory.adapt(
									selectedBreakdownElement,
									IEditingDomainItemProvider.class);
							if (adapter instanceof IBSItemProvider) {
								IResourceAwareCommand cmd = ((IBSItemProvider) adapter)
										.createDropCommand(selectedBreakdownElement,
												selection);
								getActionManager().execute(cmd);
							}
						}
					}
					
				});

			}
		};

		private IAction copyActivityAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Copy) { 
			public void run() {
				MethodConfiguration config = LibraryService.getInstance()
						.getCurrentMethodConfiguration();
				if (config == null) {
					config = TngUtil.getOwningProcess(selectedActivity)
							.getDefaultContext();
				}
				List selection = DialogHelper.selectActivitiesFor(
						selectedActivity, config, IActionTypeProvider.COPY);

				if (selection == null || selection.isEmpty()) {
					return;
				} else {
					for (Iterator itor=selection.iterator(); itor.hasNext();) {
						Object o = itor.next();
					
						if (o instanceof Activity) {
							Activity act = (Activity) o;
				
//							Process proc = TngUtil.getOwningProcess(selectedBreakdownElement);
//							if (DependencyChecker.hasCyclicDependency(act, proc)) {
//								Object[] args = { selectedActivity.getName(),
//										act.getName() };
//								String message = AuthoringUIResources
//										.bind(
//												AuthoringUIResources.apply_pattern_error_msg,
//												args);
//	
//								String title = AuthoringUIResources.apply_pattern_error_title;
//								AuthoringUIPlugin.getDefault().getMsgDialog()
//										.displayError(title, message, ""); //$NON-NLS-1$
//								itor.remove();
//							}
//							else if (ProcessUtil.hasContributorOrReplacer(act)) {
//								Object[] args = { selectedActivity.getName(),
//										act.getName() };
//								String message = AuthoringUIResources
//										.bind(
//												AuthoringUIResources.activity_variability_error_msg,
//												args);
//	
//								String title = AuthoringUIResources.activity_variability_error_title;
//								AuthoringUIPlugin.getDefault().getMsgDialog()
//										.displayError(title, message, ""); //$NON-NLS-1$
//
//								itor.remove();
//								return;
//							}
							
							IStatus status = DependencyChecker.checkCircularDependency(act, selectedActivity);
							if(!status.isOK()) {
								String title = AuthoringUIResources.activity_variability_error_title;
								AuthoringUIPlugin.getDefault().getMsgDialog()
										.displayError(title, status.getMessage());
								itor.remove();
							}
						}	
						if(selection.isEmpty()) {
							return;
						}
					}
				}

				ActivityDropCommand cmd = new ActivityDropCommand(
						selectedActivity, selection, null, getAdapterFactory());
				IStatus status = cmd.checkCopy();
				if(!status.isOK()) {
					String title = AuthoringUIResources.activity_variability_error_title;
					AuthoringUIPlugin.getDefault().getMsgDialog()
							.displayError(title, status.getMessage());
					return;
				}
				cmd.setType(IActionTypeProvider.COPY);
				getActionManager().execute(cmd);
			}
		};

		private IAction extendActivityAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Extend) { 
			public void run() {
				MethodConfiguration config = LibraryService.getInstance()
						.getCurrentMethodConfiguration();
				if (config == null) {
					config = TngUtil.getOwningProcess(selectedActivity)
							.getDefaultContext();
				}
				List selection = DialogHelper.selectActivitiesFor(
						selectedActivity, config, IActionTypeProvider.EXTEND);

				if (selection == null || selection.isEmpty()) {
					return;
				} 
				else {					
					for (Iterator itor=selection.iterator(); itor.hasNext();) {
						Object o = itor.next();
					
						if (o instanceof Activity) {
							Activity act = (Activity) o;
				
//							Process proc = TngUtil.getOwningProcess(selectedBreakdownElement);
//							if (DependencyChecker.hasCyclicDependency(act, proc)) {
//								Object[] args = { selectedActivity.getName(),
//										act.getName() };
//								String message = AuthoringUIResources
//										.bind(
//												AuthoringUIResources.apply_pattern_error_msg,
//												args);
//	
//								String title = AuthoringUIResources.apply_pattern_error_title;
//								AuthoringUIPlugin.getDefault().getMsgDialog()
//										.displayError(title, message, ""); //$NON-NLS-1$
//								itor.remove();
//							}
//							else if (ProcessUtil.hasContributorOrReplacer(act)) {
//								Object[] args = { selectedActivity.getName(),
//										act.getName() };
//								String message = AuthoringUIResources
//										.bind(
//												AuthoringUIResources.activity_variability_error_msg,
//												args);
//	
//								String title = AuthoringUIResources.activity_variability_error_title;
//								AuthoringUIPlugin.getDefault().getMsgDialog()
//										.displayError(title, message, ""); //$NON-NLS-1$
//
//								itor.remove();
//								return;
//							}
							
							IStatus status = DependencyChecker.newCheckAct ? 
									DependencyChecker.checkCircularDependencyAfterFilterSelection
											(act, selectedActivity, VariabilityType.EXTENDS_LITERAL)
									: DependencyChecker.checkCircularDependency(act, selectedActivity);
							if(!status.isOK()) {
								String title = AuthoringUIResources.activity_variability_error_title;
								AuthoringUIPlugin.getDefault().getMsgDialog()
										.displayError(title, status);
								itor.remove();
							}
						}
						if(selection.isEmpty()) {
							return;
						}
					}
				}
				ActivityDropCommand cmd = new ActivityDropCommand(
						selectedActivity, selection, null, getAdapterFactory());
				IStatus status = cmd.checkExtend();
				if(!status.isOK()) {
					String title = AuthoringUIResources.activity_variability_error_title;
					AuthoringUIPlugin.getDefault().getMsgDialog()
							.displayError(title, status.getMessage());
					return;
				}
				cmd.setType(IActionTypeProvider.EXTEND);
				getActionManager().execute(cmd);
			}
		};

		private IAction deepCopyActivityAction = new Action(
				AuthoringUIResources.ProcessEditor_action_deepCopy) { 
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.action.Action#run()
			 */
			public void run() {
				LibraryLockingOperationRunner runner = new LibraryLockingOperationRunner();
				runner.run(new IRunnableWithProgress() {

					public void run(IProgressMonitor monitor)
							throws InvocationTargetException,
							InterruptedException {
						MethodConfiguration config = LibraryService
								.getInstance().getCurrentMethodConfiguration();
						if (config == null) {
							config = TngUtil.getOwningProcess(selectedActivity)
									.getDefaultContext();
						}
						List selection = DialogHelper.selectActivitiesFor(
								selectedActivity, config,
								IActionTypeProvider.DEEP_COPY);

						if (selection == null || selection.isEmpty()) {
							return;
						} 
						else {					
							for (Iterator itor=selection.iterator(); itor.hasNext();) {
								Object o = itor.next();
							
								if (o instanceof Activity) {
									Activity act = (Activity) o;
									
//									Process proc = TngUtil.getOwningProcess(selectedBreakdownElement);
//									if (ProcessUtil.hasCyclicDependency(act, proc)) {
//										Object[] args = { selectedActivity.getName(),
//												act.getName() };
//										String message = AuthoringUIResources
//												.bind(
//														AuthoringUIResources.apply_pattern_error_msg,
//														args);
//			
//										String title = AuthoringUIResources.apply_pattern_error_title;
//										AuthoringUIPlugin.getDefault().getMsgDialog()
//												.displayError(title, message, ""); //$NON-NLS-1$
//										itor.remove();
//									}
									
									IStatus status = DependencyChecker.checkCircularDependency(act, selectedActivity);
									if(!status.isOK()) {
										String title = AuthoringUIResources.activity_variability_error_title;
										AuthoringUIPlugin.getDefault().getMsgDialog()
												.displayError(title, status.getMessage());
										itor.remove();
									}
								}
								if(selection.isEmpty()) {
									return;
								}
							}
						}

						ActivityDropCommand cmd = new ActivityDropCommand(
								selectedActivity, selection, null,
								getAdapterFactory());
						cmd.setType(IActionTypeProvider.DEEP_COPY);
						getActionManager().execute(cmd);

					}
				});				
			}
		};

		private Object selectedObject;

		private IAction expandAllAction = new Action(
				AuthoringUIResources.ProcessFormEditor_expanAllActionLabel) { 
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.action.Action#run()
			 */
			public void run() {
				Viewer viewer = ((ProcessEditor) activeEditor).currentViewer;
				if (viewer instanceof TreeViewer) {
					((TreeViewer) viewer).expandToLevel(selectedObject,
							AbstractTreeViewer.ALL_LEVELS);
				}
			}
		};

		private IAction collapseAllAction = new Action(
				AuthoringUIResources.ProcessFormEditor_collapseAllActionLabel) { 
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.action.Action#run()
			 */
			public void run() {
				Viewer viewer = ((ProcessEditor) activeEditor).currentViewer;
				if (viewer instanceof TreeViewer) {
					((TreeViewer) viewer).collapseToLevel(selectedObject,
							AbstractTreeViewer.ALL_LEVELS);
				}
			}
		};

		private SynchronizationAction manualSynchronizeAction = new SynchronizationAction() {
			public void run() {
				super.run();

				// refresh properties view after synch
				EPFPropertySheetPage page = (EPFPropertySheetPage) ((ProcessEditor) activeEditor)
						.getPropertySheetPage();
				if (page != null) {
					page.refresh();
				}
			}
		};

		private ProcessAutoSynchronizeAction autoSynchronize = new ProcessAutoSynchronizeAction() {
			private void superRun() {
				super.run();
			}
			
			/**
			 * @see org.eclipse.epf.authoring.ui.actions.ProcessAutoSynchronizeAction#run()
			 */
			public void run() {
				LibraryLockingOperationRunner runner = new LibraryLockingOperationRunner();
				runner.run(new IRunnableWithProgress() {

					public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
						if (!AuthoringUIPlugin
								.getDefault()
								.getMsgDialog()
								.displayConfirmation(
										AuthoringUIResources.ProcessEditor_defaultSynchronization,
										AuthoringUIResources.ProcessEditor_confirmAutoSynch)) { 
							return;
						}
						// ((SynchronizeCommand)command).setUIContext(getActiveEditor().getSite().getShell());
						superRun();
						
						// refresh properties view after synch
						EPFPropertySheetPage page = (EPFPropertySheetPage)((ProcessEditor) activeEditor).getPropertySheetPage();
						if (page != null) {
							page.refresh();
						}
					}
				});
				
			}
		};

		private IAction showInLibraryView = new Action(
				AuthoringUIResources.ProcessEditor_Action_ShowLinkedElementinLibraryView,
				AuthoringUIPlugin.getDefault().getImageDescriptor(
						"full/etool16/show_linked_element.gif")) { //$NON-NLS-1$   //) 

			public void run() {
				final Object linkedElement = ProcessUtil
						.getAssociatedElement((Descriptor) selectedBreakdownElement);
				if (linkedElement != null) {
					Display.getCurrent().asyncExec(new Runnable() {

						public void run() {
							LibraryView.getView().setSelectionToViewer(
									linkedElement);
						}

					});
				}
			}

		};

		private IAction assignUserDiagram = new Action(
				AuthoringUIResources.ProcessEditor_Action_AssignUserDiagram) { 
			/**
			 * @see org.eclipse.jface.action.Action#run()
			 */
			public void run() {
				UserDefinedDiagramDialog dialog = new UserDefinedDiagramDialog(
						Display.getCurrent().getActiveShell(), activeEditor,
						selectedActivity, getProcess().getDefaultContext(), TngUtil.isWrapped(selectedObject));

				dialog.open();
			}
		};
		
//		private IAction activityDetailDiagramInfo =  new ActivityDetailDiagramInfoAction(){
//			public Object getObject() {
//				return selectedActivity;
//			}
//			public IWorkbenchPage getPagex() {
//				// TODO Auto-generated method stub
//				return getPage();
//			}
//		};

		private boolean oldLocked;

		public BSActionBarContributor() {
			super(AuthoringUIResources.ProcessEditor);
			
			// don't show validate action
			//
			validateAction = null;

			// set disabled image descriptors
			moveUpAction.setDisabledImageDescriptor(AuthoringUIPlugin
					.getDefault().getImageDescriptor(
							"full/etool16/move_up_disabled.gif")); //$NON-NLS-1$
			moveDownAction.setDisabledImageDescriptor(AuthoringUIPlugin
					.getDefault().getImageDescriptor(
							"full/etool16/move_down_disabled.gif")); //$NON-NLS-1$
			showInLibraryView.setDisabledImageDescriptor(AuthoringUIPlugin
					.getDefault().getImageDescriptor(
							"full/etool16/show_linked_element_disabled.gif")); //$NON-NLS-1$
		}
		
		private static PreferencesHint getDiagramPreferencesHint(int diagramType) {
			switch(diagramType) {
			case IDiagramManager.ACTIVITY_DIAGRAM:
				return EPFDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT;
			case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
				return ActivityDetailDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT;
			case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
				return WPDDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT;
			}
			return null;
		}
		
		protected void openDiagram(int diagramType) {
			try {
				DiagramEditorInput input = new org.eclipse.epf.diagram.core.part.DiagramEditorInput(
						selectedObject, getSuppression(), diagramType);
				DiagramEditorUtil.openDiagramEditor(getPage(), input, getDiagramPreferencesHint(diagramType), new NullProgressMonitor());					
			} catch (RuntimeException e) {
				AuthoringUIPlugin.getDefault().getLogger().logError(e);
			}
		}

		protected void registerAction(IAction action) {
			if (action != null && !registeredActions.contains(action)) {
				registeredActions.add(action);
			}
		}

		private void registerActions() {
			registerAction(autoSynchronize);
			registerAction(manualSynchronizeAction);
			registerAction(updateSuppressionFromBaseAction);
		}

		/**
		 * @see org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor#update()
		 */
		public void update() {
			super.update();

			ISelectionProvider selectionProvider = activeEditor instanceof ISelectionProvider ? (ISelectionProvider) activeEditor
					: activeEditor.getEditorSite().getSelectionProvider();
			ISelection selection = selectionProvider.getSelection();
			IStructuredSelection structuredSelection = selection instanceof IStructuredSelection ? (IStructuredSelection) selection
					: StructuredSelection.EMPTY;

			for (Iterator iter = registeredActions.iterator(); iter.hasNext();) {
				Object action = (Object) iter.next();
				if (action instanceof CommandActionHandler) {
					((CommandActionHandler) action)
							.updateSelection(structuredSelection);
				}
			}
		}

		/**
		 * @see org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor#activate()
		 */
		public void activate() {
			manualSynchronizeAction.setProcess(getProcess());
			ISelectionProvider selectionProvider = activeEditor instanceof ISelectionProvider ? (ISelectionProvider) activeEditor
					: activeEditor.getEditorSite().getSelectionProvider();
			for (Iterator iter = registeredActions.iterator(); iter.hasNext();) {
				Object action = (Object) iter.next();
				if (action instanceof IWorkbenchPartAction) {
					((IWorkbenchPartAction) action)
							.setActiveWorkbenchPart(activeEditor);
				}
				if (action instanceof ISelectionChangedListener) {
					selectionProvider
							.addSelectionChangedListener((ISelectionChangedListener) action);
				}
			}
			super.activate();

			// call set Active page explicitly in order to get correct action
			// bars
			setActivePage(activeEditor);
		}

		/**
		 * @see org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor#deactivate()
		 */
		public void deactivate() {
			super.deactivate();

			ISelectionProvider selectionProvider = activeEditor instanceof ISelectionProvider ? (ISelectionProvider) activeEditor
					: activeEditor.getEditorSite().getSelectionProvider();

			for (Iterator iter = registeredActions.iterator(); iter.hasNext();) {
				Object action = (Object) iter.next();
				if (action instanceof IWorkbenchPartAction) {
					((IWorkbenchPartAction) action)
							.setActiveWorkbenchPart(null);
				}
				if (action instanceof ISelectionChangedListener) {
					selectionProvider
							.removeSelectionChangedListener((ISelectionChangedListener) action);
				}
			}
		}

		/**
		 * @see org.eclipse.epf.authoring.ui.actions.MethodLibraryActionBarContributor#init(org.eclipse.ui.IActionBars)
		 */
		public void init(IActionBars actionBars) {
			super.init(actionBars);
			registerActions();
			contributeToToolBar(actionBars.getToolBarManager());
		}

		private IActionManager getActionManager() {
			return ((MethodElementEditor) activeEditor).getActionManager();
		}

		private AdapterFactory getAdapterFactory() {
			return ((ProcessEditor) activeEditor).getAdapterFactory();
		}

		private void setAllDiagramSuppressed(final boolean suppressed) {
			String title = AuthoringUIResources.processFormEditorSaveDialog_title; 
			String message = AuthoringUIResources.processFormEditorSaveDialog_message1; 

			if (!AuthoringUIPlugin.getDefault().getMsgDialog()
					.displayConfirmation(title, message)) {
				return;
			}

			BusyIndicator.showWhile(activeEditor.getEditorSite().getShell()
					.getDisplay(), new Runnable() {

				public void run() {
					GraphicalDataHelper.setAllDiagramSuppressed(getProcess(),
							suppressed);
					doSaveActiveEditor();
				}

			});
		}
		
		private void newSetAllDiagramSuppressed(final boolean suppressed) {
			String title = AuthoringUIResources.processFormEditorSaveDialog_title; 
			String message = AuthoringUIResources.processFormEditorSaveDialog_message1; 

			if (!AuthoringUIPlugin.getDefault().getMsgDialog()
					.displayConfirmation(title, message)) {
				return;
			}

			BusyIndicator.showWhile(activeEditor.getEditorSite().getShell()
					.getDisplay(), new Runnable() {

				public void run() {
					DiagramHelper.setAllDiagramSuppressed(getProcess(),
							suppressed);
					doSaveActiveEditor();
				}

			});
		}
		

		private boolean promptSaveActiveEditor() {
			String title = AuthoringUIResources.processFormEditorSaveDialog_title; 
			String message = AuthoringUIResources.processFormEditorSaveDialog_message2; 
			if (activeEditor.isDirty()) {
				return AuthoringUIPlugin.getDefault().getMsgDialog()
						.displayConfirmation(title, message);
			}
			return true;
		}

		private void saveActiveEditor() {
			// save the editor
			//
			BusyIndicator.showWhile(activeEditor.getEditorSite().getShell()
					.getDisplay(), new Runnable() {

				public void run() {
					doSaveActiveEditor();
				}

			});
		}

		private void doSaveActiveEditor() {
			((ProcessEditor) activeEditor).resourcesToSave.add(getProcess()
					.eResource());
			activeEditor.doSave(new NullProgressMonitor());
		}

		protected DeleteAction createDeleteAction() {
			return new ProcessDeleteAction() {
				protected void saveCurrentEditor() {
					if (activeEditor.isDirty()) {
						BusyIndicator.showWhile(activeEditor.getEditorSite()
								.getShell().getDisplay(), new Runnable() {

							public void run() {
								activeEditor.doSave(new NullProgressMonitor());
							}

						});
					}
				}
				
				public void run() {	
					IFormPage activePage = ((ProcessEditor) activeEditor)
							.getActivePageInstance();
					if (activePage != null) {
						String id = activePage.getId();
						if (id == ProcessEditor.WBS_FORM_ID
								|| id == ProcessEditor.TA_FORM_ID
								|| id == ProcessEditor.WPBS_FORM_ID
								|| id == ProcessEditor.CONSOLIDATED_FORM_ID) {
							// for all other pages, disable DELETE 
							super.run();
						}
					} 
				}
			};
		}

		protected CutAction createCutAction() {
			return new CutAction() {
				public boolean updateSelection(IStructuredSelection selection) {
					return super.updateSelection(ProcessDeleteAction
							.filterSelection(selection));
				}
			};
		}

		protected PasteAction createPasteAction() {
			return new PasteAction() {
				public boolean updateSelection(IStructuredSelection selection) {
					return super.updateSelection(ProcessDeleteAction
							.filterSelection(selection));
				}
				
				/**
				 * Overrided to use ResourceAwarePasteFromClipboardCommand
				 * 
				 * @see org.eclipse.emf.edit.ui.action.PasteAction#createCommand(java.util.Collection)
				 * @see org.eclipse.epf.library.edit.command.ResourceAwarePasteFromClipboardCommand
				 */
				public Command createCommand(Collection selection) {
				    if (selection.size() == 1)
				    {
				    	return new ResourceAwarePasteFromClipboardCommand(domain, selection.iterator().next(), null, CommandParameter.NO_INDEX);
				    }
				    else
				    {
				      return UnexecutableCommand.INSTANCE;
				    }
				}
			};
		}

		protected CopyAction createCopyAction() {
			return new CopyAction() {

				public void run() {
					if (domain instanceof TraceableAdapterFactoryEditingDomain) {
						((TraceableAdapterFactoryEditingDomain) domain)
								.resetCopyMaps();
					}
					super.run();
				}

				public boolean updateSelection(IStructuredSelection selection) {
					// // disallow copying multiple elements for now until we
					// find a right way
					// // to keep the copy to original map
					// //
					// if(selection.size() > 1) {
					// return false;
					// }

					return super.updateSelection(selection);
				}
			};
		}

		/**
		 * @see org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor#addGlobalActions(org.eclipse.jface.action.IMenuManager)
		 */
		protected void addGlobalActions(IMenuManager menuManager) {
			super.addGlobalActions(menuManager);
			menuManager.insertAfter(
					"additions", new Separator("fixed-additions")); //$NON-NLS-1$ //$NON-NLS-2$
			// menuManager.insertBefore("fixed-additions",
			// insertNewPhaseAction);
		}

		public void contributeToToolBar(IToolBarManager toolBarManager) {
			super.contributeToToolBar(toolBarManager);

			moveUpAction
					.setToolTipText(AuthoringUIResources.ProcessEditor_Action_MoveUp); 
			moveDownAction
					.setToolTipText(AuthoringUIResources.ProcessEditor_Action_MoveDown); 
			showInLibraryView
					.setToolTipText(AuthoringUIResources.ProcessEditor_Action_ShowLinkedElementinLibraryView); 
			toolBarManager.add(moveUpAction);
			toolBarManager.add(moveDownAction);
			toolBarManager.add(showInLibraryView);
		}				

		/** 
		 * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
		 */
		public void menuAboutToShow(IMenuManager menuManager) {
			IFormPage activePage = ((ProcessEditor) activeEditor)
					.getActivePageInstance();
			if (activePage instanceof ProcessBreakdownStructureFormPage
					&& ((ProcessBreakdownStructureFormPage) activePage)
							.basicIsReadOnly()) {
				menuManager.add(new Separator(
						IWorkbenchActionConstants.MB_ADDITIONS));								
				menuManager.add(showInLibraryView);
				if (bsItemProvider != null
				// && ((ITreeItemContentProvider)
				// bsItemProvider).hasChildren(selectedObject)
				) {
					menuManager.add(expandAllAction); 
					menuManager.add(collapseAllAction); 
				}
				menuManager.add(new Separator());
				refreshViewerAction.setEnabled(refreshViewerAction.isEnabled());
				menuManager.add(refreshViewerAction);
				menuManager.add(showPropertiesViewAction);
				return;
			}

			ISelectionProvider selectionProvider = (ISelectionProvider) activeEditor;

			if (selectedActivity == null
					&& (selectionProvider.getSelection() == null || selectionProvider
							.getSelection().isEmpty())) {
				// fake a selection change event with the process selected if no
				// element is selected yet.
				//
				selectionChanged(new SelectionChangedEvent(selectionProvider,
						new StructuredSelection(getProcess())));
			}
			// disable all new action if it's rolled up
			boolean isRolledUP = bsItemProvider != null
					&& bsItemProvider.isRolledUp();
			super.setEnabled(!isRolledUP);
			super.menuAboutToShow(menuManager);

			// add markers
			//
			menuManager.insertAfter("fixed-additions", new Separator("preference")); //$NON-NLS-1$ //$NON-NLS-2$	
			menuManager.appendToGroup("preference", preferenceAction); //$NON-NLS-1$
			
			menuManager.insertAfter("fixed-additions", new Separator("open")); //$NON-NLS-1$ //$NON-NLS-2$

			if (bsItemProvider instanceof BreakdownElementWrapperItemProvider
					&& TngUtil.unwrap(bsItemProvider) instanceof Activity) {
				menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, contributeAction); 
				menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, replaceAction); 
				menuManager.insertBefore(
						IWorkbenchActionConstants.MB_ADDITIONS, localReplacementAndDeepCopy); 
			}

			if (!isRolledUP) {
				if (createChildActions != null && !createChildActions.isEmpty()) {
					menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, addAction); 
				}
			}

			suppressTaskAction.setEnabled(!isRolledUP && suppressTaskAction.isEnabled());
			revealTaskAction.setEnabled(!isRolledUP && revealTaskAction.isEnabled());
			if (revealAction.isEnabled()) {
				menuManager.insertBefore("fixed-additions", revealAction); //$NON-NLS-1$
			}
			if (revealTaskAction.isEnabled()) {
				menuManager.insertBefore("fixed-additions", revealTaskAction); //$NON-NLS-1$
			}
			if (suppressAction.isEnabled()) {
				menuManager.insertBefore("fixed-additions", suppressAction); //$NON-NLS-1$
			}
			if (suppressTaskAction.isEnabled()) {
				menuManager.insertBefore("fixed-additions", suppressTaskAction); //$NON-NLS-1$
			}		
			if (updateSuppressionFromBaseAction.isEnabled()) {
				menuManager.insertBefore(
						"fixed-additions", updateSuppressionFromBaseAction); //$NON-NLS-1$
			}

			if ((selectedBreakdownElement != null) && (bsItemProvider != null)) {
				if (moveUpAction.isEnabled()) {
					menuManager.insertBefore("fixed-additions", moveUpAction); //$NON-NLS-1$
				}
				if (moveDownAction.isEnabled()) {
					menuManager.insertBefore("fixed-additions", moveDownAction); //$NON-NLS-1$
				}
			}

			menuManager.appendToGroup("open", showInLibraryView); //$NON-NLS-1$

			if ((selectedActivity != null) && (bsItemProvider != null)) {
				if (bsItemProvider.isRolledUp()) {
					rollupAction
							.setText(AuthoringUIResources.ProcessEditor_Action_RollDown); 
				} else {
					rollupAction
							.setText(AuthoringUIResources.ProcessEditor_Action_RollUp); 
				}
				menuManager.appendToGroup("open", rollupAction); //$NON-NLS-1$				
			}

			if (selectedObject instanceof Activity) {
				// "Reuse" menu
				//
				MenuManager reuseSubMenu = new MenuManager(
						AuthoringUIResources.ProcessEditor_Action_ApplyPattern); 
				reuseSubMenu.add(copyActivityAction);
				reuseSubMenu.add(extendActivityAction);
				reuseSubMenu.add(deepCopyActivityAction);

				menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, reuseSubMenu); 
			}

			if (autoSynchronize.isEnabled()) {
				menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, autoSynchronize); 
			}
			if (manualSynchronizeAction.isEnabled()) {
				menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, manualSynchronizeAction); 
			}

			if (!(selectedElement instanceof Milestone)) {
				MenuManager diagramSubMenu = new MenuManager(
						AuthoringUIResources.ProcessEditor_Action_Diagrams); 
				if (selectedActivity != null) {
					if (selectedActivity.getVariabilityBasedOnElement() != null) {
						menuManager.appendToGroup("open", openBaseActivity); //$NON-NLS-1$
					}

					diagramSubMenu.add(openWorkflowEditorAction);
					diagramSubMenu.add(openWorkflowDetailEditorAction);
					diagramSubMenu.add(openWPDependencyEditorAction);
					diagramSubMenu.add(suppressDiagramAction);
					diagramSubMenu.add(assignUserDiagram);
				}
				if (selectedActivity == getProcess()) {
					diagramSubMenu.add(suppressAllDiagrams);
					diagramSubMenu.add(revealAllDiagrams);
				}
				// Enable this code if ActivityDetailDiagramInfoDialog is need.
//				if(selectedActivity != null){
//					diagramSubMenu.add(new Separator());
//					diagramSubMenu.add(activityDetailDiagramInfo);
//				}
				menuManager.appendToGroup("open", diagramSubMenu); //$NON-NLS-1$
				
				MenuManager newDiagramSubMenu = new MenuManager(
						"New Diagrams"); //$NON-NLS-1$
				if(selectedActivity != null){
					newDiagramSubMenu.add(newActivityDiagramEditor);
					newDiagramSubMenu.add(newActivityDetailDiagramEditor);
					newDiagramSubMenu.add(newWPDiagramEditor);
					newDiagramSubMenu.add(newSuppressDiagramAction);
					newDiagramSubMenu.add(newAssignUserDiagram);

				}
				
				if (selectedActivity == getProcess()) {
					newDiagramSubMenu.add(newSuppressAllDiagrams);
					newDiagramSubMenu.add(newRevealAllDiagrams);
				}
				menuManager.appendToGroup("open", newDiagramSubMenu); //$NON-NLS-1$
			}

			if (bsItemProvider != null
			// this is an expensive check, removed it
			//
			// && ((ITreeItemContentProvider)
			// bsItemProvider).hasChildren(selectedObject)
			) {
				menuManager.appendToGroup("open", expandAllAction); //$NON-NLS-1$
				menuManager.appendToGroup("open", collapseAllAction); //$NON-NLS-1$
			}
		}

		/**
		 * @return
		 */
		private Process getProcess() {
			return ((ProcessComponent) ((MethodElementEditorInput) activeEditor
					.getEditorInput()).getMethodElement()).getProcess();
		}

		private Suppression getSuppression() {
			return ((ProcessEditor) activeEditor).suppression;
		}

		private void depopulateDynamicMenuItems() {
			// Remove any menu items for old selection.
			//
			if (createChildMenuManager != null) {
				depopulateManager(createChildMenuManager, createChildActions);
			}
			if (createSiblingMenuManager != null) {
				depopulateManager(createSiblingMenuManager,
						createSiblingActions);
			}
			createChildActions = null;
			createSiblingActions = null;
		}

		/**
		 * Set action state to enabled or disabled
		 * 
		 * @param locked
		 */
		private void setActionState() {
			if (locked) {
				// disable modifying actions
				pasteAction.setEnabled(false);
				cutAction.setEnabled(false);
				deleteAction.setEnabled(false);
				autoSynchronize.setEnabled(false);
				manualSynchronizeAction.setEnabled(false);
				updateSuppressionFromBaseAction.setEnabled(false);
			} else if (!oldLocked) {
				// update state of modifying actions
				//
				IStructuredSelection selection = (IStructuredSelection) selectionProvider
						.getSelection();
				cutAction.setEnabled(cutAction.updateSelection(selection));
				pasteAction.setEnabled(pasteAction.updateSelection(selection));
				deleteAction
						.setEnabled(deleteAction.updateSelection(selection));
				autoSynchronize.setEnabled(autoSynchronize
						.updateSelection(selection));
				manualSynchronizeAction.setEnabled(manualSynchronizeAction
						.updateSelection(selection));
				updateSuppressionFromBaseAction
						.setEnabled(updateSuppressionFromBaseAction
								.updateSelection(selection));
			}

			boolean enabled = !locked;

			addAction.setEnabled(enabled);
			contributeAction.setEnabled(enabled);

			// state of these actions is set in updateActions()
			//
			// moveDownAction.setEnabled(enabled);
			// moveUpAction.setEnabled(enabled);
			// revealAction.setEnabled(enabled);
			// suppressAction.setEnabled(enabled);
			replaceAction.setEnabled(enabled);
			localReplacementAndDeepCopy.setEnabled(enabled);
			revealAllDiagrams.setEnabled(enabled);
			suppressAllDiagrams.setEnabled(enabled);
			suppressDiagramAction.setEnabled(enabled);
			copyActivityAction.setEnabled(enabled);
			extendActivityAction.setEnabled(enabled);
			deepCopyActivityAction.setEnabled(enabled);
		}

		protected Collection generateCreateChildActions(Collection descriptors,
				ISelection selection) {
			if (locked) {
				return null;
			}
			return super.generateCreateChildActions(descriptors, selection);
		}

		protected Collection generateCreateSiblingActions(
				Collection descriptors, ISelection selection) {
			if (locked) {
				return null;
			}
			return super.generateCreateSiblingActions(descriptors, selection);
		}

		
		/**
		 * @see org.eclipse.epf.authoring.ui.actions.MethodLibraryActionBarContributor#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
		 */
		public void selectionChanged(SelectionChangedEvent event) {
			ISelection sel = event.getSelection();
			if (sel instanceof IStructuredSelection) {
				IStructuredSelection structuredSelection = (IStructuredSelection) sel;
				oldLocked = locked;
				locked = ViewHelper.isLocked(structuredSelection);

				selection = ((IStructuredSelection) sel).toList();
				if (selection.size() == 1) {
					selectedObject = ((IStructuredSelection) sel)
							.getFirstElement();
					Object obj = TngUtil.unwrap(selectedObject);
					super.selectionChanged(event);
					selectedElement = obj;
					if (obj instanceof Activity) {
						selectedActivity = (Activity) obj;
					} else {
						// depopulateDynamicMenuItems();
						// bsItemProvider = null;
						selectedActivity = null;
					}
					AdapterFactoryEditingDomain domain = (AdapterFactoryEditingDomain) ((IEditingDomainProvider) activeEditorPart)
							.getEditingDomain();
					Object providerObj = domain.getAdapterFactory().adapt(
							selectedObject, ITreeItemContentProvider.class);
					if (providerObj instanceof IBSItemProvider)
						bsItemProvider = (IBSItemProvider) providerObj;

					if (obj instanceof BreakdownElement) {
						selectedBreakdownElement = (BreakdownElement) obj;
					} else {
						selectedBreakdownElement = null;
					}
				} else {
					depopulateDynamicMenuItems();
					bsItemProvider = null;
					selectedElement = null;
					selectedActivity = null;
					selectedBreakdownElement = null;
					selectedObject = null;
				}

				updateActions();

			} else {
				depopulateDynamicMenuItems();
				bsItemProvider = null;
				selectedElement = null;
				selectedActivity = null;
				selectedBreakdownElement = null;
			}

			// // test code
			// //
			// if(selectedActivity != null) {
			// for (Iterator iter =
			// selectedActivity.eClass().getEAllAttributes().iterator();
			// iter.hasNext();) {
			// EAttribute attrib = (EAttribute) iter.next();
			// if(String.class.isAssignableFrom(attrib.getEAttributeType().getInstanceClass()))
			// {
			// List values =
			// ConfigurationHelper.getStringAttribute(selectedActivity, attrib);
			// System.out.println();
			// System.out.println(attrib.getName() + ": " + values);
			// }
			// }
			// }
		}

		/**
		 * Updates actions including enabling/disabling them based on selection
		 */
		private void updateActions() {
			showInLibraryView
					.setEnabled(selectedBreakdownElement instanceof Descriptor
							&& ProcessUtil
									.getAssociatedElement((Descriptor) selectedBreakdownElement) != null);

			if (!locked && selection != null && !selection.isEmpty()) {
				if (selection.size() == 1) {
					if (getSuppression().canReveal(selection)) {
						revealAction.setEnabled(true);
						suppressAction.setEnabled(false);
					} else if (getSuppression().canSuppress(selection)) {
						suppressAction.setEnabled(true);
						revealAction.setEnabled(false);
					} else {
						revealAction.setEnabled(false);
						suppressAction.setEnabled(false);
					}
				} else {
					revealAction.setEnabled(getSuppression().canReveal(
							selection));
					suppressAction.setEnabled(getSuppression().canSuppress(
							selection));
				}
				
				// Action Enable/Disable for Suppress Task/Reveal Task context menu
				boolean show = true;
				for (int i = 0; i < selection.size(); i++) {
					if (getAdapterFactory() == TngAdapterFactory.INSTANCE
							.getWBS_ComposedAdapterFactory()) {
						
						if (!(selection.get(i) instanceof Activity || selection
								.get(i) instanceof ActivityWrapperItemProvider)) {
							show = false;
							break;
						}
					} else
						show = false;
				}
				if (show) {
					List taskDescriptors = ProcessUtil.getTaskDescriptors(selection);
					suppressTaskAction.setEnabled(getSuppression().canSuppress(taskDescriptors));
					revealTaskAction.setEnabled(getSuppression().canReveal(taskDescriptors));
				}
				else {
					suppressTaskAction.setEnabled(false);
					revealTaskAction.setEnabled(false);
				}

				// boolean hasInherited = false;
				// for (Iterator iter = selection.iterator(); iter.hasNext();) {
				// Object item = iter.next();
				// if (item instanceof BreakdownElementWrapperItemProvider
				// && ((BreakdownElementWrapperItemProvider) item)
				// .isReadOnly()) {
				// hasInherited = true;
				// break;
				// }
				// }
				// updateSuppressionFromBaseAction.setEnabled(hasInherited);
			} else {
				revealAction.setEnabled(false);
				suppressAction.setEnabled(false);
				suppressTaskAction.setEnabled(false);
				revealTaskAction.setEnabled(false);
			}

			if (!locked) {
				refreshMoveButtonActions();
			} else {
				moveUpAction.setEnabled(false);
				moveDownAction.setEnabled(false);
			}

			// Set Activity Detail Diagram Action enable state.
			if (selectedObject instanceof Activity
					|| selectedObject instanceof ActivityWrapperItemProvider)
				setActionStateForADD();

			// change action state for locked plugin
			setActionState();
		}

		public void setActivePage(IEditorPart part) {
			if (this.activeEditor != null) {
				int page = ((ProcessEditor) this.activeEditor).getActivePage();
				IActionBars actionBars = this.activeEditor.getEditorSite()
						.getActionBars();

				if (page == 0) {
					actionBars.setGlobalActionHandler(ActionFactory.DELETE
							.getId(), null);
					actionBars.setGlobalActionHandler(
							ActionFactory.CUT.getId(), null);
					actionBars.setGlobalActionHandler(ActionFactory.COPY
							.getId(), null);
					actionBars.setGlobalActionHandler(ActionFactory.PASTE
							.getId(), null);
					actionBars.setGlobalActionHandler(ActionFactory.UNDO
							.getId(), null);
					actionBars.setGlobalActionHandler(ActionFactory.REDO
							.getId(), null);
				} else {
					actionBars.setGlobalActionHandler(ActionFactory.DELETE
							.getId(), deleteAction);
					actionBars.setGlobalActionHandler(
							ActionFactory.CUT.getId(), cutAction);
					actionBars.setGlobalActionHandler(ActionFactory.COPY
							.getId(), copyAction);
					actionBars.setGlobalActionHandler(ActionFactory.PASTE
							.getId(), pasteAction);
					actionBars.setGlobalActionHandler(ActionFactory.UNDO
							.getId(), undoAction);
					actionBars.setGlobalActionHandler(ActionFactory.REDO
							.getId(), redoAction);
				}
				actionBars.updateActionBars();
			}
		}

		protected void doRefresh() {
			// update IDs
			//
			AdapterFactory adapterFactory = getAdapterFactory();
			if (adapterFactory == TngAdapterFactory.INSTANCE
					.getWBS_ComposedAdapterFactory()
					|| adapterFactory == TngAdapterFactory.INSTANCE
							.getProcessComposedAdapterFactory()) {
				Process proc = getProcess();
				ProcessUtil.updateIDs(adapterFactory, proc);
				ProcessUtil.refreshPredeccessorLists(adapterFactory, proc);
			}

			super.doRefresh();
		}

		private void refreshMoveButtonActions() {
			if ((selectedBreakdownElement != null) && (bsItemProvider != null)) {
				moveUpAction.setEnabled(!bsItemProvider.isFirstElement(selectedBreakdownElement));
				moveDownAction.setEnabled(!bsItemProvider.isLastElement(selectedBreakdownElement));
			}
		}

		/*
		 * Set Action state for Activity Detail Diagram in Context Menu on
		 * selection of Activity. If an Activity consist atleast one
		 * taskdescriptor and its primary performer in current configuration,
		 * then state is enabled else state is disabled in context menu (process
		 * editor).
		 */
		private void setActionStateForADD() {

			// set ADD Action state false
			openWorkflowDetailEditorAction.setEnabled(false);

			// set AD Action state true always
			openWorkflowEditorAction.setEnabled(true);

			// set WPD Diagram Menu Action state tru always
			openWPDependencyEditorAction.setEnabled(true);

			if (selectedObject != null) {

				if (getSuppression().isSuppressed(selectedObject)) {
					openWorkflowDetailEditorAction.setEnabled(false);
					openWorkflowEditorAction.setEnabled(false);
					openWPDependencyEditorAction.setEnabled(false);
					return;
				}

				Activity activity = null;
				List list = new ArrayList();

				if (selectedObject instanceof Activity) {
					activity = selectedActivity;
				} else if (selectedObject instanceof ActivityWrapperItemProvider) {
					activity = (Activity) ((ActivityWrapperItemProvider) selectedObject)
							.getValue();
				}
				if (activity == null)
					return;

				while (!activity.getVariabilityType().equals(
						VariabilityType.NA_LITERAL)) {

					VariabilityElement ve = activity
							.getVariabilityBasedOnElement();
					// If Activity is set to local contribution,
					// need to get breakdown elements of local contributed
					// activity + base activity. And base activity breakdown
					// elements
					// are collected after while loop ends)
					// if (VariabilityType.CONTRIBUTES_LITERAL.equals(activity
					// .getVariabilityType())) {
					// list.addAll(activity.getBreakdownElements());
					// }
					list.addAll(activity.getBreakdownElements());

					if ((ve != null) && (ve instanceof Activity)) {
						activity = (Activity) ve;
					} else {
						break;
					}
				}

				// For AD diagram menu option, if Base Activity donot have any
				// AD diagram, donot show AD diagram option in context menu for
				// readonly activity.
				Diagram diagram = GraphicalDataManager.getInstance()
						.getUMADiagram(activity,
								GraphicalDataHelper.ACTIVITY_DIAGRAM, false);
				if (diagram == null
						&& selectedObject instanceof ActivityWrapperItemProvider) {
					openWorkflowEditorAction.setEnabled(false);
				}

				// For WPD diagram menu option, if Base Activity donot have any
				// WPD diagram, donot show WPD diagram option in context menu
				// for readonly activity.
				diagram = GraphicalDataManager.getInstance().getUMADiagram(
						activity,
						GraphicalDataHelper.WORK_PRODUCT_DEPENDENCY_DIAGRAM,
						false);
				if (diagram == null
						&& selectedObject instanceof ActivityWrapperItemProvider) {
					openWPDependencyEditorAction.setEnabled(false);
				}

				// Collect the breakdown elements to verifty taskdescriptors are
				// not.
				list.addAll(activity.getBreakdownElements());

				// For ADD diagram menu option, if Base Activity donot have any
				// ADD diagram, donot show ADD diagram option in context menu
				// for
				// readonly activity.
				diagram = GraphicalDataManager.getInstance().getUMADiagram(
						activity, GraphicalDataHelper.ACTIVITY_DETAIL_DIAGRAM,
						false);
				if (diagram == null
						&& selectedObject instanceof ActivityWrapperItemProvider) {
					openWorkflowDetailEditorAction.setEnabled(false);
				} else {
					// Iterate through the List, to find taskdescriptor and has
					// primary role within current configuration.
					// then enable the action.
					for (Iterator iterator = list.iterator(); iterator
							.hasNext();) {
						Object obj = iterator.next();
						if (obj instanceof TaskDescriptor) {
							if (!getSuppression().isSuppressed(obj)) {
								Object e = ((TaskDescriptor) obj)
										.getPerformedPrimarilyBy();
								AdapterFactoryEditingDomain domain = (AdapterFactoryEditingDomain) ((IEditingDomainProvider) activeEditorPart)
										.getEditingDomain();
								AdapterFactory factory = domain
										.getAdapterFactory();
								if (factory instanceof ExposedAdapterFactory) {
									IFilter filter = ((ExposedAdapterFactory) factory)
											.getFilter();
									if (filter != null
											&& filter.accept(e)
											&& !getSuppression()
													.isSuppressed(e)) {
										openWorkflowDetailEditorAction
												.setEnabled(true);
										break;
									}
								}
							}
						}
					}
				}
			}
		}
	}

	private class ProcessEditorDropAdapter extends
			EditingDomainTableTreeViewerDropAdapter {

		/**
		 * @param domain
		 * @param viewer
		 */
		public ProcessEditorDropAdapter(EditingDomain domain, Viewer viewer) {
			super(domain, viewer);
		}

		/** 
		 * @see org.eclipse.epf.authoring.ui.dnd.EditingDomainTableTreeViewerDropAdapter#getDropTarget(org.eclipse.swt.widgets.Widget)
		 */
		protected Object getDropTarget(Widget item) {
			Object target = super.getDropTarget(item);
			if (target == null && selectedProcessComponent != null) {
				target = selectedProcessComponent.getProcess();
			}
			return target;
		}

		/**
		 * @see org.eclipse.epf.authoring.ui.dnd.EditingDomainTableTreeViewerDropAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent)
		 */
		public void drop(DropTargetEvent event) {
			if (currentViewer instanceof IActionTypeProvider) {
				((IActionTypeProvider) currentViewer).setInputData(new Point(
						event.x, event.y));
			}
			super.drop(event);
		}
	}

	private ComposedAdapterFactory adapterFactory;

	private AdapterFactoryEditingDomain editingDomain;

	private Viewer currentViewer;

	private ISelectionChangedListener selectionChangedListener;

	private Collection selectionChangedListeners = new ArrayList();

	private ISelection viewSelection;

	private ProcessComponent selectedProcessComponent;

	private Process selectedProcess;

	private Adapter processComponentListener = new AdapterImpl() {
		/**
		 * @see org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.eclipse.emf.common.notify.Notification)
		 */
		public void notifyChanged(Notification msg) {
			switch (msg.getFeatureID(ProcessComponent.class)) {
			case UmaPackage.PROCESS_COMPONENT__NAME:
				String name = msg.getNewStringValue();
				if (name == null)
					name = ""; //$NON-NLS-1$
				setPartName(name);

				if (pages != null) {
					for (Iterator iter = pages.iterator(); iter.hasNext();) {
						Object page = iter.next();
						if (page instanceof ProcessDescription) {
							((ProcessDescription) page)
									.refreshElementName(name);
						}

					}
				}

				break;
			}
		}
	};

	private AdapterFactoryContentProvider propContentProvider;

	private MethodConfiguration currentConfig;

	private ILibraryChangeListener libraryListener = new ILibraryChangeListener() {

		public void libraryChanged(int option, Collection collection) {
			switch (option) {
			// case ILibraryChangeListener.OPTION_LOADED:
			// // close all open diagram editors
			// //
			// IEditorReference[] editorRefs =
			// getSite().getPage().getEditorReferences();
			// for (int i = 0; i < editorRefs.length; i++) {
			// IEditorPart editorPart = editorRefs[i].getEditor(false);
			// if(editorPart instanceof GraphicalWorkflowEditor
			// || editorPart instanceof ProcessFormEditor) {
			// getSite().getPage().closeEditor(editorPart, true);
			// }
			// }
			// getSite().getPage().closeEditor(ProcessFormEditor.this, true);
			case ILibraryChangeListener.OPTION_CHANGED: {
				if (collection != null && collection.contains(currentConfig)) {
					MethodConfiguration config = ProcessAuthoringConfigurator.INSTANCE
							.getMethodConfiguration();
					try {
						ProcessAuthoringConfigurator.INSTANCE
								.setMethodConfiguration(currentConfig);
						refreshAll();
					} finally {
						ProcessAuthoringConfigurator.INSTANCE
								.setMethodConfiguration(config);
					}
				}
				break;
			}
				// handled by libSvcListener
				// case ILibraryChangeListener.OPTION_CONFIGURATION_SELECTED: {
				// configChanged();
				// break;
				// }

			}

		}

	};

	private ILibraryServiceListener libSvcListener = new ILibraryServiceListener() {

		public void configurationSet(MethodConfiguration config) {
			configChanged();
		}

		public void libraryClosed(MethodLibrary library) {
		}

		public void libraryCreated(MethodLibrary library) {
		}

		public void libraryOpened(MethodLibrary library) {
		}

		public void libraryReopened(MethodLibrary library) {
		}

		public void librarySet(MethodLibrary library) {
		}

	};

	private ProcessBreakdownStructureFormPage WBSTab;

	private ProcessBreakdownStructureFormPage OBSTab;

	private ProcessBreakdownStructureFormPage PBSTab;

	private ProcessBreakdownStructureFormPage procTab;

	private ProcessBreakdownStructureFormPage[] extensionTabs = null;

	private ProcessBreakdownStructureFormPage[] bsPages;

	private EPFPropertySheetPage propertySheetPage;

	public Collection resourcesToSave = new ArrayList();

	// private boolean firstExpanded = false;

	/**
	 * a listener that is interested in part activation events.
	 */
	private IPartListener partActivationListener = new IPartListener() {

		public void partActivated(IWorkbenchPart part) {
			if (part instanceof PropertySheet) {
				removePropertiesDropDownMenu(part);
			}
		}

		public void partBroughtToTop(IWorkbenchPart part) {
			// if(!firstExpanded) {
			// synchronized(ProcessFormEditor.this) {
			// if(firstExpanded) {
			// ((AbstractTreeViewer) WBSTab.getViewer()).expandAll();
			// ((AbstractTreeViewer) OBSTab.getViewer()).expandAll();
			// ((AbstractTreeViewer) PBSTab.getViewer()).expandAll();
			// firstExpanded = true;
			// }
			// }
			// }
		}

		public void partClosed(IWorkbenchPart part) {
			if (part instanceof PropertySheet) {
				propertySheetPage = null;
			}
		}

		public void partDeactivated(IWorkbenchPart part) {
		}

		public void partOpened(IWorkbenchPart part) {
			if (part instanceof PropertySheet) {
				removePropertiesDropDownMenu(part);
			}
		}
	};

	private IPropertyChangeListener prefStoreListener;

	// private ProcessConfigurator configurator;

	private Suppression suppression;

	private boolean synchronizingSelection;

	private boolean inputChanged;

	public static final IAdapterFactoryProvider adapterFactoryProvider = new IAdapterFactoryProvider() {

		public AdapterFactory getCBSAdapterFactory() {
			return TngAdapterFactory.INSTANCE.getProcessComposedAdapterFactory();
		}

		public AdapterFactory getTBSAdapterFactory() {
			return TngAdapterFactory.INSTANCE.getOBS_ComposedAdapterFactory();
		}

		public AdapterFactory getWBSAdapterFactory() {
			return TngAdapterFactory.INSTANCE.getWBS_ComposedAdapterFactory();
		}

		public AdapterFactory getWPBSAdapterFactory() {
			return TngAdapterFactory.INSTANCE.getPBS_ComposedAdapterFactory();
		}
	};
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.authoring.ui.editors.MethodElementEditor#isValidateResourcesBeforeSaveRequired()
	 */
	protected boolean isValidateResourcesBeforeSaveRequired() {
		return true;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.epf.authoring.ui.editors.MethodElementEditor#createValidateResourceAction()
	 */
	protected LibraryValidateAction createValidateResourceAction() {
		LibraryValidateAction validateAction = super.createValidateResourceAction();
		validateAction.putContextData(LibraryEValidator.CTX_ADAPTER_FACTORY_PROVIDER,
				adapterFactoryProvider);
		return validateAction;
	}
	
	protected void inputChanged(Object newInput) {
		inputChanged = false;
		if (!(newInput instanceof MethodElementEditorInput))
			return;
		MethodElementEditorInput methodElementInput = (MethodElementEditorInput) newInput;

		Object obj = methodElementInput.getMethodElement();
		if (obj instanceof ProcessComponent) {
			selectedProcessComponent = (ProcessComponent) obj;
			selectedProcess = (Process) ProcessUtil
					.getTopBreakdownElement(selectedProcessComponent);
			suppression = Suppression.getSuppression(selectedProcess);

			// for (Iterator iter = pages.iterator(); iter.hasNext();) {
			// Object page = iter.next();
			// if(page instanceof ProcessBreakdownStructureFormPage) {
			// ((ProcessBreakdownStructureFormPage)page).setProcess(proc);
			// }
			// }

			WBSTab.setProcess(selectedProcess);
			OBSTab.setProcess(selectedProcess);
			PBSTab.setProcess(selectedProcess);
			procTab.setProcess(selectedProcess);
			if (extensionTabs != null) {
				for (int i = 0; i < extensionTabs.length; i++) {
					if (extensionTabs[i] != null) {
						extensionTabs[i].setProcess(selectedProcess);
					}
				}
			}

		}
	}

	// private String getTitlePrefix() {
	// IEditorInput input = getEditorInput();
	// if (input instanceof MethodElementEditorInput) {
	// Object obj = ((MethodElementEditorInput) input).getMethodElement();
	// if (obj instanceof ProcessComponent) {
	// ProcessComponent pc = (ProcessComponent) obj;
	// Process proc = pc.getProcess();
	// if (proc instanceof CapabilityPattern) {
	// return LibraryUIText.TEXT_CAPABILITY_PATTERN;
	// } else if (proc instanceof DeliveryProcess) {
	// return LibraryUIText.TEXT_DELIVERY_PROCESS;
	// } else if (proc instanceof ProcessContribution) {
	// return LibraryUIText.TEXT_PROCESS_CONTRIBUTION;
	// }
	// }
	// }
	// return AuthoringUIResources
	// .getString("AuthoringUI.ProcessEditor.Title"); //$NON-NLS-1$
	// }

	private Image getProcTitleImage() {
		IEditorInput input = getEditorInput();
		if (input instanceof MethodElementEditorInput) {
			Object obj = ((MethodElementEditorInput) input).getMethodElement();
			if (obj instanceof ProcessComponent) {
				ProcessComponent pc = (ProcessComponent) obj;
				Process proc = pc.getProcess();
				if (proc instanceof CapabilityPattern) {
					return LibraryUIImages.IMG_CAPABILITY_PATTERN;
				} else if (proc instanceof DeliveryProcess) {
					return LibraryUIImages.IMG_DELIVERY_PROCESS;
				}
			}
		}
		return LibraryUIImages.IMG_PROCESS;
	}

	/**
	 * Remove Properties view drop down menu
	 * 
	 * @param part
	 */
	private void removePropertiesDropDownMenu(IWorkbenchPart part) {
		if (part instanceof PropertySheet) {
			IViewSite view = ((PropertySheet) part).getViewSite();

			IMenuManager menuMgr = view.getActionBars().getMenuManager();
			// IContributionItem[] items = menuMgr.getItems();
			// for (int i=0; i < items.length; i++)
			// {
			// System.out.println("Id =" + i + " " + items[i].getId() + "$");
			// }
			menuMgr.removeAll();
			menuMgr.updateAll(true);
		}
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormEditor#init(org.eclipse.ui.IEditorSite,
	 *      org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		super.init(site, input);

		// TODO: need revisit
		// site.setSelectionProvider(new FormEditorSelectionProvider(this));
		// actionManager = getActionManager();

		List factories = new ArrayList();
		factories.add(new ResourceItemProviderAdapterFactory());
		factories.add(new ReflectiveItemProviderAdapterFactory());

		adapterFactory = new ComposedAdapterFactory(factories);

		// Create the command stack that will notify this editor as commands are
		// executed.
		//
		CommandStack commandStack = actionMgr.getCommandStack(); // new
		// BasicCommandStack();

		// Add a listener to set the most recent command's affected objects to
		// be the selection of the viewer with focus.
		//
		commandStack.addCommandStackListener(new CommandStackListener() {
			public void commandStackChanged(final EventObject event) {
				boolean run = false;
				if (event instanceof CommandStackChangedEvent) {
					switch (((CommandStackChangedEvent) event).getType()) {
					case CommandStackChangedEvent.EXECUTED:
					case CommandStackChangedEvent.UNDO:
						run = true;
						break;
					}
				} else {
					run = true;
				}
				if (run) {
					Display.getCurrent().asyncExec(new Runnable() {
						public void run() {
							firePropertyChange(IEditorPart.PROP_DIRTY);

							// Try to select the affected objects.
							//
							Command mostRecentCommand = ((CommandStack) event
									.getSource()).getMostRecentCommand();
							if (mostRecentCommand != null) {
								if (mostRecentCommand instanceof CreateChildCommand
										&& currentViewer instanceof ProcessViewer) {
									Object[] arr = mostRecentCommand
											.getAffectedObjects().toArray();
									if (arr.length == 1) {
										ProcessViewer viewer = (ProcessViewer) currentViewer;
										viewer.editElement(arr[0], 0);
									}
								} else {
									if (!(TngUtil.unwrap(mostRecentCommand) instanceof SetCommand)) {
										setSelectionToViewer(mostRecentCommand
												.getAffectedObjects());
									}

								}
							}
							// if (propertySheetPage != null) {
							// propertySheetPage.refresh();
							// }
						}
					});
				}
			}
		});

		// Create the editing domain with a special command stack.
		editingDomain = new TraceableAdapterFactoryEditingDomain(
				adapterFactory, commandStack);

		LibraryService.getInstance().addListener(libSvcListener);
		ILibraryManager manager = (ILibraryManager) LibraryService
				.getInstance().getCurrentLibraryManager();
		if (manager != null) {
			manager.addListener(libraryListener);
			manager.startListeningTo(actionMgr.getCommandStack());

			// TODO: need to revisit this code
			if (!addAdapterFactoryListeners) {
				addAdapterFactoryListeners = true;
				manager.startListeningTo(TngAdapterFactory.INSTANCE
						.getWBS_ComposedAdapterFactory());
				manager.startListeningTo(TngAdapterFactory.INSTANCE
						.getOBS_ComposedAdapterFactory());
				manager.startListeningTo(TngAdapterFactory.INSTANCE
						.getPBS_ComposedAdapterFactory());
			}
		}

		setPartName(input.getName());
		setTitleImage(getProcTitleImage());

		// get method element object from Editor input
		MethodElementEditorInput methodElementInput = (MethodElementEditorInput) input;
		elementObj = methodElementInput.getMethodElement();

		if (elementObj instanceof ProcessComponent) {
			selectedProcessComponent = ((ProcessComponent) elementObj);
			selectedProcess = selectedProcessComponent.getProcess();
		}

		if (selectedProcessComponent != null) {
			selectedProcessComponent.eAdapters().add(processComponentListener);
		}

		// listen to resource change to update dirty flag
		//
		// addResourceChangedListener();

		// add part listener to listen to propertySheet close event
		getSite().getWorkbenchWindow().getPartService().addPartListener(
				partActivationListener);

		// inputChanged(input);

		// listen to the change of column list in preference store
		//
		if (prefStoreListener == null) {
			prefStoreListener = new IPropertyChangeListener() {

				public void propertyChange(PropertyChangeEvent event) {
					ProcessBreakdownStructureFormPage page = null;
					if (event.getProperty().equals(
							ApplicationPreferenceConstants.PREF_WBS_COLUMNS)) {
						page = WBSTab;
					} else if (event.getProperty().equals(
							ApplicationPreferenceConstants.PREF_TBS_COLUMNS)) {
						page = OBSTab;
					} else if (event.getProperty().equals(
							ApplicationPreferenceConstants.PREF_WPBS_COLUMNS)) {
						page = PBSTab;
					}
					if (page != null) {
						ColumnDescriptor[] cols = toColumnDescriptors(getPreferenceStore().getString(
										event.getProperty()));
						page.updateColumns(cols);
						if (page == WBSTab || page == OBSTab) {
							// update consolidated view as well
							//
							// get WBS columns
							List list = toColumnDescriptorList(getPreferenceStore()
									.getString(ApplicationPreferenceConstants.PREF_WBS_COLUMNS));

							// get TBS columns 
							ColumnDescriptor[] teamColumnDescriptors = toColumnDescriptors(getPreferenceStore()
									.getString(ApplicationPreferenceConstants.PREF_TBS_COLUMNS));

							// if TBS columns has TEAM column then add to consolidated view
							for (int i = 0; i < teamColumnDescriptors.length; i++) {
								ColumnDescriptor colDesc = teamColumnDescriptors[i];
								if (colDesc == COL_DESC_TEAM) {
									list.add(colDesc);
									break;
								}
							}
							
							ColumnDescriptor[] columns = new ColumnDescriptor[list.size()];
							list.toArray(columns);
							procTab.updateColumns(columns);
						}
					}
				}

			};
		}

		getPreferenceStore()
				.addPropertyChangeListener(prefStoreListener);

	}

	/**
	 * This sets the selection into whichever viewer is active. 
	 * 
	 */
	public void setSelectionToViewer(Collection collection) {
		// System.out.println(getClass().getName() + ".setSelectionToViewer:
		// selection="+collection);
		final Collection theSelection = collection;
		// Make sure it's okay.
		//
		if (theSelection != null && !theSelection.isEmpty()) {
			// I don't know if this should be run this deferred
			// because we might have to give the editor a chance to process the
			// viewer update events
			// and hence to update the views first.
			//
			//
			Runnable runnable = new Runnable() {
				public void run() {
					// Try to select the items in the current content viewer of
					// the editor.
					//
					if (currentViewer != null) {
						currentViewer.setSelection(new StructuredSelection(
								theSelection.toArray()), true);

					}
				}
			};
			runnable.run();
		}
	}

	public EditingDomainActionBarContributor getActionBarContributor() {
		return (EditingDomainActionBarContributor) getEditorSite()
				.getActionBarContributor();
	}

	public void dispose() {
		getPreferenceStore()
				.removePropertyChangeListener(prefStoreListener);

		// ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener);
		//
		// getSite().getPage().removePartListener(partListener);

		adapterFactory.dispose();

		if (getActionBarContributor().getActiveEditor() == this) {
			getActionBarContributor().setActiveEditor(null);
		}

		if (propertySheetPage != null) {
			propertySheetPage.dispose();
		}

		ILibraryManager manager = LibraryService.getInstance()
				.getCurrentLibraryManager();
		if (manager != null) {
			manager.removeListener(libraryListener);
			manager.stopListeningTo(editingDomain.getCommandStack());
		}
		LibraryService.getInstance().removeListener(libSvcListener);

		if (selectedProcessComponent != null) {
			selectedProcessComponent.eAdapters().remove(
					processComponentListener);
		}

		// removeResourceChangedListener();

		getSite().getWorkbenchWindow().getPartService().removePartListener(
				partActivationListener);

		boolean saveNeeded = isDirty();

		super.dispose();

		// call this to set modified flag of suppression to false
		//
		suppression.saveIsDone();

		if (saveNeeded) {
			// user discarded all the changes, save the resources after changes
			// are undone.
			// TODO: reload the process component resource instead since it is
			// not shared.
			//
			// for (Iterator iter = resources.iterator(); iter.hasNext();) {
			// Resource resource = (Resource) iter.next();
			// saveResource(resource);
			// }
		}
	}

	private void addDescriptionPage() throws PartInitException {
		if (selectedProcess instanceof DeliveryProcess) {
			// Delivery Process
			addPage(0, new DeliveryProcessDescription(this));
		} else {
			// Capability Pattern
			// Process Contribution
			addPage(0, new ProcessDescription(this));
		}
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
	 */
	protected void addPages() {
		try {
			addDescriptionPage();

			AdapterFactory adapterFactory;

			// create DND transfer objects
			// int dndOperations = DND.DROP_COPY | DND.DROP_LINK;
			// Transfer[] transfers = new Transfer[]
			// {LocalTransfer.getInstance() };

			// preference is managed by library plugin,
			// since this preferences is also used for browsing and publishing
			// Jinhua Xi 08/21/2006
			// IPreferenceStore store = AuthoringUIPlugin.getDefault()
			// .getPreferenceStore();
			PreferenceUtil.validatePreferences();
			IPreferenceStore store = getPreferenceStore();
			
			List pages = new ArrayList();

			// WBS tab
			WBSTab = new ProcessBreakdownStructureFormPage(this, WBS_FORM_ID,
					AuthoringUIResources.ProcessEditor_WorkBreakdownStructure); //$NON-NLS-1$ 
			ColumnDescriptor[] columnDescriptors = toColumnDescriptors(store
					.getString(ApplicationPreferenceConstants.PREF_WBS_COLUMNS));
			adapterFactory = TngAdapterFactory.INSTANCE
					.getWBS_ComposedAdapterFactory();
			currentConfig = LibraryService.getInstance()
					.getCurrentMethodConfiguration();
			ProcessAuthoringConfigurator.INSTANCE
					.setMethodConfiguration(currentConfig);
			if (adapterFactory instanceof ConfigurableComposedAdapterFactory) {
				((ConfigurableComposedAdapterFactory) adapterFactory)
						.setFilter(ProcessAuthoringConfigurator.INSTANCE);
			}
			WBSTab.setAdapterFactory(adapterFactory);
			WBSTab.setColumnDescriptors(columnDescriptors);
			int id = addPage(WBSTab.createControl(getContainer()));
			setPageText(id, WBSTab.getTitle());
			WBSTab.setTabIndex(id);
			StructuredViewer viewer = (StructuredViewer) WBSTab.getViewer();
			createContextMenuFor(viewer);
			pages.add(WBSTab);
			// viewer.addDropSupport(dndOperations, transfers, new
			// ProcessEditorDropAdapter(editingDomain, viewer));
			// viewer.addDoubleClickListener(new IDoubleClickListener()
			// {
			// public void doubleClick(DoubleClickEvent event)
			// {
			// UIActionDispatcher.getInstance().handleDoubleClickEvent(event);
			// // System.out.println("double clicked ...");
			// //
			// // StructuredSelection selection = (StructuredSelection)
			// event.getSelection();
			// // System.out.println("sel"+selection.getFirstElement());
			// //
			// ProductEditorView.getView().getProductViewer().setInput(selection.getFirstElement());
			// }
			// });
			// addPage(WBSTab);

			// OBS tab
			OBSTab = new ProcessBreakdownStructureFormPage(this, TA_FORM_ID,
					AuthoringUIResources.ProcessEditor_TeamAllocation); //$NON-NLS-1$ 
			columnDescriptors = toColumnDescriptors(store
					.getString(ApplicationPreferenceConstants.PREF_TBS_COLUMNS));
			// setColumnIndexToNameMap(TngAdapterFactory.INSTANCE.getOBS_AdapterFactories(),
			// columnDescriptors);
			adapterFactory = TngAdapterFactory.INSTANCE
					.getOBS_ComposedAdapterFactory();
			if (adapterFactory instanceof ConfigurableComposedAdapterFactory) {
				((ConfigurableComposedAdapterFactory) adapterFactory)
						.setFilter(ProcessAuthoringConfigurator.INSTANCE);
			}
			OBSTab.setAdapterFactory(adapterFactory);
			OBSTab.setColumnDescriptors(columnDescriptors);
			id = addPage(OBSTab.createControl(getContainer()));
			setPageText(id, OBSTab.getTitle());
			OBSTab.setTabIndex(id);
			viewer = (StructuredViewer) OBSTab.getViewer();
			createContextMenuFor(viewer);
			pages.add(OBSTab);
			// viewer.addDropSupport(dndOperations, transfers, new
			// ProcessEditorDropAdapter(editingDomain, viewer));
			// addPage(OBSTab);

			// PBS tab
			PBSTab = new ProcessBreakdownStructureFormPage(this, WPBS_FORM_ID,
					AuthoringUIResources.ProcessEditor_WorkProductUsage); //$NON-NLS-1$ 
			columnDescriptors = toColumnDescriptors(store
					.getString(ApplicationPreferenceConstants.PREF_WPBS_COLUMNS));
			// setColumnIndexToNameMap(TngAdapterFactory.INSTANCE.getPBS_AdapterFactories(),
			// columnDescriptors);
			adapterFactory = TngAdapterFactory.INSTANCE
					.getPBS_ComposedAdapterFactory();
			if (adapterFactory instanceof ConfigurableComposedAdapterFactory) {
				((ConfigurableComposedAdapterFactory) adapterFactory)
						.setFilter(ProcessAuthoringConfigurator.INSTANCE);
			}
			PBSTab.setAdapterFactory(adapterFactory);
			PBSTab.setColumnDescriptors(columnDescriptors);
			id = addPage(PBSTab.createControl(getContainer()));
			setPageText(id, PBSTab.getTitle());
			PBSTab.setTabIndex(id);
			viewer = (StructuredViewer) PBSTab.getViewer();
			createContextMenuFor(viewer);
			pages.add(PBSTab);
			// viewer.addDropSupport(dndOperations, transfers, new
			// ProcessEditorDropAdapter(editingDomain, viewer));
			// addPage(PBSTab);

			// consolidated tab
			procTab = new ProcessBreakdownStructureFormPage(this,
					CONSOLIDATED_FORM_ID,
					AuthoringUIResources.ProcessEditor_ConsolidatedView); //$NON-NLS-1$ 
			procTab.setReadOnly(true);
			adapterFactory = TngAdapterFactory.INSTANCE
					.getProcessComposedAdapterFactory();
			if (adapterFactory instanceof ConfigurableComposedAdapterFactory) {
				((ConfigurableComposedAdapterFactory) adapterFactory)
						.setFilter(ProcessAuthoringConfigurator.INSTANCE);
			}
			procTab.setAdapterFactory(adapterFactory);
//			columnDescriptors = toColumnDescriptors(store
//					.getString(ApplicationPreferenceConstants.PREF_WBS_COLUMNS));
//			
			// get WBS columns
			List list = toColumnDescriptorList(store
					.getString(ApplicationPreferenceConstants.PREF_WBS_COLUMNS));

			// get TBS columns 
			ColumnDescriptor[] teamColumnDescriptors = toColumnDescriptors(store
					.getString(ApplicationPreferenceConstants.PREF_TBS_COLUMNS));

			// if TBS columns has TEAM column then add to consolidated view
			for (int i = 0; i < teamColumnDescriptors.length; i++) {
				ColumnDescriptor colDesc = teamColumnDescriptors[i];
				if (colDesc == COL_DESC_TEAM) {
					list.add(colDesc);
					break;
				}
			}

			ColumnDescriptor[] columns = new ColumnDescriptor[list.size()];
			list.toArray(columns);
			procTab.setColumnDescriptors(columns);
			
			id = addPage(procTab.createControl(getContainer()));
			setPageText(id, procTab.getTitle());
			procTab.setTabIndex(id);
			viewer = (StructuredViewer) procTab.getViewer();
			createContextMenuFor(viewer);
			pages.add(procTab);

			// check for extenstion point and add the page if there
			List pageProviders = ProcessEditorPageProvider.getInstance()
					.getPageProviders();

			if (pageProviders != null && pageProviders.size() > 0) {
				try {
					extensionTabs = new ProcessBreakdownStructureFormPage[pageProviders
							.size()];
					for (int i = 0; i < pageProviders.size(); i++) {
						Object page = pageProviders.get(i);
						if (page instanceof IExtensionFormPage) {

							IExtensionFormPage formPage = (IExtensionFormPage) page;
							IFormPage control = formPage.setEditor(this);
							formPage.setInput(selectedProcess);
							ProcessBreakdownStructureFormPage extendedPage = null;
							if (control instanceof ProcessBreakdownStructureFormPage) {
								extendedPage = (ProcessBreakdownStructureFormPage) control;
								extensionTabs[i] = extendedPage;
							}

							id = addPage(extendedPage
									.createControl(getContainer()));
							setPageText(id, extendedPage.getTitle());
							extendedPage.setTabIndex(id);
							viewer = (StructuredViewer) extendedPage
									.getViewer();
							createContextMenuFor(viewer);

							pages.add(extendedPage);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			bsPages = new ProcessBreakdownStructureFormPage[pages.size()];
			for (int i = 0; i < pages.size(); i++) {
				bsPages[i] = (ProcessBreakdownStructureFormPage) pages.get(i);
			}

			// bsPages = new ProcessBreakdownStructureFormPage[] { WBSTab,
			// OBSTab,
			// PBSTab, procTab };

			// if(getEditorInput() instanceof ProcessEditorInput) {
			// int pageId =
			// ((ProcessEditorInput)getEditorInput()).getActivePage();
			// if(pageId != -1) {
			// setActivePage(0);
			// setActivePage(pageId);
			// }
			// }

			inputChanged(getEditorInput());
		} catch (PartInitException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
			e.printStackTrace();
		}
	}

	protected void setActivePage(int pageIndex) {
		super.setActivePage(pageIndex);

		// work around for active page that is not a form page. Super method
		// does not call pageChange() in this case
		//
		handlePageChange();
		if (pageIndex > 0 && bsPages.length <= pageIndex) {
			Viewer viewer = bsPages[pageIndex].getViewer();
			ISelection selection = viewer.getSelection();
			if (selection == null || selection.isEmpty()) {
				ISelection initialSelection = null;
				if (getEditorInput() instanceof ProcessEditorInput) {
					initialSelection = ((ProcessEditorInput) getEditorInput())
							.getInitialSelection();
				}
				if (initialSelection == null) {
					selection = new StructuredSelection(selectedProcess);
				} else {
					selection = initialSelection;
				}
				viewer.setSelection(selection, true);
			}
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ui.forms.editor.FormEditor#setActivePage(java.lang.String)
	 */
	public IFormPage setActivePage(String pageId) {
		int id = -1;
		IFormPage activePage = null;
		for (int i = 0; i < pages.size(); i++) {
			Object page = pages.get(i);
			if (page instanceof IFormPage) {
				IFormPage fpage = (IFormPage) page;
				if (fpage.getId().equals(pageId)) {
					id = i;
					activePage = fpage;
					break;
				}
			}
		}
		if(id == -1) {
			for (int i = 0; i < bsPages.length; i++) {
				ProcessBreakdownStructureFormPage page = bsPages[i];
				if (page.getId().equals(pageId)) {
					id = page.getTabIndex();
					activePage = page;
					break;
				}
			}
		}
		if(id == -1 && extensionTabs != null) {
			for (int i = 0; i < extensionTabs.length; i++) {
				ProcessBreakdownStructureFormPage page = extensionTabs[i];
				if (page.getId().equals(pageId)) {
					id = page.getTabIndex();
					activePage = page;
					break;
				}
			}
		}

		if(activePage != null) {
			setActivePage(id);
			return activePage;
		}
		return null;
	}
	
	private void handlePageChange() {
		int id = getActivePage();
		if (id != -1) {
			Object page = pages.get(id);
			if (page instanceof ProcessDescription) {
				((ProcessDescription) page).setFormText();
			}
			if (id == WBSTab.getTabIndex()) {
				setCurrentViewer(WBSTab.getViewer());
			} else if (id == OBSTab.getTabIndex()) {
				setCurrentViewer(OBSTab.getViewer());
			} else if (id == PBSTab.getTabIndex()) {
				setCurrentViewer(PBSTab.getViewer());
			} else if (id == procTab.getTabIndex()) {
				setCurrentViewer(procTab.getViewer());
			} else if (extensionTabs != null) {
				for (int i = 0; i < extensionTabs.length; i++) {
					if (extensionTabs[i] != null && id == extensionTabs[i].getTabIndex())
						setCurrentViewer(extensionTabs[i].getViewer());
				}
			} else {
				setCurrentViewer(null);
			}

			if (propertySheetPage != null) {
				propertySheetPage.refresh();
			}
		}
	}

	protected void pageChange(int newPageIndex) {
		super.pageChange(newPageIndex);
		handlePageChange();
	}

	/**
	 * Create context menu for the give viewer
	 * @param viewer
	 */
	public void createContextMenuFor(final StructuredViewer viewer) {
		MenuManager contextMenu = new MenuManager("#PopUp"); //$NON-NLS-1$
		contextMenu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		contextMenu.setRemoveAllWhenShown(true);
		contextMenu.addMenuListener(this);
		Menu menu = contextMenu.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(contextMenu, viewer);

		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				IStructuredSelection sel = (IStructuredSelection) event
						.getSelection();
				setSelection(sel);
			}
		});

		int dndOperations = DND.DROP_LINK | DND.DROP_COPY;
		Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance() };
		viewer.addDropSupport(dndOperations, transfers,
				new ProcessEditorDropAdapter(editingDomain, viewer));
	}

	private void setCurrentViewer(Viewer viewer) {
		// If it is changing...
		//
		if (currentViewer != viewer) {
			if (selectionChangedListener == null) {
				// Create the listener on demand.
				//
				selectionChangedListener = new ISelectionChangedListener() {
					// This just notifies those things that are affected by the
					// section.
					//
					public void selectionChanged(
							SelectionChangedEvent selectionChangedEvent) {
						setSelection(selectionChangedEvent.getSelection());
					}
				};
			}

			// Stop listening to the old one.
			//
			if (currentViewer != null) {
				currentViewer
						.removeSelectionChangedListener(selectionChangedListener);
			}

			// Start listening to the new one.
			//
			if (viewer != null) {
				viewer.addSelectionChangedListener(selectionChangedListener);
			}

			// Remember it.
			//
			currentViewer = viewer;

			// Set adapter factory of editingDomain to that of the current view
			//
			if (currentViewer instanceof ProcessViewer) {
				IContentProvider contentProvider = ((ProcessViewer) currentViewer)
						.getContentProvider();
				if (contentProvider instanceof AdapterFactoryContentProvider) {
					AdapterFactoryContentProvider adapterFactoryContentProvider = ((AdapterFactoryContentProvider) contentProvider);
					AdapterFactory adapterFactory = adapterFactoryContentProvider
							.getAdapterFactory();
					if (adapterFactory instanceof EditingDomainComposedAdapterFactory) {
						((EditingDomainComposedAdapterFactory) adapterFactory)
								.setEditingDomain(editingDomain);
					} else {
						editingDomain.setAdapterFactory(adapterFactory);
					}

					if (propContentProvider != null) {
						propContentProvider.setAdapterFactory(adapterFactory);
					}
				}
			}

			// Set the editors selection based on the current viewer's
			// selection.
			//
			setSelection(currentViewer == null ? StructuredSelection.EMPTY
					: currentViewer.getSelection());

		}
	}

	private static Activity getParentActivity(BreakdownElement e,
			AdapterFactory adapterFactory) {
		Activity act = UmaUtil.getParentActivity(e);
		if (act != null) {
			return act;
		}

		// TODO: handle element that does not directly belong to an activity
		// (like deliverable part of a deliverable descriptor)
		//

		return null;
	}

	private static AdapterFactory getAdapterFactory(StructuredViewer viewer) {
		return ((AdapterFactoryContentProvider) viewer.getContentProvider())
				.getAdapterFactory();
	}

	private static void setSelectionToViewer(Viewer viewer,
			IStructuredSelection otherSel, boolean alternateSelection) {
		if (alternateSelection) {
			IStructuredSelection sel = (IStructuredSelection) viewer
					.getSelection();
			Object currentSelection = null;
			if (sel.size() == 1) {
				currentSelection = sel.getFirstElement();
				if (currentSelection instanceof BreakdownElement) {
					Activity act = getParentActivity(
							(BreakdownElement) currentSelection,
							getAdapterFactory((StructuredViewer) viewer));
					if (act != otherSel.getFirstElement()) {
						viewer.setSelection(otherSel, true);
					}
				}
			} else {
				viewer.setSelection(otherSel, true);
			}
		} else {
			viewer.setSelection(otherSel, true);
		}
	}

	/**
	 * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
	 */
	public void setSelection(ISelection selection) {
		if (synchronizingSelection) {
			return;
		}

		// // check if the resources of selected objects are out of synch or any
		// of the selected objects
		// // became proxy then refresh them if needed
		// //
		// if(refreshOutOfSynch(selection)) {
		// return;
		// }

		viewSelection = selection;
		ArrayList listenerList = new ArrayList(selectionChangedListeners);

		for (int i = 0; i < listenerList.size(); i++) {
			ISelectionChangedListener listener = (ISelectionChangedListener) listenerList
					.get(i);
			listener
					.selectionChanged(new SelectionChangedEvent(this, selection));
		}

		// synchronize selection in all BS views if only one element is selected
		//
		synchronizeSelection(selection, currentViewer);
	}

	/**
	 * @param selection
	 * @return
	 */
	private boolean refreshOutOfSynch(ISelection selection) {
		if (currentViewer != null && selection instanceof IStructuredSelection) {
			boolean refreshRequired = false;
			IStructuredSelection sel = (IStructuredSelection) selection;
			HashSet resources = new HashSet();
			for (Iterator iter = sel.iterator(); iter.hasNext();) {
				Object e = TngUtil.unwrap(iter.next());
				if (e instanceof EObject) {
					EObject eObject = ((EObject) e);
					if (eObject.eIsProxy()) {
						eObject = RefreshJob.getInstance().resolve(eObject);
						refreshRequired = true;
					}
					Resource resource = eObject.eResource();
					if (resource != null) {
						resources.add(resource);
					}
				}
			}
			if (!resources.isEmpty()) {
				ArrayList removedResources = new ArrayList();
				ArrayList changedResources = new ArrayList();
				ResourceUtil.checkOutOfSynchResources(resources,
						removedResources, changedResources);
				if (!removedResources.isEmpty() || !changedResources.isEmpty()) {
					boolean ret = promptReloadFiles();
					if (ret) {
						// unload the removed resources
						//
						if (!removedResources.isEmpty()) {
							for (Iterator iter = removedResources.iterator(); iter
									.hasNext();) {
								MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) iter
										.next();
								try {
									resource.unloadWithoutRemove();
								} catch (Exception e) {
									CommonPlugin.INSTANCE.log(e);
								}
							}
						}

						Collection reloadedResources = null;
						if (!changedResources.isEmpty()) {
							// Reload the changed resources.
							ILibraryManager manager = (ILibraryManager) LibraryService
									.getInstance().getCurrentLibraryManager();
							if (manager != null) {
								reloadedResources = manager
										.reloadResources(changedResources);
							}
						}

						if (!removedResources.isEmpty()
								|| reloadedResources != null) {
							refreshRequired = true;
						}

						// refresh out-of-synch resources
						//
						for (Iterator iter = changedResources.iterator(); iter
								.hasNext();) {
							FileManager.getInstance().refresh(
									(Resource) iter.next());
						}
					}
				}
			}
			if (refreshRequired) {
				currentViewer.refresh();
				return true;
			}
		}

		return false;
	}

	/**
	 * @param selection
	 */
	private void synchronizeSelection(ISelection selection, Viewer currentViewer) {
		try {
			synchronizingSelection = true;
			if (currentViewer != null
					&& selection instanceof IStructuredSelection) {
				IStructuredSelection sel = (IStructuredSelection) selection;
				if (sel.size() == 1) {
					Object selected = sel.getFirstElement();
					IStructuredSelection otherSel = null;
					boolean alternateSelection = false;
					ArrayList selectedPath = null;
					AdapterFactory adapterFactory = getAdapterFactory((StructuredViewer) currentViewer);
					if (selected instanceof BreakdownElementWrapperItemProvider) {
						if (((BreakdownElementWrapperItemProvider) selected)
								.isReadOnly()) {
							if (adapterFactory != null) {
								// get path
								//
								Object e = TngUtil.unwrap(selected);
								selectedPath = new ArrayList();
								ITreeItemContentProvider adapter = (ITreeItemContentProvider) selected;
								do {
									selectedPath.add(0, e);
									Object parent = adapter.getParent(e);
									if (parent == null) {
										break;
									}
									if (parent instanceof BreakdownElementWrapperItemProvider) {
										adapter = (ITreeItemContentProvider) parent;
										e = TngUtil.unwrap(parent);
									} else {
										adapter = (ITreeItemContentProvider) adapterFactory
												.adapt(
														parent,
														ITreeItemContentProvider.class);
										e = parent;
									}
								} while (true);
							}
						} else if (procTab.getViewer() == currentViewer) {
							selected = TngUtil.unwrap(selected);
							selection = new StructuredSelection(selected);
						} else if (extensionTabs != null) {
							for (int i = 0; i < extensionTabs.length; i++) {
								if (extensionTabs[i].getViewer() == currentViewer) {
									selected = TngUtil.unwrap(selected);
									selection = new StructuredSelection(
											selected);

								}
							}
						}
					}
					if (selected instanceof BreakdownElement) {
						if (procTab.getViewer() != currentViewer) {
							procTab.getViewer().setSelection(selection, false);
						}
						if (extensionTabs != null) {
							for (int i = 0; i < extensionTabs.length; i++) {
								if (extensionTabs[i].getViewer() != currentViewer)
									extensionTabs[i].getViewer().setSelection(
											selection, false);
							}
						}

						if (selected instanceof Activity
								|| selected instanceof Milestone) {
							otherSel = (IStructuredSelection) selection;
						} else {
							Activity act = getParentActivity(
									(BreakdownElement) selected, adapterFactory);
							if (act != null) {
								otherSel = new StructuredSelection(act);
								alternateSelection = true;
							}
						}
					}
					if (otherSel != null) {
						// own element is selected
						//
						Viewer viewer = WBSTab.getViewer();
						if (viewer != currentViewer) {
							if (selected instanceof WorkBreakdownElement) {
								viewer.setSelection(selection, false);
							} else {
								setSelectionToViewer(viewer, otherSel,
										alternateSelection);
							}
						}
						viewer = OBSTab.getViewer();
						if (viewer != currentViewer) {
							if (selected instanceof RoleDescriptor) {
								viewer.setSelection(selection, false);
							} else {
								setSelectionToViewer(viewer, otherSel,
										alternateSelection);
							}
						}
						viewer = PBSTab.getViewer();
						if (viewer != currentViewer) {
							if (selected instanceof WorkProductDescriptor) {
								viewer.setSelection(selection, false);
							} else {
								setSelectionToViewer(viewer, otherSel,
										alternateSelection);
							}
						}
					} else if (selectedPath != null) {
						// inherited element is selected
						//
						Viewer viewer = WBSTab.getViewer();
						if (viewer != currentViewer) {
							selection = new StructuredSelection(findSelection(
									selectedPath, WBSTab.getAdapterFactory()));
							viewer.setSelection(selection, false);
						}
						viewer = OBSTab.getViewer();
						if (viewer != currentViewer) {
							selection = new StructuredSelection(findSelection(
									selectedPath, OBSTab.getAdapterFactory()));
							viewer.setSelection(selection, false);
						}
						viewer = PBSTab.getViewer();
						if (viewer != currentViewer) {
							selection = new StructuredSelection(findSelection(
									selectedPath, PBSTab.getAdapterFactory()));
							viewer.setSelection(selection, false);
						}
						viewer = procTab.getViewer();
						if (viewer != currentViewer) {
							selection = new StructuredSelection(findSelection(
									selectedPath, procTab.getAdapterFactory()));
							viewer.setSelection(selection, false);
						}

						if (extensionTabs != null) {
							for (int i = 0; i < extensionTabs.length; i++) {
								viewer = extensionTabs[i].getViewer();
								if (viewer != currentViewer) {
									selection = new StructuredSelection(
											findSelection(
													selectedPath,
													extensionTabs[i]
															.getAdapterFactory()));
									viewer.setSelection(selection, false);
								}
							}
						}
					}
				}
			}
		} finally {
			synchronizingSelection = false;
		}
	}

	private static Object findSelection(List selectedPath,
			AdapterFactory adapterFactory) {
		int size = selectedPath.size();
		if (size == 0) {
			return null;
		}
		Object e = selectedPath.get(0);
		Object selection = e;
		ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory
				.adapt(e, ITreeItemContentProvider.class);
		Collection children = adapter.getChildren(e);
		find_selection: for (int i = 1; i < size; i++) {
			e = selectedPath.get(i);
			for (Iterator iter = children.iterator(); iter.hasNext();) {
				Object child = iter.next();
				Object element = TngUtil.unwrap(child);
				if (element == e) {
					selection = child;
					adapter = (ITreeItemContentProvider) adapterFactory.adapt(
							child, ITreeItemContentProvider.class);
					children = adapter.getChildren(e);
					continue find_selection;
				}
			}
			break find_selection;
		}
		return selection;
	}

	// Implements ISelectionProvider
	//
	public void addSelectionChangedListener(ISelectionChangedListener listener) {
		selectionChangedListeners.add(listener);
	}

	public void removeSelectionChangedListener(
			ISelectionChangedListener listener) {
		selectionChangedListeners.remove(listener);
	}

	/**
	 * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection()
	 */
	public ISelection getSelection() {
		return viewSelection;
	}

	/**
	 * @see org.eclipse.emf.edit.domain.IEditingDomainProvider#getEditingDomain()
	 */
	public EditingDomain getEditingDomain() {
		return editingDomain;
	}

	/**
	 * @see org.eclipse.emf.common.ui.viewer.IViewerProvider#getViewer()
	 */
	public Viewer getViewer() {
		return currentViewer;
	}

	/**
	 * Gets the adapter factory of the current page if there is any
	 * 
	 * @return
	 * 		Adapter Factory of the current page of the editor
	 */
	public AdapterFactory getAdapterFactory() {
		IFormPage page = getActivePageInstance();
		if (page instanceof ProcessBreakdownStructureFormPage) {
			return ((ProcessBreakdownStructureFormPage) page)
					.getAdapterFactory();
		}

		return null;
	}

	/**
	 * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
	 */
	public void menuAboutToShow(IMenuManager menuManager) {
		((IMenuListener) getEditorSite().getActionBarContributor())
				.menuAboutToShow(menuManager);
		
		// populate contributed menu items
		//
		IFormPage activePage = getActivePageInstance();
		if(activePage instanceof ProcessBreakdownStructureFormPage) {
			IAction[] actions = ((ProcessBreakdownStructureFormPage)activePage).getAdditionalActions();
			if(actions != null && actions.length > 0) {
				menuManager.insertAfter(IWorkbenchActionConstants.MB_ADDITIONS, new Separator());
				for (int i = 0; i < actions.length; i++) {
					IAction action = actions[i];
					ISelection selection = getSelection();
					if(selection instanceof IStructuredSelection && action instanceof BaseSelectionListenerAction) {
						((BaseSelectionListenerAction)action).selectionChanged((IStructuredSelection) selection);
					}
					if (action instanceof IWorkbenchPartAction) {
						((IWorkbenchPartAction) action)
								.setActiveWorkbenchPart(this);
					}
					menuManager.insertAfter(IWorkbenchActionConstants.MB_ADDITIONS, action);
				}
			}
		}
	}

	/**
	 * Return property sheet page
	 * @return
	 * 			PropertySheet Page
	 */
	public IPropertySheetPage getPropertySheetPage() {
		if (propertySheetPage == null) {
			propertySheetPage = new EPFPropertySheetPage(this);
			// {
			// public void makeContributions(IMenuManager menuManager,
			// IToolBarManager toolBarManager, IStatusLineManager
			// statusLineManager) {
			// super.makeContributions(menuManager, toolBarManager,
			// statusLineManager);
			// }
			//
			// public void setActionBars(IActionBars actionBars) {
			// super.setActionBars(actionBars);
			// getActionBarContributor().shareGlobalActions(this, actionBars);
			// }
			// };
			// System.out.println("Setting provider ");
			if (currentViewer != null) {
				AdapterFactoryContentProvider contentProvider = (AdapterFactoryContentProvider) ((ProcessViewer) currentViewer)
						.getContentProvider();
				propContentProvider = new AdapterFactoryContentProvider(
						contentProvider.getAdapterFactory());
				propertySheetPage
						.setPropertySourceProvider(propContentProvider);
			}
		}
		return propertySheetPage;
	}

	/**
	 * @see org.eclipse.ui.part.MultiPageEditorPart#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class key) {
		if (key.equals(IPropertySheetPage.class)) {
			return getPropertySheetPage();
		} else if (key.equals(IGotoMarker.class)) {
			return this;
		} else {
			return super.getAdapter(key);
		}
	}


	/**
	 * @see org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor#getContributorId()
	 */
	public String getContributorId() {
		return getSite().getId();
	}

	
	/**
	 * Return column descriptor list for given string
	 * @param str
	 * @return
	 * 			list of column descriptors
	 */
	public static EList toColumnDescriptorList(String str) {
		EList columnDescriptors = new BasicEList();
		StringTokenizer tokens = new StringTokenizer(str, ","); //$NON-NLS-1$
		while (tokens.hasMoreTokens()) {
			String token = tokens.nextToken();
			Object columnDescriptor = ProcessEditor.idToColumnDescriptorMap
					.get(token);
			if (columnDescriptor != null) {
				columnDescriptors.add(columnDescriptor);
			}
		}
		return columnDescriptors;
	}

	/**
	 * Return array of column descriptors for the given string
	 * @param str
	 * @return
	 * 			list of column descriptors
	 */
	public static ColumnDescriptor[] toColumnDescriptors(String str) {
		List list = toColumnDescriptorList(str);
		ColumnDescriptor[] columns = new ColumnDescriptor[list.size()];
		list.toArray(columns);
		return columns;
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormEditor#getCurrentPage()
	 */
	public int getCurrentPage() {
		return super.getCurrentPage();
	}

	/**
	 * Return suppression info
	 */
	public Suppression getSuppression() {
		return suppression;
	}

	private void configChanged() {
		MethodConfiguration config = LibraryService.getInstance()
				.getCurrentMethodConfiguration();
		if (config != currentConfig) {
			// refresh only if the active part is this editor or diagram editor
			// of any activity in this process
			//
			IWorkbenchPart activePart = getSite().getWorkbenchWindow()
					.getPartService().getActivePart();
			boolean refresh = activePart == this;
			if (!refresh) {
				if (activePart instanceof AbstractDiagramEditor) {
					BreakdownElementEditorInput input = (BreakdownElementEditorInput) ((IEditorPart) activePart)
							.getEditorInput();
					refresh = input.getSuppression().getProcess() == selectedProcess;
				}
			}
			if (refresh) {
				currentConfig = config;
				refreshAll();
			}
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.editors.MethodElementEditor#setInput(org.eclipse.ui.IEditorInput)
	 */
	protected void setInput(IEditorInput input) {
		if (input != getEditorInput()) {
			inputChanged = true;
		}
		super.setInput(input);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.editors.MethodElementEditor#updatePages()
	 */
	protected void updatePages() {
		// remove and add description page if the model.xmi or content.xmi of
		// the process have been changed
		//
		Resource modelResource = selectedProcess.eResource();
		Resource contentResource = selectedProcess.getPresentation()
				.eResource();
		if (changedResources.contains(modelResource)
				|| (contentResource != null && changedResources
						.contains(contentResource))) {
			removePage(0);
			try {
				addDescriptionPage();
			} catch (PartInitException e) {
				AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
						AuthoringUIResources.ProcessEditor_refreshErrorTitle, //$NON-NLS-1$
						AuthoringUIResources.ProcessEditor_refreshErrorMsg, e); //$NON-NLS-1$
			}
		}
		if (inputChanged) {
			inputChanged(getEditorInput());
			if (propertySheetPage != null) {
				propertySheetPage.refresh();
			}
		} else {
			refreshAll();
		}
	}

	private void refreshAll() {
		BusyIndicator.showWhile(getSite().getShell().getDisplay(),
				new Runnable() {

					public void run() {
						doRefreshAll(true);
					}

				});
	}

	/**
	 * Refresh all viewers 
	 * @param updateIDs
	 * 			if true, then refresh all index in viewers
	 */
	public void doRefreshAll(boolean updateIDs) {
		if (updateIDs) {
			AdapterFactory adapterFactory = TngAdapterFactory.INSTANCE
					.getWBS_ComposedAdapterFactory();
			ProcessUtil.updateIDs(adapterFactory, selectedProcess);
			ProcessUtil.refreshPredeccessorLists(adapterFactory,
					selectedProcess);

			adapterFactory = TngAdapterFactory.INSTANCE
					.getProcessComposedAdapterFactory();
			ProcessUtil.updateIDs(adapterFactory, selectedProcess);
		}

		WBSTab.getViewer().refresh();
		OBSTab.getViewer().refresh();
		PBSTab.getViewer().refresh();
		procTab.getViewer().refresh();

		if (extensionTabs != null) {
			for (int i = 0; i < extensionTabs.length; i++) {
				extensionTabs[i].getViewer().refresh();
			}
		}

		if (propertySheetPage != null) {
			propertySheetPage.refresh();
		}
	}
	

	/**
	 * Refresh all open process editors
	 */
	public void refreshAllProcessEditors() {
		IEditorReference[] editorReferences = getSite().getPage()
				.getEditorReferences();
		for (int i = 0; i < editorReferences.length; i++) {
			IEditorReference reference = editorReferences[i];
			IEditorPart editor = reference.getEditor(true);
			if (editor instanceof ProcessEditor) {
				((ProcessEditor) editor).doRefreshAll(false);
			}
		}
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormEditor#getActivePageInstance()
	 */
	public IFormPage getActivePageInstance() {
		int index = getActivePage();
		if (index == -1) {
			return null;
		}
		if (index == 0) {
			return super.getActivePageInstance();
		}
		return bsPages[index - 1];
	}

	protected Collection getModifiedResources() {
		Collection modifiedResources = super.getModifiedResources();
		if (suppression.isSaveNeeded()
				&& !modifiedResources.contains(selectedProcessComponent
						.eResource())) {
			modifiedResources.add(selectedProcessComponent.eResource());
		}
		modifiedResources.addAll(resourcesToSave);

		return modifiedResources;
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.editors.MethodElementEditor#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void doSave(IProgressMonitor monitor) {
		suppression.saveToModel();
		super.doSave(monitor);
		suppression.saveIsDone();
		resourcesToSave.clear();
		firePropertyChange(PROP_DIRTY);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.editors.MethodElementEditor#isDirty()
	 */
	public boolean isDirty() {
		if (suppression.isSaveNeeded()) {
			return true;
		}
		return super.isDirty();
	}

	
	/**
	 * @see org.eclipse.ui.part.WorkbenchPart#firePropertyChange(int)
	 */
	public void firePropertyChange(int propertyId) {
		super.firePropertyChange(propertyId);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.editors.MethodElementEditor#getUsedResources()
	 */
	public Collection getUsedResources() {
		HashSet usedResources = new HashSet();

		// model.xmi
		//
		Resource resource = elementObj.eResource();
		if (resource != null) {
			usedResources.add(resource);
		}

		// content.xmi
		//
		resource = selectedProcess.getPresentation().eResource();
		if (resource != null) {
			usedResources.add(resource);
		}

		// configuration.xmi
		//
		MethodConfiguration config = selectedProcess.getDefaultContext();
		if (config != null) {
			resource = config.eResource();
			if (resource != null) {
				usedResources.add(resource);
			}
		}

		// resources of other processes that this process is depending on
		//
		AdapterFactory adapterFactory = WBSTab.getAdapterFactory();
		for (Iterator iter = new AdapterFactoryTreeIterator(adapterFactory,
				selectedProcess); iter.hasNext();) {
			Object obj = TngUtil.unwrap(iter.next());
			if (obj instanceof EObject) {
				resource = ((EObject) obj).eResource();
				if (resource != null) {
					usedResources.add(resource);
				}
			}
		}

		lastUsedResources = usedResources;

		return usedResources;
	}

	/**
	 * Check whether selected objects can be revealed or not and retuns result
	 * 
	 * @param selection
	 * 			List of objects
	 * @param adapterFactory
	 * 			Adapter factory of the selected objects
	 * @param suppression
	 * 			Suppression information
	 * @return
	 * 		Boolean value to indicate whether selected objects can be revealed
	 */
	public static boolean canReveal(Collection selection,
			AdapterFactory adapterFactory, Suppression suppression) {
		// check if revealing the selected elements will cause name duplication
		//
		String msg = suppression.checkDuplicateNameAfterReveal(selection,
				adapterFactory);
		if (msg != null) {
			AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
					AuthoringUIResources.ProcessEditor_Reveal_Title, //$NON-NLS-1$ 
					msg);
			return false;
		}

		// check if revealing the selected elements will cause duplicate
		// descriptors.
		// If so, prompt user to delete the duplicates before continuing.
		//
		Collection duplicates = ProcessUtil
				.getDuplicateDescriptorsAfterReveal(selection);
		if (!duplicates.isEmpty()) {
			MultiStatus status = new MultiStatus(AuthoringUIPlugin.getDefault()
					.getId(), 0, "", null); //$NON-NLS-1$
			for (Iterator iter = duplicates.iterator(); iter.hasNext();) {
				Descriptor desc = (Descriptor) iter.next();
				String descTxt = TngUtil.getTypeText(desc)
						+ ": " + desc.getPresentationName(); //$NON-NLS-1$
				status.add(new Status(IStatus.INFO, AuthoringUIPlugin
						.getDefault().getId(), 0, descTxt, null));
			}
			if (AuthoringUIPlugin
					.getDefault()
					.getMsgDialog()
					.displayConfirmation(
							AuthoringUIResources.ProcessEditor_Reveal_Title, //$NON-NLS-1$ 
							AuthoringUIResources.ProcessEditor_promptToDeleteBeforeReveal, //$NON-NLS-1$
							status) == Dialog.CANCEL) {
				return false;
			}

			// delete duplicate descriptors
			try {
				ProcessDeleteAction.delete(duplicates);
			} catch (OperationCanceledException e) {
				return false;
			}
		}

		return true;
	}

	private static boolean hasInherited(Collection selection) {
		for (Iterator iter = selection.iterator(); iter.hasNext();) {
			Object element = iter.next();
			if (ProcessUtil.isInherited(element)) {
				return true;
			}
		}
		return false;
	}

	private IPreferenceStore getPreferenceStore() {
		// preference is managed by library plugin,
		// since this preferences is also used for browsing and publishing
		// Jinhua Xi 08/21/2006
		// IPreferenceStore store = AuthoringUIPlugin.getDefault()
		// .getPreferenceStore();
		IPreferenceStore store = LibraryPlugin.getDefault()
				.getPreferenceStore();

		return store;
	}
}