//------------------------------------------------------------------------------
// 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.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.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.LibraryLockingOperationRunner;
import org.eclipse.epf.authoring.ui.actions.MethodLibraryActionBarContributor;
import org.eclipse.epf.authoring.ui.actions.ProcessAutoSynchronizeAction;
import org.eclipse.epf.authoring.ui.actions.ProcessDeleteAction;
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.views.LibraryView;
import org.eclipse.epf.authoring.ui.views.ProcessViewer;
import org.eclipse.epf.authoring.ui.views.ViewHelper;
import org.eclipse.epf.diagram.model.util.GraphicalDataHelper;
import org.eclipse.epf.diagram.model.util.GraphicalDataManager;
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.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.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.events.ILibraryChangeListener;
import org.eclipse.epf.library.prefs.PreferenceUtil;
import org.eclipse.epf.library.ui.LibraryUIImages;
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.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
 * @authos 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, AuthoringUIResources.ProcessEditor_Name,
			3, 200, true, ColumnDescriptor.CELL_EDITOR_TYPE_TEXT);

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

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

	public static final ColumnDescriptor COL_DESC_MODEL_INFO = new ColumnDescriptor(
			IBSItemProvider.COL_MODEL_INFO,
			AuthoringUIResources.ProcessEditor_ModelInfo, 0, 120, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_NONE); //$NON-NLS-1$

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

	public static final ColumnDescriptor COL_DESC_PREDECESSORS = new ColumnDescriptor(
			IBSItemProvider.COL_PREDECESSORS,
			AuthoringUIResources.ProcessEditor_Predecessors, 2, 100, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT); //$NON-NLS-1$

	public static final ColumnDescriptor COL_DESC_IS_REPEATABLE = new ColumnDescriptor(
			IBSItemProvider.COL_IS_REPEATABLE,
			AuthoringUIResources.ProcessEditor_Repetable, 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_CHECK_BOOLEAN); //$NON-NLS-1$

	public static final ColumnDescriptor COL_DESC_IS_ONGOING = new ColumnDescriptor(
			IBSItemProvider.COL_IS_ONGOING,
			AuthoringUIResources.ProcessEditor_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,
			AuthoringUIResources.ProcessEditor_EventDriven, 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_CHECK_BOOLEAN); //$NON-NLS-1$

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

	public static final ColumnDescriptor COL_DESC_ENTRY_STATE = new ColumnDescriptor(
			IBSItemProvider.COL_ENTRY_STATE,
			AuthoringUIResources.ProcessEditor_EntryState, 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT); //$NON-NLS-1$

	public static final ColumnDescriptor COL_DESC_EXIT_STATE = new ColumnDescriptor(
			IBSItemProvider.COL_EXIT_STATE,
			AuthoringUIResources.ProcessEditor_ExitState, 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT); //$NON-NLS-1$

	public static final ColumnDescriptor COL_DESC_PRESENTATION_NAME = new ColumnDescriptor(
			IBSItemProvider.COL_PRESENTATION_NAME,
			AuthoringUIResources.ProcessEditor_PresentationName, 3, 200, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT); //$NON-NLS-1$

	public static final ColumnDescriptor COL_DESC_DELIVERABLE = new ColumnDescriptor(
			IBSItemProvider.COL_DELIVERABLE,
			AuthoringUIResources.ProcessEditor_Deliverable, 1, 100, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_TEXT); //$NON-NLS-1$

	public static final ColumnDescriptor COL_DESC_IS_OPTIONAL = new ColumnDescriptor(
			IBSItemProvider.COL_IS_OPTIONAL,
			AuthoringUIResources.ProcessEditor_Optional, 1, 60, true,
			ColumnDescriptor.CELL_EDITOR_TYPE_CHECK_BOOLEAN); //$NON-NLS-1$

	public static final ColumnDescriptor COL_DESC_IS_PLANNED = new ColumnDescriptor(
			IBSItemProvider.COL_IS_PLANNED,
			AuthoringUIResources.ProcessEditor_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,
			AuthoringUIResources.ProcessEditor_MultipleOccurrences, 1, 60,
			true, ColumnDescriptor.CELL_EDITOR_TYPE_CHECK_BOOLEAN); //$NON-NLS-1$

	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;

	public static class BSActionBarContributor extends
			MethodLibraryActionBarContributor {
		private Collection registeredActions = new ArrayList();

		private boolean locked;

		private IAction rollupAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_RollUp) { //$NON-NLS-1$

			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 (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$   //$NON-NLS-2$     
			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$   //$NON-NLS-2$      
			public void run() {
				bsItemProvider.moveDown(selectedBreakdownElement,
						getActionManager());
				refreshMoveButtonActions();
			}
		};

		private IAction openBaseActivity = new Action(
				AuthoringUIResources.ProcessEditor_Action_OpenBaseActivity) { //$NON-NLS-1$
			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) { //$NON-NLS-1$
			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);
				}
			}
		};

		// Open workflow detail action
		//
		private IAction openWorkflowDetailEditorAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_OpenActivityDetailDiagram) { //$NON-NLS-1$
			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) { //$NON-NLS-1$
			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) { //$NON-NLS-1$
			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) { //$NON-NLS-1$
			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);
				}
			}

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

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

		}

		private IAction suppressAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Suppress) { //$NON-NLS-1$

			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, //$NON-NLS-1$
									status) == Dialog.CANCEL) {
						return;
					}

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

				// 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) { //$NON-NLS-1$

			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 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) { //$NON-NLS-1$
			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); //$NON-NLS-1$
				dlg.setInitialElementSelections(unsuppressedDiagrams);
				dlg
						.setTitle(AuthoringUIResources.ProcessEditor_SuppressDialog_Title); //$NON-NLS-1$
				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 suppressAllDiagrams = new Action(
				AuthoringUIResources.ProcessEditor_Action_SuppressAll) { //$NON-NLS-1$
			public void run() {
				setAllDiagramSuppressed(true);
			}
		};

		private IAction revealAllDiagrams = new Action(
				AuthoringUIResources.ProcessEditor_Action_RevealAll) { //$NON-NLS-1$
			public void run() {
				setAllDiagramSuppressed(false);
			}
		};

		private IAction addAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Add) { //$NON-NLS-1$
			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) { //$NON-NLS-1$
			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 (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();
							}
						}	
					}
				}

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

		private IAction extendActivityAction = new Action(
				AuthoringUIResources.ProcessEditor_Action_Extend) { //$NON-NLS-1$
			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 (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();
							}
							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;
							}
						}	
					}
				}
				ActivityDropCommand cmd = new ActivityDropCommand(
						selectedActivity, selection, null, getAdapterFactory());
				cmd.setType(IActionTypeProvider.EXTEND);
				getActionManager().execute(cmd);
			}
		};

		private IAction deepCopyActivityAction = new Action(
				AuthoringUIResources.ProcessEditor_action_deepCopy) { //$NON-NLS-1$
			/*
			 * (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();
									}
								}	
							}
						}

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

		private ProcessAutoSynchronizeAction autoSynchronize = new ProcessAutoSynchronizeAction() {
			private void superRun() {
				super.run();
			}
			
			/*
			 * (non-Javadoc)
			 * 
			 * @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(
										getText(),
										AuthoringUIResources.ProcessEditor_confirmAutoSynch)) { //$NON-NLS-1$
							return;
						}
						// ((SynchronizeCommand)command).setUIContext(getActiveEditor().getSite().getShell());
						superRun();
					}
				});
				
			}
		};

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

			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) { //$NON-NLS-1$
			/*
			 * (non-Javadoc)
			 * 
			 * @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 boolean oldLocked;

		public BSActionBarContributor() {
			super(AuthoringUIResources.ProcessEditor);

			// 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$
		}
		
		protected void registerAction(IAction action) {
			if (action != null && !registeredActions.contains(action)) {
				registeredActions.add(action);
			}
		}

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

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

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

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

		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; //$NON-NLS-1$
			String message = AuthoringUIResources.processFormEditorSaveDialog_message1; //$NON-NLS-1$

			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 boolean promptSaveActiveEditor() {
			String title = AuthoringUIResources.processFormEditorSaveDialog_title; //$NON-NLS-1$
			String message = AuthoringUIResources.processFormEditorSaveDialog_message2; //$NON-NLS-1$
			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());
							}

						});
					}
				}
			};
		}

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

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

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

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

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

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

		/*
		 * (non-Javadoc)
		 * 
		 * @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); //$NON-NLS-1$
			moveDownAction
					.setToolTipText(AuthoringUIResources.ProcessEditor_Action_MoveDown); //$NON-NLS-1$
			showInLibraryView
					.setToolTipText(AuthoringUIResources.ProcessEditor_Action_ShowLinkedElementinLibraryView); //$NON-NLS-1$
			toolBarManager.add(moveUpAction);
			toolBarManager.add(moveDownAction);
			toolBarManager.add(showInLibraryView);
		}				

		/*
		 * (non-Javadoc)
		 * 
		 * @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));								
				if (showInLibraryView.isEnabled()) {
					menuManager.add(showInLibraryView);
				}
				if (bsItemProvider != null
				// && ((ITreeItemContentProvider)
				// bsItemProvider).hasChildren(selectedObject)
				) {
					menuManager.add(expandAllAction); //$NON-NLS-1$
					menuManager.add(collapseAllAction); //$NON-NLS-1$
				}
				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("open")); //$NON-NLS-1$ //$NON-NLS-2$

			if (bsItemProvider instanceof BreakdownElementWrapperItemProvider
					&& TngUtil.unwrap(bsItemProvider) instanceof Activity) {
				menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, contributeAction); //$NON-NLS-1$
				menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, replaceAction); //$NON-NLS-1$
				menuManager.insertBefore(
						IWorkbenchActionConstants.MB_ADDITIONS, localReplacementAndDeepCopy); //$NON-NLS-1$
			}

			if (!isRolledUP) {
				if (createChildActions != null && !createChildActions.isEmpty()) {
					menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, addAction); //$NON-NLS-1$
				}
			}

			if (revealAction.isEnabled()) {
				menuManager.insertBefore("fixed-additions", revealAction); //$NON-NLS-1$
			}
			if (suppressAction.isEnabled()) {
				menuManager.insertBefore("fixed-additions", suppressAction); //$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$
				}
			}

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

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

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

				menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, reuseSubMenu); //$NON-NLS-1$
			}

			if (autoSynchronize.isEnabled()) {
				menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, autoSynchronize); //$NON-NLS-1$
			}
			if (manualSynchronizeAction.isEnabled()) {
				menuManager.insertBefore(IWorkbenchActionConstants.MB_ADDITIONS, manualSynchronizeAction); //$NON-NLS-1$
			}

			if (!(selectedElement instanceof Milestone)) {
				MenuManager diagramSubMenu = new MenuManager(
						AuthoringUIResources.ProcessEditor_Action_Diagrams); //$NON-NLS-1$
				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);
				}
				menuManager.appendToGroup("open", diagramSubMenu); //$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);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.jface.viewers.ISelectionChangedListener#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));
				}

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

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

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

		/*
		 * (non-Javadoc)
		 * 
		 * @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() {
		/*
		 * (non-Javadoc)
		 * 
		 * @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;

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

	/*
	 * (non-Javadoc)
	 * 
	 * @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) {
							// update consolidated view as well
							//
							procTab.updateColumns(cols);
						}
					}
				}

			};
		}

		getPreferenceStore()
				.addPropertyChangeListener(prefStoreListener);

	}

	/**
	 * This sets the selection into whichever viewer is active. <!--
	 * begin-user-doc --> <!-- end-user-doc -->
	 * 
	 * @generated
	 */
	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));
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @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));
			procTab.setColumnDescriptors(columnDescriptors);
			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);
			}
		}
	}

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

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

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

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

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

	/*
	 * (non-Javadoc)
	 * 
	 * @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
	 */
	public AdapterFactory getAdapterFactory() {
		IFormPage page = getActivePageInstance();
		if (page instanceof ProcessBreakdownStructureFormPage) {
			return ((ProcessBreakdownStructureFormPage) page)
					.getAdapterFactory();
		}

		return null;
	}

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

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

	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.wst.common.ui.properties.ITabbedPropertySheetPageContributor#getContributorId()
	 */
	public String getContributorId() {
		return getSite().getId();
	}

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

	public static ColumnDescriptor[] toColumnDescriptors(String str) {
		List list = toColumnDescriptorList(str);
		ColumnDescriptor[] columns = new ColumnDescriptor[list.size()];
		list.toArray(columns);
		return columns;
	}

	public int getCurrentPage() {
		return super.getCurrentPage();
	}

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

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

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

				});
	}

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

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

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

	public void doSave(IProgressMonitor monitor) {
		suppression.saveToModel();
		super.doSave(monitor);
		suppression.saveIsDone();
		resourcesToSave.clear();
		firePropertyChange(PROP_DIRTY);
	}

	public boolean isDirty() {
		if (suppression.isSaveNeeded()) {
			return true;
		}
		return super.isDirty();
	}

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

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

	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_Action_Reveal, //$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_Action_Reveal, //$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;
	}
}