//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.UnexecutableCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.NotificationImpl;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.AbstractTreeIterator;
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.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.provider.DelegatingWrapperItemProvider;
import org.eclipse.emf.edit.provider.IChangeNotifier;
import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ViewerNotification;
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.PasteAction;
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.IModifyingAction;
import org.eclipse.epf.authoring.ui.actions.IWorkbenchPartAction;
import org.eclipse.epf.authoring.ui.actions.IndentAction;
import org.eclipse.epf.authoring.ui.actions.MethodLibraryActionBarContributor;
import org.eclipse.epf.authoring.ui.actions.MoveDownAction;
import org.eclipse.epf.authoring.ui.actions.MoveUpAction;
import org.eclipse.epf.authoring.ui.actions.OutdentAction;
import org.eclipse.epf.authoring.ui.actions.ProcessAutoSynchronizeAction;
import org.eclipse.epf.authoring.ui.actions.SynchronizationAction;
import org.eclipse.epf.authoring.ui.actions.UpdateSuppressionFromBaseAction;
import org.eclipse.epf.authoring.ui.dialogs.DialogHelper;
import org.eclipse.epf.authoring.ui.dialogs.UserDefinedDiagramDialog;
import org.eclipse.epf.authoring.ui.forms.ProcessBreakdownStructureFormPage;
import org.eclipse.epf.authoring.ui.properties.EPFPropertySheetPage;
import org.eclipse.epf.authoring.ui.views.LibraryView;
import org.eclipse.epf.authoring.ui.views.ProcessViewer;
import org.eclipse.epf.authoring.ui.views.ViewHelper;
import org.eclipse.epf.diagram.ad.ADImages;
import org.eclipse.epf.diagram.add.ADDImages;
import org.eclipse.epf.diagram.core.part.DiagramEditorInput;
import org.eclipse.epf.diagram.core.part.util.DiagramEditorUtil;
import org.eclipse.epf.diagram.core.services.DiagramManager;
import org.eclipse.epf.diagram.model.util.GraphicalDataHelper;
import org.eclipse.epf.diagram.model.util.GraphicalDataManager;
import org.eclipse.epf.diagram.ui.service.DiagramEditorHelper;
import org.eclipse.epf.diagram.wpdd.part.WPDDImages;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.configuration.ActivityDeepCopyConfigurator;
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.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.DiagramOptions;
import org.eclipse.epf.library.edit.util.ExposedAdapterFactory;
import org.eclipse.epf.library.edit.util.IDiagramManager;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.util.Suppression.SuppressionCommand;
import org.eclipse.epf.library.edit.validation.DependencyChecker;
import org.eclipse.epf.library.ui.actions.LibraryLockingOperationRunner;
import org.eclipse.epf.library.ui.actions.ProcessDeleteAction;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
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.Milestone;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.VariabilityType;
import org.eclipse.epf.uma.edit.domain.TraceableAdapterFactoryEditingDomain;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
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.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.ArrayContentProvider;
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.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.forms.editor.IFormPage;

/**
 * Action bar contribtutor for process editor
 * 
 * @author Phong Nguyen Le
 * @sine 1.2
 */
public class ProcessEditorActionBarContributor extends
		MethodLibraryActionBarContributor {
	protected Collection<IAction> registeredActions = new ArrayList<IAction>();

	protected boolean locked;

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

		public void run() {
			boolean wasRolledUp = bsItemProvider.isRolledUp();
			bsItemProvider.setRolledUp(!bsItemProvider.isRolledUp());
			((IChangeNotifier) bsItemProvider)
					.fireNotifyChanged(new ViewerNotification(
							new ENotificationImpl(
									(InternalEObject) selectedActivity,
									Notification.ADD, null, null, null, false),
							selectedActivity, true, false));

			if (bsItemProvider instanceof DelegatingWrapperItemProvider) {
				// Refreshing for green activities during rollup
				DelegatingWrapperItemProvider provider = (DelegatingWrapperItemProvider) bsItemProvider;
				provider.fireNotifyChanged(new ViewerNotification(
						new NotificationImpl(Notification.SET, provider,
								provider), provider, true, false));
			}
			if (wasRolledUp) {
				ProcessViewer viewer = (ProcessViewer) ((ProcessEditor) activeEditor).currentViewer;
				viewer.expandToLevel(selectedActivity,
						AbstractTreeViewer.ALL_LEVELS);

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

	};

	protected MoveUpAction moveUpAction = new MoveUpAction() {
		@Override
		protected boolean accept(IStructuredSelection selection) {
			if(!isEditingAllowed()) {
				return false;
			}
			return super.accept(selection);
		}		
	};

	protected MoveDownAction moveDownAction = new MoveDownAction() {
		@Override
		protected boolean accept(IStructuredSelection selection) {
			if(!isEditingAllowed()) {
				return false;
			}
			return super.accept(selection);
		}
	};

	private IAction preferenceAction = new Action(
			AuthoringUIResources.ProcessEditor_Action_Preferences) {
		public void run() {
			// open process preference page
			org.eclipse.ui.dialogs.PreferencesUtil
					.createPreferenceDialogOn(
							getActiveEditor().getEditorSite().getShell(),
							"org.eclipse.epf.authoring.ui.preferences.ProcessEditorPreferencePage", //$NON-NLS-1$
							null, null).open();
		}
	};

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

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

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

		private int diagramType;

		public OpenDiagramEditorAction(String text, int diagramType) {
			super(text);
			this.diagramType = diagramType;
			setImageDescriptor(getImageDescriptor(diagramType));
			setDisabledImageDescriptor(getDisabledImageDescriptor(diagramType));
		}
		
		private ImageDescriptor getImageDescriptor(int diagramType) {
			switch(diagramType) {
			case IDiagramManager.ACTIVITY_DIAGRAM:
				return ADImages.IMG_DESC_EDITOR;
			case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
				return ADDImages.IMG_DESC_EDITOR;
			case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
				return WPDDImages.IMG_DESC_EDITOR;
			}
			return null;
		}
		
		private ImageDescriptor getDisabledImageDescriptor(int diagramType) {
			switch(diagramType) {
			case IDiagramManager.ACTIVITY_DIAGRAM:
				return ADImages.DISABLED_IMG_DESC_EDITOR;
			case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
				return ADDImages.DISABLED_IMG_DESC_EDITOR;
			case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
				return WPDDImages.DISABLED_IMG_DESC_EDITOR;
			}
			return null;
		}

		
		@Override
		public void run() {
			DiagramManager mgr = null;
			try {
				if(!ProcessUtil.isInherited(selectedObject)) {
					mgr = DiagramManager.getInstance(getProcess(), this);
					Resource resource = mgr.getResource();
					if(mgr.isNewResource() && !new File(FileManager.toFileString(resource.getURI())).exists()) {
						boolean result = AuthoringUIPlugin
						.getDefault()
						.getMsgDialog()
						.displayConfirmation(AuthoringUIResources.NewDiagramFile_title,
								AuthoringUIResources.promptCreateNewDiagramFile_msg);
						if(result) {
							resource.save(Collections.EMPTY_MAP);

							// still keep the flag resourceIsNew set so editor will be marked dirty
							//
							mgr.setResourceIsNew(true);
						}
						else {
							return;
						}
					}
				}
				openDiagram(diagramType);
			} catch (Exception exception) {
				AuthoringUIPlugin.getDefault().getLogger().logError(
						exception);
			}
			finally {
				if(mgr != null) {
					mgr.removeConsumer(this);
				}
			}
		}
	}
	
	private IAction newActivityDiagramEditor = new OpenDiagramEditorAction(
			AuthoringUIResources.ProcessEditor_Action_OpenActivityDiagram, IDiagramManager.ACTIVITY_DIAGRAM);

	private IAction newActivityDetailDiagramEditor = new OpenDiagramEditorAction(
			AuthoringUIResources.ProcessEditor_Action_OpenActivityDetailDiagram, IDiagramManager.ACTIVITY_DETAIL_DIAGRAM);

	private IAction newWPDiagramEditor = new OpenDiagramEditorAction(
			AuthoringUIResources.ProcessEditor_Action_OpenWorkProductDependencyDiagram,
			IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM);

	// Open workflow detail action
	//
	protected IAction openWorkflowDetailEditorAction = new Action(
			AuthoringUIResources.ProcessEditor_Action_OpenActivityDetailDiagram) {
		public void run() {
			try {
				try {
					IEditorPart parent = getPage().getActiveEditor();
					IEditorInput input = new ActivityDetailDiagramEditor.EditorInput(
							selectedObject, getSuppression());
					IEditorPart part = getPage().openEditor(input,
							ProcessEditor.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();
			}

		}
	};

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

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

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

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

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

		private void refresh() {
			if (!getResult().isEmpty()) {
				ProcessEditor editor = (ProcessEditor) getActiveEditor();
				if (isReadOnlyElementAffected()) {
					if (ProcessEditor.hasInherited(selection)) {
						editor.refreshAllProcessEditors();
					} else {
						editor.doRefreshAll(false);
					}
				}
				editor.firePropertyChange(IEditorPart.PROP_DIRTY);

				// Do Diagram Editors refresh
				List<IEditorReference> list = new ArrayList<IEditorReference>();
				for (Iterator iter = selection.iterator(); iter.hasNext();) {
					Object element = iter.next();
					DiagramEditorHelper.closeDiagramEditors(element, list);
					DiagramEditorHelper.refreshParentDiagramEditors(element,
							list, true);
					list.clear();
				}
			}
		}

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

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

	}

	//TODO: move this action to its own CommandActionHandler class, see IndenAction
	private IAction suppressTaskAction = new Action(
			AuthoringUIResources.ProcessEditor_Action_Suppress_Task) {

		public void run() {
			// check if suppressing the selected elements will cause
			// duplicate descriptors.
			// If so, prompt user to delete the duplicates before
			// continuing.
			//

			final List taskDescriptors = ProcessUtil
					.getTaskDescriptors(selection);
			
			// NO MORE CHECK FOR DUPLICATION OF NAME, PRESENTATION NAME, OR LINKED ELEMENT

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

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

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

			revealTaskAction.setEnabled(show);
			suppressTaskAction.setEnabled(show);

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

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

		public void run() {
			// NO MORE CHECK FOR DUPLICATION OF NAME, PRESENTATION NAME, OR LINKED ELEMENT
			
			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())));
		}
	};

	protected UpdateSuppressionFromBaseAction updateSuppressionFromBaseAction = new UpdateSuppressionFromBaseAction();

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

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

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

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

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

				});
				// update context bar menu after performing reveal
				revealAction.setEnabled(getSuppression().canReveal(selection));
				suppressAction.setEnabled(getSuppression().canSuppress(
						selection));
				// enable synchronize actions correctly
				autoSynchronize.setEnabled(autoSynchronize
						.updateSelection(new StructuredSelection(selection
								.toArray())));
				manualSynchronizeAction.setEnabled(manualSynchronizeAction
						.updateSelection(new StructuredSelection(selection
								.toArray())));
			}
		}
	};

	private IAction revealTaskAction = new Action(
			AuthoringUIResources.ProcessEditor_Action_Reveal_Task) {

		public void run() {
			final List taskDescriptors = ProcessUtil
					.getTaskDescriptors(selection);
			if (ProcessEditor.canReveal(taskDescriptors, getAdapterFactory(),
					getSuppression())) {

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

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

				});

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

	protected IBSItemProvider bsItemProvider = null;

	protected Object selectedElement = null;

	protected Activity selectedActivity = null;

	protected BreakdownElement selectedBreakdownElement = null;

	protected List selection;

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

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

			IStructuredContentProvider contentProvider = new ArrayContentProvider();

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

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

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

			Object[] diagramsToReveal = dlg.getResult();

			if (diagramsToReveal == null) {
				return;
			}

			boolean changed = true;

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

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

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

				// save the editor
				//
				saveActiveEditor();
			}
		}
	};

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

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

			IStructuredContentProvider contentProvider = new ArrayContentProvider();

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

			Collection diagrams = ((ProcessEditor) getActiveEditor())
					.getDiagramEditorHelper().getDiagrams(selectedActivity);
			ArrayList<org.eclipse.gmf.runtime.notation.Diagram> publishDiagrams = new ArrayList<org.eclipse.gmf.runtime.notation.Diagram>();

			for (Iterator iter = diagrams.iterator(); iter.hasNext();) {
				org.eclipse.gmf.runtime.notation.Diagram diagram = (org.eclipse.gmf.runtime.notation.Diagram) iter
						.next();
				switch (DiagramEditorHelper.getDiagramType(diagram)) {
				case IDiagramManager.ACTIVITY_DIAGRAM:
					if (DiagramOptions.isPublishAD(selectedActivity)) {
						publishDiagrams.add(diagram);
					}
					break;
				case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
					if (DiagramOptions.isPublishADD(selectedActivity)) {
						publishDiagrams.add(diagram);
					}
					break;
				case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
					if (DiagramOptions.isPublishWPDD(selectedActivity)) {
						publishDiagrams.add(diagram);
					}
					break;
				}
			}

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

			Object[] diagramsToReveal = dlg.getResult();

			if (diagramsToReveal == null) {
				return;
			}

			boolean changed = true;

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

			if (changed) {
				for (Iterator iter = diagrams.iterator(); iter.hasNext();) {
					org.eclipse.gmf.runtime.notation.Diagram diagram = (org.eclipse.gmf.runtime.notation.Diagram) iter
							.next();
					switch (DiagramEditorHelper.getDiagramType(diagram)) {
					case IDiagramManager.ACTIVITY_DIAGRAM:
						DiagramOptions.setPublishAD(selectedActivity, false);
						break;
					case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
						DiagramOptions.setPublishADD(selectedActivity, false);
						break;
					case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
						DiagramOptions.setPublishWPDD(selectedActivity, false);
						break;
					}
				}

				for (int i = 0; i < diagramsToReveal.length; i++) {
					org.eclipse.gmf.runtime.notation.Diagram diagram = (org.eclipse.gmf.runtime.notation.Diagram) diagramsToReveal[i];
					switch (DiagramEditorHelper.getDiagramType(diagram)) {
					case IDiagramManager.ACTIVITY_DIAGRAM:
						DiagramOptions.setPublishAD(selectedActivity, true);
						break;
					case IDiagramManager.ACTIVITY_DETAIL_DIAGRAM:
						DiagramOptions.setPublishADD(selectedActivity, true);
						break;
					case IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM:
						DiagramOptions.setPublishWPDD(selectedActivity, true);
						break;
					}
				}
				// save the editor
				//
				saveActiveEditor();
			}
		}
	};

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

	private IAction diagramPublishNone = new Action(
			AuthoringUIResources.ProcessEditor_Action_SuppressAll) {
		public void run() {
			publishDiagramsForProcess(false);
		}
	};

	private IAction diagramsPublishAll = new Action(
			AuthoringUIResources.ProcessEditor_Action_RevealAll) {
		public void run() {
			publishDiagramsForProcess(true);
		}
	};

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

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

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

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

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

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

			});

		}
	};

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

			if (selection == null || selection.isEmpty()) {
				return;
			} else {
				for (Iterator itor = selection.iterator(); itor.hasNext();) {
					Object o = itor.next();

					if (o instanceof Activity) {
						Activity act = (Activity) o;

						// Process proc =
						// TngUtil.getOwningProcess(selectedBreakdownElement);
						// if (DependencyChecker.hasCyclicDependency(act, proc))
						// {
						// Object[] args = { selectedActivity.getName(),
						// act.getName() };
						// String message = AuthoringUIResources
						// .bind(
						// AuthoringUIResources.apply_pattern_error_msg,
						// args);
						//
						// String title =
						// AuthoringUIResources.apply_pattern_error_title;
						// AuthoringUIPlugin.getDefault().getMsgDialog()
						// .displayError(title, message, ""); //$NON-NLS-1$
						// itor.remove();
						// }
						// else if (ProcessUtil.hasContributorOrReplacer(act)) {
						// Object[] args = { selectedActivity.getName(),
						// act.getName() };
						// String message = AuthoringUIResources
						// .bind(
						// AuthoringUIResources.activity_variability_error_msg,
						// args);
						//
						// String title =
						// AuthoringUIResources.activity_variability_error_title;
						// AuthoringUIPlugin.getDefault().getMsgDialog()
						// .displayError(title, message, ""); //$NON-NLS-1$
						//
						// itor.remove();
						// return;
						// }

						IStatus status = DependencyChecker
								.checkCircularDependency(act, selectedActivity);
						if (!status.isOK()) {
							String title = AuthoringUIResources.activity_variability_error_title;
							AuthoringUIPlugin.getDefault().getMsgDialog()
									.displayError(title, status.getMessage());
							itor.remove();
						}
					}
					if (selection.isEmpty()) {
						return;
					}
				}
			}

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

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

			if (selection == null || selection.isEmpty()) {
				return;
			} else {
				for (Iterator itor = selection.iterator(); itor.hasNext();) {
					Object o = itor.next();

					if (o instanceof Activity) {
						Activity act = (Activity) o;

						// Process proc =
						// TngUtil.getOwningProcess(selectedBreakdownElement);
						// if (DependencyChecker.hasCyclicDependency(act, proc))
						// {
						// Object[] args = { selectedActivity.getName(),
						// act.getName() };
						// String message = AuthoringUIResources
						// .bind(
						// AuthoringUIResources.apply_pattern_error_msg,
						// args);
						//
						// String title =
						// AuthoringUIResources.apply_pattern_error_title;
						// AuthoringUIPlugin.getDefault().getMsgDialog()
						// .displayError(title, message, ""); //$NON-NLS-1$
						// itor.remove();
						// }
						// else if (ProcessUtil.hasContributorOrReplacer(act)) {
						// Object[] args = { selectedActivity.getName(),
						// act.getName() };
						// String message = AuthoringUIResources
						// .bind(
						// AuthoringUIResources.activity_variability_error_msg,
						// args);
						//
						// String title =
						// AuthoringUIResources.activity_variability_error_title;
						// AuthoringUIPlugin.getDefault().getMsgDialog()
						// .displayError(title, message, ""); //$NON-NLS-1$
						//
						// itor.remove();
						// return;
						// }

						/*
						 * IStatus status = DependencyChecker.newCheckAct ?
						 * DependencyChecker.checkCircularDependencyAfterFilterSelection
						 * (act, selectedActivity,
						 * VariabilityType.EXTENDS_LITERAL) :
						 * DependencyChecker.checkCircularDependency(act,
						 * selectedActivity);
						 */
						IStatus status = DependencyChecker.newCheckAct ? DependencyChecker
								.checkCircularForApplyingVariabilityElement(
										selectedActivity, act, true)
								: DependencyChecker.checkCircularDependency(
										act, selectedActivity);
						if (!status.isOK()) {
							String title = AuthoringUIResources.activity_variability_error_title;
							AuthoringUIPlugin.getDefault().getMsgDialog()
									.displayError(title, status);
							itor.remove();
						}
					}
					if (selection.isEmpty()) {
						return;
					}
				}
			}
			ActivityDropCommand cmd = new ActivityDropCommand(selectedActivity,
					selection, null, getAdapterFactory());
			IStatus status = cmd.checkExtend();
			if (!status.isOK()) {
				String title = AuthoringUIResources.activity_variability_error_title;
				AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
						title, status.getMessage());
				return;
			}
			cmd.setType(IActionTypeProvider.EXTEND);
			getActionManager().execute(cmd);
		}
	};

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

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

					if (selection == null || selection.isEmpty()) {
						return;
					} else {
						for (Iterator itor = selection.iterator(); itor
								.hasNext();) {
							Object o = itor.next();

							if (o instanceof Activity) {
								Activity act = (Activity) o;

								// Process proc =
								// TngUtil.getOwningProcess(selectedBreakdownElement);
								// if (ProcessUtil.hasCyclicDependency(act,
								// proc)) {
								// Object[] args = { selectedActivity.getName(),
								// act.getName() };
								// String message = AuthoringUIResources
								// .bind(
								// AuthoringUIResources.apply_pattern_error_msg,
								// args);
								//
								// String title =
								// AuthoringUIResources.apply_pattern_error_title;
								// AuthoringUIPlugin.getDefault().getMsgDialog()
								// .displayError(title, message, "");
								// //$NON-NLS-1$
								// itor.remove();
								// }

								IStatus status = DependencyChecker
										.checkCircularDependency(act,
												selectedActivity);
								if (!status.isOK()) {
									String title = AuthoringUIResources.activity_variability_error_title;
									AuthoringUIPlugin.getDefault()
											.getMsgDialog().displayError(title,
													status.getMessage());
									itor.remove();
								}
							}
							if (selection.isEmpty()) {
								return;
							}
						}
					}

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

				}
			});
		}
	};

	protected Object selectedObject;

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

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

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

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

	protected ProcessAutoSynchronizeAction autoSynchronize = new ProcessAutoSynchronizeAction() {
		private void superRun() {
			super.run();
		}

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

				public void run(IProgressMonitor monitor)
						throws InvocationTargetException, InterruptedException {
					if (!AuthoringUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayConfirmation(
									AuthoringUIResources.ProcessEditor_defaultSynchronization,
									AuthoringUIResources.ProcessEditor_confirmAutoSynch)) {
						return;
					}
					// ((SynchronizeCommand)command).setUIContext(getActiveEditor().getSite().getShell());
					superRun();

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

		}
	};

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

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

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

				});
			}
		}

	};

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

			dialog.open();
		}
	};

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

	private boolean oldLocked;

	private IndentAction indentAction = new IndentAction() {
		public boolean updateSelection(IStructuredSelection selection) {
			if (!isEditingAllowed()) {
				return false;
			}
			return super.updateSelection(selection);
		}
	};

	private OutdentAction outdentAction = new OutdentAction() {
		@Override
		public boolean updateSelection(IStructuredSelection selection) {
			if (!isEditingAllowed()) {
				return false;
			}
			return super.updateSelection(selection);
		}
	};

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

		// don't show validate action
		//
		validateAction = null;

		// set disabled image descriptors
		showInLibraryView.setDisabledImageDescriptor(AuthoringUIPlugin
				.getDefault().getImageDescriptor(
						"full/etool16/show_linked_element_disabled.gif")); //$NON-NLS-1$			
	}

	public ProcessEditorActionBarContributor(String name) {
        super(name);
    }

	protected void openDiagram(int diagramType) {
		try {
			DiagramEditorInput input = new DiagramEditorInput(
					selectedObject, getSuppression(), diagramType);
			DiagramEditorUtil.openDiagramEditor(getPage(), input,
					DiagramEditorHelper.getDiagramPreferencesHint(diagramType),
					new NullProgressMonitor());
		} catch (RuntimeException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
	}

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

	protected void registerActions() {
		registerAction(autoSynchronize);
		registerAction(manualSynchronizeAction);
		registerAction(updateSuppressionFromBaseAction);
		registerAction(indentAction);
		registerAction(outdentAction);
		registerAction(moveDownAction);
		registerAction(moveUpAction);
	}

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

		boolean editingAllowed = isEditingAllowed();
		for (IAction action : registeredActions) {
			if (action instanceof CommandActionHandler) {
				action.setEnabled(((CommandActionHandler) action)
						.updateSelection(structuredSelection));
			}
			else if (action instanceof IModifyingAction) {
				action.setEnabled(editingAllowed);
			}
		}
	}

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

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

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

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

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

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

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

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

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

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

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

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

		});
	}

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

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

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

			public void run() {

				Iterator iterator = new AbstractTreeIterator(getProcess()) {

					/**
					 * Comment for <code>serialVersionUID</code>
					 */
					private static final long serialVersionUID = -618949014476371114L;

					protected Iterator getChildren(Object object) {
						Activity act = (Activity) object;
						ArrayList children = new ArrayList();
						for (Iterator iterator = act.getBreakdownElements()
								.iterator(); iterator.hasNext();) {
							Object element = iterator.next();
							if (element instanceof Activity) {
								children.add(element);
							}
						}
						return children.iterator();
					}

				};
				try {
					while (iterator.hasNext()) {
						Activity activity = (Activity) iterator.next();
						DiagramOptions.setPublishAD(activity, publish);
						DiagramOptions.setPublishADD(activity, publish);
						DiagramOptions.setPublishWPDD(activity, publish);
					}
				} catch (Exception e) {
					AuthoringUIPlugin.getDefault().getLogger().logError(e);
				}
				doSaveActiveEditor();
			}
		});
	}

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

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

			public void run() {
				doSaveActiveEditor();
			}

		});
	}

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

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

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

					});
				}
			}

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

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

			@Override
			public Command createCommand(Collection selection) {
				boolean unexecutable = false;
				for (Iterator iter = selection.iterator(); iter.hasNext();) {
					Object element = (Object) iter.next();
					if (element instanceof Activity) {
						unexecutable = true;
					}
				}
				if (unexecutable) {
					return UnexecutableCommand.INSTANCE;
				} else {
					return super.createCommand(selection);
				}
			}
		};
	}

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

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

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

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

		};
	}

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

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

		showInLibraryView
				.setToolTipText(AuthoringUIResources.ProcessEditor_Action_ShowLinkedElementinLibraryView);
		toolBarManager.add(moveUpAction);
		toolBarManager.add(moveDownAction);
		toolBarManager.add(indentAction);
		toolBarManager.add(outdentAction);
		toolBarManager.add(showInLibraryView);
	}

	protected boolean isEditingAllowed() {
		IFormPage activePage = ((ProcessEditor) activeEditor)
				.getActivePageInstance();
		return !(activePage instanceof ProcessBreakdownStructureFormPage && ((ProcessBreakdownStructureFormPage) activePage)
				.basicIsReadOnly());
	}

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

		ISelectionProvider selectionProvider = (ISelectionProvider) activeEditor;

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

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

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

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

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

		if (revealAction.isEnabled()) {
			menuManager.insertBefore("fixed-additions", revealAction); //$NON-NLS-1$
		}

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

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

		// Indent/outdent
		//
		menuManager.insertBefore("fixed-additions", indentAction); //$NON-NLS-1$				
		menuManager.insertBefore("fixed-additions", outdentAction); //$NON-NLS-1$

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

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

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

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

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

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

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

			MenuManager newDiagramSubMenu = new MenuManager(
					AuthoringUIResources.ProcessEditor_Action_Diagrams); 
			if (selectedActivity != null) {
				newDiagramSubMenu.add(newActivityDiagramEditor);
				newDiagramSubMenu.add(newActivityDetailDiagramEditor);
				newDiagramSubMenu.add(newWPDiagramEditor);
				newDiagramSubMenu.add(newSuppressDiagramAction);
				newDiagramSubMenu.add(newAssignUserDiagram);

			}

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

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

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

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

	protected 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
	 */
	protected void setActionState() {
		if (locked) {
			// disable modifying actions
			pasteAction.setEnabled(false);
			cutAction.setEnabled(false);
			deleteAction.setEnabled(false);
			
			for(IAction action : registeredActions) {
				if(action instanceof IModifyingAction) {
					action.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));
			
			for(IAction action : registeredActions) {
				if(action instanceof IModifyingAction) {
					action.setEnabled(action instanceof CommandActionHandler ? 
							((CommandActionHandler)action).updateSelection(selection) : true);
				}
			}
		}

		boolean enabled = !locked;

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

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

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

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

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

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

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

			updateActions();

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

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

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

		if (!locked && selection != null && !selection.isEmpty()) {
			if (selection.size() == 1) {				
				Object o = selection.get(0);
				AdapterFactory adapterFactory = getAdapterFactory();
				if(ProcessUtil.isRolledUpDescriptor(o, adapterFactory)) {
					revealAction.setEnabled(false);
					suppressAction.setEnabled(false);
				}
				else {
					if (getSuppression().canReveal(selection)) {
						revealAction.setEnabled(true);
						suppressAction.setEnabled(false);
					} else if (getSuppression().canSuppress(selection)) {
						suppressAction.setEnabled(true);
						revealAction.setEnabled(false);
					} else {
						revealAction.setEnabled(false);
						suppressAction.setEnabled(false);
					}
				}
			} else {
				revealAction.setEnabled(getSuppression().canReveal(selection));
				suppressAction.setEnabled(getSuppression().canSuppress(
						selection));
			}

			// Action Enable/Disable for Suppress Task/Reveal Task context menu
			boolean show = true;
			for (int i = 0; i < selection.size(); i++) {
				if (getAdapterFactory() == TngAdapterFactory.INSTANCE
						.getWBS_ComposedAdapterFactory()) {

					if (!(selection.get(i) instanceof Activity || selection
							.get(i) instanceof ActivityWrapperItemProvider)) {
						show = false;
						break;
					}
				} else
					show = false;
			}
			if (show) {
				List taskDescriptors = ProcessUtil
						.getTaskDescriptors(selection);
				suppressTaskAction.setEnabled(getSuppression().canSuppress(
						taskDescriptors));
				revealTaskAction.setEnabled(getSuppression().canReveal(
						taskDescriptors));
			} else {
				suppressTaskAction.setEnabled(false);
				revealTaskAction.setEnabled(false);
			}

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

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

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

			// TODO - need to get IFormPage and compare on that rather than
			// integer page id. These id will change if we reposition pages.
			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 if (page == 4) {
				actionBars.clearGlobalActionHandlers();
			}
			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();
		}
	}
	
	private void superDoRefresh() {
		super.doRefresh();
	}

	protected void doRefresh() {
		if (activeEditorPart instanceof IViewerProvider) {
			Display display = activeEditorPart.getEditorSite().getShell().getDisplay();
			BusyIndicator.showWhile(display, new Runnable() {

				public void run() {
					// update IDs
					//
					AdapterFactory adapterFactory = getAdapterFactory();
					if (adapterFactory == TngAdapterFactory.INSTANCE
							.getWBS_ComposedAdapterFactory()
							|| adapterFactory == TngAdapterFactory.INSTANCE
									.getProcessComposedAdapterFactory()) {
						Process proc = getProcess();
						ProcessUtil.updateIDs(adapterFactory, proc);
//						long time = System.currentTimeMillis();
						ProcessUtil.refreshPredeccessorLists(adapterFactory, proc);
//						System.out.println("refreshPredeccessorLists() took: " + (System.currentTimeMillis() - time));
					}

					superDoRefresh();
				}
				
			});
		}

	}

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

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

	/*
	 * Set Action state for Open Diagram Actions in Context Menu on
	 * selection of Activity. Checking condition to handle if activity suppressed, if activity don't have
	 * any taskdescriptor and primary performer, if base activity don't have diagram. 
	 */
	private void setDiagramsContextMenuState() {

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

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

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

		if (selectedObject != null) {

			if (getSuppression().isSuppressed(selectedObject)) {
				newActivityDetailDiagramEditor.setEnabled(false);
				newActivityDiagramEditor.setEnabled(false);
				newWPDiagramEditor.setEnabled(false);
				return;
			}

			Object unwrapped = TngUtil.unwrap(selectedObject);
			if(!(unwrapped instanceof Activity)) {
				return;
			}
			Activity activity = (Activity) unwrapped;
			List list = new ArrayList();
			
			//TODO: check for existing diagrams in immediate base instead of root base
			
			while (!activity.getVariabilityType().equals(
					VariabilityType.NA)) {

				VariabilityElement ve = activity.getVariabilityBasedOnElement();
				list.addAll(activity.getBreakdownElements());

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

			org.eclipse.gmf.runtime.notation.Diagram diagram = ((ProcessEditor) getActiveEditor())
					.getDiagramEditorHelper().getDiagram(activity,
							IDiagramManager.ACTIVITY_DIAGRAM);
			if (diagram == null
					&& selectedObject instanceof ActivityWrapperItemProvider) {
				newActivityDiagramEditor.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 = ((ProcessEditor) getActiveEditor())
					.getDiagramEditorHelper().getDiagram(activity,
							IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM);
			if (diagram == null
					&& selectedObject instanceof ActivityWrapperItemProvider) {
				newWPDiagramEditor.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 = ((ProcessEditor) getActiveEditor())
					.getDiagramEditorHelper().getDiagram(activity,
							IDiagramManager.ACTIVITY_DETAIL_DIAGRAM);

			if (diagram == null
					&& selectedObject instanceof ActivityWrapperItemProvider) {
				newActivityDetailDiagramEditor.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)) {
									newActivityDetailDiagramEditor
											.setEnabled(true);
									break;
								}
							}
						}
					}
				}
			}
		}
	}
}
