//------------------------------------------------------------------------------
// 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.ad.part.ActivityDiagramEditorPlugin;
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.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 ActivityDiagramEditorPlugin.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();
				}

			};
		}

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