//------------------------------------------------------------------------------
// 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.views;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EventObject;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.command.BasicCommandStack;
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.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
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.dnd.LocalTransfer;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIHelpContexts;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.UIActionDispatcher;
import org.eclipse.epf.authoring.ui.actions.ILibraryActionBarContributor;
import org.eclipse.epf.authoring.ui.actions.LayoutActionGroup;
import org.eclipse.epf.authoring.ui.actions.LibraryActionBarContributor;
import org.eclipse.epf.authoring.ui.actions.LibraryViewCopyAction;
import org.eclipse.epf.authoring.ui.actions.LibraryViewCutAction;
import org.eclipse.epf.authoring.ui.actions.LibraryViewDeleteAction;
import org.eclipse.epf.authoring.ui.actions.LibraryViewPasteAction;
import org.eclipse.epf.authoring.ui.actions.NewPluginAction;
import org.eclipse.epf.authoring.ui.dialogs.MoveDialog;
import org.eclipse.epf.authoring.ui.dialogs.VariabilitySelection;
import org.eclipse.epf.authoring.ui.dnd.LibraryViewerDragAdapter;
import org.eclipse.epf.authoring.ui.editors.AbstractDiagramEditor;
import org.eclipse.epf.authoring.ui.editors.BreakdownElementEditorInput;
import org.eclipse.epf.authoring.ui.editors.EditorChooser;
import org.eclipse.epf.authoring.ui.editors.IEditorKeeper;
import org.eclipse.epf.authoring.ui.editors.MethodElementEditor;
import org.eclipse.epf.authoring.ui.editors.MethodElementEditorInput;
import org.eclipse.epf.authoring.ui.editors.ProcessEditor;
import org.eclipse.epf.authoring.ui.preferences.ApplicationPreferenceConstants;
import org.eclipse.epf.authoring.ui.providers.MethodElementLabelDecorator;
import org.eclipse.epf.authoring.ui.util.LibraryValidationMarkerHelper;
import org.eclipse.epf.common.serviceability.MsgBox;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceException;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.FeatureValueWrapperItemProvider;
import org.eclipse.epf.library.edit.PluginUIPackageContext;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.category.CustomCategoryItemProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.IValidator;
import org.eclipse.epf.library.edit.validation.IValidatorFactory;
import org.eclipse.epf.library.persistence.ILibraryResource;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.persistence.PersistenceService;
import org.eclipse.epf.library.project.MethodLibraryProjectNature;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.ui.LibraryUIManager;
import org.eclipse.epf.library.ui.actions.LibraryLockingOperationRunner;
import org.eclipse.epf.library.ui.dialogs.SwitchConfigDialog;
import org.eclipse.epf.library.ui.preferences.LibraryUIPreferences;
import org.eclipse.epf.library.util.ImportExportUtil;
import org.eclipse.epf.library.xmi.XMILibraryUtil;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.persistence.MultiFileResourceSetImpl;
import org.eclipse.epf.persistence.refresh.IRefreshEvent;
import org.eclipse.epf.persistence.refresh.IRefreshHandler;
import org.eclipse.epf.persistence.refresh.IRefreshListener;
import org.eclipse.epf.persistence.refresh.RefreshJob;
import org.eclipse.epf.persistence.util.LibrarySchedulingRule;
import org.eclipse.epf.persistence.util.PersistenceUtil;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.services.Services;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.NamedElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessElement;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.TeamProfile;
import org.eclipse.epf.uma.VariabilityElement;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.epf.uma.edit.domain.TraceableAdapterFactoryEditingDomain;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.ContentDescriptionFactory;
import org.eclipse.epf.uma.util.MessageException;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.HTMLTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.views.markers.internal.MarkerAdapter;
import org.eclipse.ui.views.navigator.ResourceNavigator;

/**
 * The Library view.
 * <p>
 * Displays the physical representation of a Method Library.
 * 
 * @author Phong Nguyen Le
 * @author Shilpa Toraskar
 * @author Kelvin Low
 * @since 1.0
 */
public class LibraryView extends AbstractBaseView implements IRefreshHandler,
		IShowInTarget {

	/**
	 * The view ID.
	 */
	public static final String VIEW_ID = LibraryView.class.getName();

	private static boolean DEBUG = AuthoringUIPlugin.getDefault().isDebugging();

	protected TreeViewer treeViewer;

	protected IDoubleClickListener doubleClickListener = null;

	private ISelection selection;
	
	private LayoutActionGroup fLayoutActionSet;

	// Listen to process editor activation and prompt the user to load the
	// the process's default Configuration into the Configuration view.
	private IPartListener editorPartListener = new IPartListener() {

		public void partOpened(IWorkbenchPart part) {
		}

		public void partDeactivated(IWorkbenchPart part) {
		}

		public void partClosed(IWorkbenchPart part) {
		}

		public void partBroughtToTop(IWorkbenchPart part) {
		}

		public void partActivated(IWorkbenchPart part) {
			if (part instanceof IEditorPart) {
				Object obj = null;
				if (part instanceof AbstractDiagramEditor) {
					BreakdownElementEditorInput input = (BreakdownElementEditorInput) ((IEditorPart) part)
							.getEditorInput();
					if (input.getSuppression().getProcess() != null) {
						obj = input.getSuppression().getProcess().eContainer();
					}
				} else {
					obj = EditorChooser.getInstance().getSelectedEditorInput();
				}
				if (obj != null && obj instanceof ProcessComponent) {
					SwitchConfigDialog dialog = new SwitchConfigDialog(Display
							.getCurrent().getActiveShell(),
							((ProcessComponent) obj).getProcess()
									.getDefaultContext());
					dialog.execute();
				}
			}
		}

	};

	private long lastRefreshTimeStamp;

	private IResourceChangeListener markerListener = new IResourceChangeListener() {
		public void resourceChanged(IResourceChangeEvent event) {
			if (LibraryService.getInstance().getCurrentLibraryManager() == null
					|| LibraryService.getInstance().getCurrentLibraryManager()
							.getEditingDomain() == null
					|| LibraryService.getInstance().getCurrentLibraryManager()
							.getEditingDomain().getResourceSet() == null)
				return;
			IResourceDelta delta = event.getDelta();
			if (delta == null)
				return;
			try {
				class ResourceDeltaVisitor implements IResourceDeltaVisitor {
					public boolean visit(IResourceDelta delta)
							throws CoreException {
						if ((delta.getFlags() & IResourceDelta.MARKERS) == IResourceDelta.MARKERS) {
							switch (delta.getKind()) {
							case IResourceDelta.ADDED:
							case IResourceDelta.CHANGED:
								// show Problems View
								ILibraryResourceSet resourceSet = ((ILibraryResourceSet) LibraryService
										.getInstance()
										.getCurrentLibraryManager()
										.getEditingDomain().getResourceSet());
								if (resourceSet.hasUnresolvedProxy()) {
									SafeUpdateController
											.asyncExec(new Runnable() {
												public void run() {
													try {
														PlatformUI
																.getWorkbench()
																.getActiveWorkbenchWindow()
																.getActivePage()
																.showView(
																		"org.eclipse.ui.views.ProblemView", null, IWorkbenchPage.VIEW_VISIBLE); //$NON-NLS-1$
													} catch (Exception e) {
														// couldn't open the
														// problem view, too
														// bad..
													}
												}
											});
								}
								return false;
							}
						}
						return true;
					}
				}
				;

				ResourceDeltaVisitor visitor = new ResourceDeltaVisitor();
				delta.accept(visitor);

			} catch (CoreException e) {
				CommonPlugin.INSTANCE.log(e);
			}

		}

	};

	private IRefreshListener refreshListener = new IRefreshListener() {

		public void notifyRefreshed(IRefreshEvent event) {
			if (event.getRefreshedObjects() != null
					&& !event.getRefreshedObjects().isEmpty()) {
				Control ctrl = getViewer().getControl();
				if (ctrl == null || ctrl.isDisposed())
					return;

				if (ctrl.getDisplay().getThread() == Thread.currentThread()) {
					doRefresh(getSite().getShell());
				} else {
					ctrl.getDisplay().syncExec(new Runnable() {

						public void run() {
							doRefresh(null);
						}

					});
				}
			}
		}

	};

	/**
	 * Creates a new instance.
	 */
	public LibraryView() {
		// read layout pref
		if (PluginUIPackageContext.FLAT_LAYOUT.equals(ApplicationPreferenceConstants.getLayout())) {
			PluginUIPackageContext.INSTANCE.setLayoutFlat();
		} else if (PluginUIPackageContext.HIERARCHICAL_LAYOUT.equals(ApplicationPreferenceConstants.getLayout())) {
			PluginUIPackageContext.INSTANCE.setLayoutHierarchical();
		}

	}

	/**
	 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(Composite)
	 */
	public void createPartControl(Composite parent) {
		super.createPartControl(parent);
		
		makeActions();
		
		PlatformUI.getWorkbench().getHelpSystem().setHelp(parent,
				AuthoringUIHelpContexts.LIBRARY_NAVIGATOR_VIEW_CONTEXT);

		RefreshJob.getInstance().setRefreshHandler(this);
	}
	
	private void makeActions() {
		fLayoutActionSet= new LayoutActionGroup(this);
		IActionBars actionBars= getViewSite().getActionBars();
		fLayoutActionSet.fillActionBars(actionBars);
	}

	/**
	 * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
	 */
	public void setFocus() {
		// This is required to make the global edit action work the first time.
		actionBarContributor.setActiveView(this);

		IStructuredSelection selected = (IStructuredSelection) getSelection();
		if (selected.isEmpty())
			actionBarContributor.disableGlobalEditMenu();
		else
			actionBarContributor.enableGlobalEditMenu();

		if (treeViewer != null) {
			treeViewer.getControl().setFocus();
		}
	}

	/**
	 * Returns the underlying tree viewer.
	 */
	public Viewer getViewer() {
		return treeViewer;
	}

	/**
	 * Creates the underlying tree viewer.
	 */
	public void createViewer(Composite parent) {
		treeViewer = new TreeViewer(parent) {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.StructuredViewer#handleLabelProviderChanged(org.eclipse.jface.viewers.LabelProviderChangedEvent)
			 */
			protected void handleLabelProviderChanged(
					LabelProviderChangedEvent event) {
				if (event.getElement() instanceof IResource
						&& event.getSource() instanceof ILabelDecorator) {
					this.refresh();
					return;
				}
				super.handleLabelProviderChanged(event);
			}
		};

		adapterFactory = TngAdapterFactory.INSTANCE
				.getNavigatorView_ComposedAdapterFactory();

		// Create the command stack that will notify this editor as commands are
		// executed.
		BasicCommandStack commandStack = 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) {
				Runnable runnable = new Runnable() {
					public void run() {
						firePropertyChange(IEditorPart.PROP_DIRTY);

						// Try to select the affected objects.
						Command mostRecentCommand = ((CommandStack) event
								.getSource()).getMostRecentCommand();
						if (mostRecentCommand != null) {
							setSelectionToViewer(mostRecentCommand
									.getAffectedObjects());
						}
						if (propertySheetPage != null
								&& propertySheetPage.getControl() != null
								&& !propertySheetPage.getControl().isDisposed()
								&& propertySheetPage.getControl().isVisible()) {
							propertySheetPage.refresh();
						}
					}
				};
				if (Display.getCurrent() != null) {
					Display.getCurrent().asyncExec(runnable);
				} else {
					runnable.run();
				}
			}
		});

		// Create the editing domain with a special command stack.
		ResourceSet resourceSet = PersistenceService.INSTANCE
				.createResourceSet(Services.getDefaultLibraryPersistenceType());

		editingDomain = new TraceableAdapterFactoryEditingDomain(
				adapterFactory, commandStack, resourceSet);

		ILibraryManager manager = (ILibraryManager) LibraryService
				.getInstance().getCurrentLibraryManager();
		if (manager != null) {
			manager.registerEditingDomain(editingDomain);

			manager.addPropertyListener(new IPropertyListener() {
				public void propertyChanged(Object source, int propId) {
					// TODO: Replace hardcoded constant with variable.
					if (propId == 1) {
						firePropertyChange(PROP_DIRTY);
					}
				}
			});
		}

		treeViewer.setContentProvider(new AdapterFactoryContentProvider(
				adapterFactory));

		// treeViewer.setLabelProvider(new
		// AdapterFactoryLabelProvider(adapterFactory));
		treeViewer.setLabelProvider(new DecoratingLabelProvider(
				new AdapterFactoryLabelProvider(adapterFactory),
				new MethodElementLabelDecorator()));

		// Add a double click listener for launching the Method editors.
		doubleClickListener = new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				UIActionDispatcher.getInstance().handleDoubleClickEvent(event);
			}
		};
		treeViewer.addDoubleClickListener(doubleClickListener);

		getSite().getPage().addPartListener(editorPartListener);

		ResourcesPlugin.getWorkspace()
				.addResourceChangeListener(markerListener);

		createContextMenuFor(treeViewer);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.views.AbstractBaseView#setInputForViewer(Object)
	 */
	public void setInputForViewer(Object model) {
		Control ctrl = this.getViewer().getControl();
		if (ctrl.isDisposed()) {
			return;
		}
		if (model == null || model instanceof MethodLibrary) {
			// Prevent memory leak.
			StructuredSelection emptySelection = new StructuredSelection();
			actionDispatcher.setSelection(emptySelection);
			UIActionDispatcher.getInstance().setSelection(emptySelection);

			getViewer().setInput(model);
			updateLastRefreshTimestamp();
		} else {
			AuthoringUIPlugin
					.getDefault()
					.getLogger()
					.logError(
							"Library viewer input is not a MethodLibrary object: " + model); //$NON-NLS-1$
		}
	}

	/**
	 * 
	 */
	private void updateLastRefreshTimestamp() {
		lastRefreshTimeStamp = System.currentTimeMillis();
	}

	/**
	 * Returns this view.
	 */
	public static LibraryView getView() {
		return (LibraryView) ViewHelper.openView(VIEW_ID);
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.views.AbstractBaseView#setSelection(ISelection)
	 */
	public void setSelection(ISelection selection) {
		((LibraryViewActionBarContributor) actionBarContributor)
				.updateSelection(selection);

		super.setSelection(selection);
		this.selection = selection;

		// if only one element is selected, show path to its file in status line
		//
		IStatusLineManager statusLineManager = getViewSite().getActionBars()
				.getStatusLineManager();
		if (statusLineManager != null) {
			String path = ""; //$NON-NLS-1$
			if (selection instanceof IStructuredSelection) {
				IStructuredSelection structuredSelection = (IStructuredSelection) selection;
				if (structuredSelection.size() == 1) {
					Object o = TngUtil.unwrap(structuredSelection
							.getFirstElement());
					if (o instanceof EObject) {
						Resource resource = ((EObject) o).eResource();
						if (resource != null) {
							URI uri = resource.getURI();
							if (uri != null && uri.isFile()) {
								path = uri.toFileString();
								if (o instanceof ContentElement) {
									ContentDescription content = ((ContentElement) o)
											.getPresentation();
									if (content != null) {
										resource = content.eResource();
										if (resource != null) {
											URI contentURI = resource.getURI();
											if (contentURI != null) {
												path = path
														+ ",." + File.separatorChar + contentURI.deresolve(uri).toFileString(); //$NON-NLS-1$
											}
										}
									}
								}
							}
						}
					}
				}
			}
			statusLineManager.setMessage(path);
		}
	}

	/**
	 * @see org.eclipse.epf.library.ILibraryServiceListener#libraryReopened(MethodLibrary)
	 */
	public void libraryReopened(MethodLibrary library) {
		refreshViews();
	}

	/**
	 * The action bar for the library view
	 */
	class LibraryViewActionBarContributor extends LibraryActionBarContributor {

		private IAction newPluginAction = new NewPluginAction(
				AuthoringUIResources.new_plugin);

		private IAction moveAction = new Action(AuthoringUIResources.move) {

			private void doMove() {
				Collection elementsToMove = new ArrayList();
				IStructuredSelection selection = (IStructuredSelection) LibraryView.this.selection;
				for (Iterator iter = selection.iterator(); iter.hasNext();) {
					Object element = iter.next();
					if (element instanceof MethodElement
							|| (element = TngUtil.unwrap(element)) instanceof CustomCategory) {
						// Handle CustomCategory specially.
						EObject container = ((EObject) element).eContainer();
						IStatus status = UserInteractionHelper.checkModify(
								container, getSite().getShell());
						if (container != null && !status.isOK()) {
							AuthoringUIPlugin
									.getDefault()
									.getMsgDialog()
									.displayError(
											AuthoringUIResources.errorDialog_title,
											AuthoringUIResources.errorDialog_moveError,
											status);
							return;
						}
						elementsToMove.add(element);
					}
				}

				// TODO: Prompt the user the save editing changes for
				// elements that will be moved.

				// Remove elements from the move list if their containers are
				// already in the move list.
				for (Iterator iterator = elementsToMove.iterator(); iterator
						.hasNext();) {
					EObject element = (EObject) iterator.next();
					boolean isContained = false;
					check_contained: for (Iterator iter = elementsToMove
							.iterator(); iter.hasNext();) {
						Object e = (Object) iter.next();
						if (UmaUtil.isContainedBy(element, e)) {
							isContained = true;
							break check_contained;
						}
					}
					if (isContained) {
						iterator.remove();
					}
				}

				MoveDialog dlg = new MoveDialog(getSite().getShell(),
						elementsToMove, editingDomain);
				dlg.open();
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.action.Action#run()
			 */
			public void run() {
				LibraryLockingOperationRunner runner = new LibraryLockingOperationRunner();
				runner.setProgressMonitor(getActionBars()
						.getStatusLineManager().getProgressMonitor());
				runner.run(new IRunnableWithProgress() {

					public void run(IProgressMonitor monitor)
							throws InvocationTargetException,
							InterruptedException {
						doMove();
					}

				});
			}
		};

		private IAction renameAction = new Action(
				AuthoringUIResources.renameAction_text) {

			public void run() {
				final NamedElement e = (NamedElement) TngUtil
						.unwrap(((IStructuredSelection) selection)
								.getFirstElement());

				IStatus status = UserInteractionHelper.checkModify(e, getSite()
						.getShell());
				if (!status.isOK()) {
					AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
							AuthoringUIResources.renameDialog_title,
							AuthoringUIResources.renameDialog_renameError,
							status);
					return;
				}

				if (e.eContainer() != null
						&& e.eContainer().eResource() != e.eResource()) {
					status = UserInteractionHelper.checkModify(e.eContainer(),
							getSite().getShell());
					if (!status.isOK()) {
						AuthoringUIPlugin
								.getDefault()
								.getMsgDialog()
								.displayError(
										AuthoringUIResources.renameDialog_title,
										AuthoringUIResources.renameDialog_renameError,
										status);
						return;
					}
				}

				final IValidator validator = IValidatorFactory.INSTANCE
						.createNameValidator(e, adapterFactory);
				IInputValidator inputValidator = new IInputValidator() {
					public String isValid(String newText) {
						if (validator != null) {
							return UserInteractionHelper
									.getSimpleErrorMessage(validator
											.isValid(newText));
						}
						return null;
					}
				};

				boolean getInput = true;
				InputDialog inputDlg = new InputDialog(Display.getCurrent()
						.getActiveShell(), AuthoringUIResources.rename_text,
						AuthoringUIResources.newname_text, e.getName(),
						inputValidator);
				while (getInput) {
					getInput = false;
					if (inputDlg.open() == Window.OK) {
						final String newName = inputDlg.getValue().trim();
						if (!newName.equals(e.getName())) {
							if (e instanceof MethodConfiguration) {
								String[] configNames = LibraryServiceUtil
										.getMethodConfigurationNames(LibraryService
												.getInstance()
												.getCurrentMethodLibrary());
								for (int i = 0; i < configNames.length; i++) {
									if (newName.equals(configNames[i])) {
										AuthoringUIPlugin
												.getDefault()
												.getMsgDialog()
												.displayError(
														AuthoringUIResources.renameDialog_title,
														AuthoringUIResources
																.bind(
																		AuthoringUIResources.duplicateElementNameError_msg,
																		newName));
										getInput = true;
										break;
									}
								}
							}
							if (getInput == true) {
								inputDlg = new InputDialog(Display.getCurrent()
										.getActiveShell(),
										AuthoringUIResources.rename_text,
										AuthoringUIResources.newname_text, e
												.getName(), inputValidator);
								continue;
							}
							doRename(e, newName);
						}
					}
				}
			}
		};

		private IAction replaceAction = new Action(
				AuthoringUIResources.ElementsView_replaceAction_text) {

			public void run() {
				if (!getPage().closeAllEditors(true)) {
					return;
				}

				final ProcessComponent procComp = (ProcessComponent) ((IStructuredSelection) selection)
						.getFirstElement();
				Process proc = procComp.getProcess();
				final String typeStr;
				if (proc instanceof CapabilityPattern) {
					typeStr = AuthoringUIResources.ElementsView_20;
				} else if (proc instanceof DeliveryProcess) {
					typeStr = AuthoringUIResources.ElementsView_21;
				} else {
					typeStr = AuthoringUIResources.ElementsView_22;
				}
				DirectoryDialog dirDlg = new DirectoryDialog(getSite()
						.getShell());
				dirDlg.setText(AuthoringUIResources.ElementsView_replace_text);
				dirDlg
						.setMessage(MessageFormat
								.format(
										AuthoringUIResources.ElementsView_migration_dir_dlg_description_text,
										new Object[] { typeStr }));
				final String dir = dirDlg.open();
				if (dir == null) {
					return;
				}

				boolean ret = UserInteractionHelper
						.runWithProgress(
								new IRunnableWithProgress() {

									public void run(IProgressMonitor monitor)
											throws InvocationTargetException,
											InterruptedException {
										try {
											ImportExportUtil.replace(procComp,
													dir);
										} catch (Exception e) {
											throw new WrappedException(e);
										}
									}
								},
								MessageFormat
										.format(
												AuthoringUIResources.ElementsView_replaceingwithformat_text,
												new Object[] { typeStr }));

				if (ret) {
					// Reopen the library.
					LibraryUIManager.getInstance().openLibrary(
							LibraryService.getInstance()
									.getCurrentMethodLibraryPath());
				}
			}
		};

		private IAction openVariabilityDialogAction = new Action(
				AuthoringUIResources.ElementsView_openVariabilityDialogAction_text) {
			public void run() {
				Object obj = TngUtil.unwrap(((IStructuredSelection) selection)
						.getFirstElement());
				if (obj instanceof VariabilityElement) {
					VariabilityElement element = (VariabilityElement) obj;
					VariabilitySelection variabilitySelection = new VariabilitySelection();
					Object selectedObject = variabilitySelection
							.getSelectedVariability(element);
					if (selectedObject != null) {
						EditorChooser.getInstance().openEditor(selectedObject);
					}
				}
			}
		};

		private boolean locked;

		private boolean canRename;

		private boolean canMove;

		private IAction showInResourceNavigatorAction = new Action(
				AuthoringUIResources.showInResourceNavigatorAction_label) {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.action.Action#run()
			 */
			public void run() {
				ResourceNavigator navigator;
				try {
					navigator = (ResourceNavigator) getPage().showView(
							"org.eclipse.ui.views.ResourceNavigator"); //$NON-NLS-1$
					Object obj = TngUtil
							.unwrap(((IStructuredSelection) selection)
									.getFirstElement());
					IResource wsRes = PersistenceUtil.getWorkspaceResource(obj);
					if (wsRes != null) {
						navigator.getViewer().setSelection(
								new StructuredSelection(wsRes), true);
					}
				} catch (PartInitException e) {
					AuthoringUIPlugin.getDefault().getLogger().logError(e);
				}
			}
		};

		/**
		 * Creates a new instance.
		 */
		public LibraryViewActionBarContributor(EditingDomain editingDomain) {
			super(editingDomain);
		}

		/**
		 * @see org.eclipse.epf.authoring.ui.actions.LibraryActionBarContributor#createDeleteAction()
		 */
		protected DeleteAction createDeleteAction() {
			LibraryViewDeleteAction action = new LibraryViewDeleteAction() {
				/**
				 * @see org.eclipse.epf.authoring.ui.actions.ElementsViewPasteAction#updateSelection(IStructuredSelection)
				 */
				public boolean updateSelection(IStructuredSelection selection) {
					if (locked) {
						return false;
					}
					return super.updateSelection(selection);
				}

				public void run() {
					String title = AuthoringUIResources.actions_LibraryActionBarContributor_deleteErrorTitle;
					try {
						super.run();
					} catch (MessageException e) {
						AuthoringUIPlugin.getDefault().getMsgDialog()
								.displayError(title, e.getMessage());
					} catch (Exception e) {
						String details = TngUtil.toStackTraceString(e);
						String message = AuthoringUIResources.actions_LibraryActionBarContributor_deleteErrorMessage;
						String reason = AuthoringUIResources.actions_LibraryActionBarContributor_deleteErrorReason;
						AuthoringUIPlugin.getDefault().getMsgDialog()
								.displayError(title, message, reason, details,
										e);
					}
				}

				protected void deleteFailed() {
					AuthoringUIPlugin.getDefault().getMsgDialog().displayInfo(
							AuthoringUIResources.dlgTitle_reloadLibrary,
							AuthoringUIResources.msg_reloadLibrary);

					// Library need to be reloaded.
					String libDir = LibraryService.getInstance()
							.getCurrentMethodLibraryPath();
					LibraryUIManager.getInstance().openLibrary(libDir);

					// User tried to select the old selection.
					if (activeViewPart instanceof IViewerProvider) {
						final ArrayList elements = new ArrayList();
						for (Iterator iter = selection.iterator(); iter
								.hasNext();) {
							Object e = iter.next();
							if (e instanceof MethodElement) {
								String guid = ((MethodElement) e).getGuid();
								ILibraryManager manager = LibraryService
										.getInstance()
										.getCurrentLibraryManager();
								if (manager != null) {
									MethodElement element = manager
											.getMethodElement(guid);
									if (element != null) {
										elements.add(element);
									}
								}
							}
						}
						if (!elements.isEmpty()) {
							Viewer viewer = ((IViewerProvider) activeViewPart)
									.getViewer();
							viewer.setSelection(new StructuredSelection(
									elements), true);
						}
					}
				}
			};
			action.setProgressMonitor(getActionBars().getStatusLineManager()
					.getProgressMonitor());
			return action;
		}

		/**
		 * @see org.eclipse.epf.authoring.ui.actions.LibraryActionBarContributor#createCutAction()
		 */
		protected CutAction createCutAction() {
			return new LibraryViewCutAction() {
				/**
				 * @see org.eclipse.epf.authoring.ui.actions.ElementsViewPasteAction#updateSelection(IStructuredSelection)
				 */
				public boolean updateSelection(IStructuredSelection selection) {
					if (locked) {
						return false;
					}
					return super.updateSelection(selection);
				}
			};
		}

		/**
		 * @see org.eclipse.epf.authoring.ui.actions.LibraryActionBarContributor#createCopyAction()
		 */
		protected CopyAction createCopyAction() {
			return new LibraryViewCopyAction();
		}

		/**
		 * @see org.eclipse.epf.authoring.ui.actions.LibraryActionBarContributor#createPasteAction()
		 */
		protected PasteAction createPasteAction() {
			LibraryViewPasteAction action = new LibraryViewPasteAction() {
				/**
				 * @see org.eclipse.epf.authoring.ui.actions.ElementsViewPasteAction#updateSelection(IStructuredSelection)
				 */
				public boolean updateSelection(IStructuredSelection selection) {
					if (locked) {
						return false;
					}
					return super.updateSelection(selection);
				}
			};
			action.setProgressMonitor(getActionBars().getStatusLineManager()
					.getProgressMonitor());
			return action;
		}

		private void checkLocked() {
			if (selection instanceof IStructuredSelection) {
				boolean wasLocked = locked;
				locked = ViewHelper.isLocked((IStructuredSelection) selection);
				if (wasLocked != locked) {
					deleteAction.setEnabled(deleteAction
							.updateSelection((IStructuredSelection) selection));
					cutAction.setEnabled(cutAction
							.updateSelection((IStructuredSelection) selection));
					pasteAction.setEnabled(pasteAction
							.updateSelection((IStructuredSelection) selection));
					boolean enabled = !locked;
					renameAction.setEnabled(enabled);
					moveAction.setEnabled(enabled);
				}
			}
		}

		void updateSelection(ISelection selection) {
			IStructuredSelection sel = (IStructuredSelection) selection;

			locked = ViewHelper.isLocked(sel);

			boolean enabled = !locked;
			renameAction.setEnabled(enabled);
			moveAction.setEnabled(enabled);

			canRename = canRename(sel);
			canMove = canMove(sel);

			if (!locked && sel.size() == 1
					&& sel.getFirstElement() instanceof ProcessComponent) {
				replaceAction.setEnabled(true);
			} else {
				replaceAction.setEnabled(false);
			}

			if (sel.size() == 1) {
				Object obj = TngUtil.unwrap(((IStructuredSelection) selection)
						.getFirstElement());
				openVariabilityDialogAction
						.setEnabled(obj instanceof VariabilityElement
								&& !TngUtil.isPredefined((MethodElement) obj));
				showInResourceNavigatorAction
						.setEnabled(obj instanceof MethodElement);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.epf.authoring.ui.actions.LibraryActionBarContributor#enableGlobalEditMenu()
		 */
		public void enableGlobalEditMenu() {
		}

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

		private boolean canMove(IStructuredSelection selection) {
			for (Iterator iter = selection.iterator(); iter.hasNext();) {
				Object element = iter.next();
				if ((element instanceof MethodElement)
						&& !(element instanceof ContentCategory)
						&& !(element instanceof MethodPlugin)
						&& !(element instanceof MethodConfiguration)
						&& !TngUtil.isPredefined((MethodElement) element)) {
					return true;
				}
			}
			return false;
		}

		/**
		 * @see LibraryActionBarContributor#menuAboutToShow(IMenuManager)
		 */
		public void menuAboutToShow(IMenuManager menuManager) {
			checkLocked();

			// Add our standard marker.
			menuManager.add(new Separator("fixed-additions")); //$NON-NLS-1$
			menuManager.add(new Separator("fixed-additions-end")); //$NON-NLS-1$
			menuManager.add(new Separator("edit")); //$NON-NLS-1$

			// Add the edit menu actions.
			menuManager.add(new ActionContributionItem(libraryViewEditAction));
			menuManager.add(new ActionContributionItem(copyAction));
			menuManager.add(new ActionContributionItem(pasteAction));
			menuManager.add(new Separator());
			menuManager.add(new ActionContributionItem(deleteAction));
			if (canRename) {
				menuManager.add(new ActionContributionItem(renameAction));
			}
			if (canMove) {
				menuManager.add(new ActionContributionItem(moveAction));
			}

			menuManager.add(new Separator("view")); //$NON-NLS-1$
			if (openVariabilityDialogAction.isEnabled()) {
				menuManager.add(new ActionContributionItem(
						openVariabilityDialogAction));
			}
			if (showInResourceNavigatorAction.isEnabled()) {
				menuManager.add(new ActionContributionItem(
						showInResourceNavigatorAction));
			}
			menuManager.add(new Separator());

			// Add our other standard marker where other plugins will contribute
			// menu
			//
			menuManager.add(new Separator("additions")); //$NON-NLS-1$
			menuManager.add(new Separator("additions-end")); //$NON-NLS-1$

			addGlobalActions(menuManager);

			if (!locked) {
				MenuManager submenuManager = null;
				submenuManager = new MenuManager(
						AuthoringUIResources._UI_CreateChild_menu_item);
				populateManager(submenuManager, createChildActions, null);
				menuManager.insertBefore("fixed-additions", submenuManager); //$NON-NLS-1$
			}

			// menuManager.add(new Action("Reload") {
			// /*
			// * (non-Javadoc)
			// *
			// * @see org.eclipse.jface.action.Action#run()
			// */
			// public void run() {
			// ISelection selection = getSelection();
			// if (selection instanceof IStructuredSelection) {
			// Object object = ((IStructuredSelection) selection)
			// .getFirstElement();
			// object = TngUtil.unwrap(object);
			// if (object instanceof InternalEObject) {
			// InternalEObject e = ((InternalEObject) object);
			// ILibraryResourceSet resourceSet = (ILibraryResourceSet) e
			// .eResource().getResourceSet();
			// resourceSet.unload(e);
			// URI uri = e.eProxyURI();
			// EObject newObject = resourceSet.getEObject(e, uri,
			// true);
			// refreshViews();
			// }
			// }
			// }
			// });
		}

		/**
		 * Returns <code>true</code> if the selected method elements can be
		 * renamed.
		 */
		private boolean canRename(IStructuredSelection selection) {
			if (selection.size() > 1)
				return false;
			Object element = TngUtil.unwrap(selection.getFirstElement());
			if (element instanceof NamedElement
					&& !TngUtil.isPredefined((MethodElement) element)) {
				return true;
			}
			return false;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.epf.authoring.ui.actions.LibraryActionBarContributor#refreshViewer(org.eclipse.jface.viewers.Viewer)
		 */
		protected void refreshViewer(final Viewer viewer) {
			if (viewer == LibraryView.this.getViewer()) {
				IRunnableWithProgress runnable = new IRunnableWithProgress() {

					public void run(IProgressMonitor monitor)
							throws InvocationTargetException,
							InterruptedException {
						monitor.beginTask("", 3); //$NON-NLS-1$
						monitor
								.subTask(AuthoringUIResources._UI_RefreshViewer_menu_item);
						monitor.worked(1);
						try {
							// Refresh all loaded resources.
							ILibraryManager manager = (ILibraryManager) LibraryService
									.getInstance().getCurrentLibraryManager();
							if (manager != null) {
								ResourceSet resourceSet = manager
										.getEditingDomain().getResourceSet();
								if (resourceSet instanceof ILibraryResourceSet
										&& ((ILibraryResourceSet) resourceSet)
												.getPersistenceType()
												.equals(
														Services.XMI_PERSISTENCE_TYPE)) {
									List removedResources = new ArrayList();
									List changedResources = new ArrayList();
									for (Iterator iter = new ArrayList(
											resourceSet.getResources())
											.iterator(); iter.hasNext();) {
										Resource resource = (Resource) iter
												.next();
										String loc = resource.getURI()
												.toFileString();
										IResource wsRes = FileManager
												.getResourceForLocation(loc);
										if (wsRes == null) {
											removedResources.add(resource);
										} else if (!wsRes
												.isSynchronized(IResource.DEPTH_ZERO)) {
											changedResources.add(resource);
										}
									}
									monitor.worked(2);
									if (removedResources.isEmpty()
											&& changedResources.isEmpty()) {
										viewer.refresh();
									} else {
										doRefresh(removedResources,
												changedResources, null, false);
									}
								} else {
									viewer.refresh();
								}
							}
						} finally {
							monitor.done();
						}
					}

				};
				IRunnableContext context = new ProgressMonitorDialog(getSite()
						.getShell());
				try {
					getSite().getWorkbenchWindow().getWorkbench()
							.getProgressService().runInUI(context, runnable,
									null);
				} catch (Exception e) {
					AuthoringUIPlugin.getDefault().getLogger().logError(e);
					String title = AuthoringUIResources.ProcessEditor_refreshErrorTitle;
					AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
							title, e.toString(), e);
				}
				return;
			}
			super.refreshViewer(viewer);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.authoring.ui.views.AbstractBaseView#createActionBarContributor()
	 */
	public ILibraryActionBarContributor createActionBarContributor() {
		ILibraryActionBarContributor actionBar = new LibraryViewActionBarContributor(
				editingDomain);
		return actionBar;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.authoring.ui.views.AbstractBaseView#createContextMenuFor(org.eclipse.jface.viewers.StructuredViewer)
	 */
	public void createContextMenuFor(final StructuredViewer viewer) {
		super.createContextMenuFor(viewer);
		int dndOperations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
		Transfer[] transfers = new Transfer[] { HTMLTransfer.getInstance(),
				TextTransfer.getInstance(), LocalTransfer.getInstance() };
		viewer.addDragSupport(dndOperations, transfers,
				new LibraryViewerDragAdapter(viewer));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.authoring.ui.views.AbstractBaseView#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
	 */
	public void menuAboutToShow(IMenuManager menuManager) {
		super.menuAboutToShow(menuManager);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
	 */
	public void init(IViewSite site) throws PartInitException {
		super.init(site);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.authoring.ui.views.AbstractBaseView#dispose()
	 */
	public void dispose() {
		RefreshJob.getInstance().setRefreshHandler(null);

		if (fLayoutActionSet != null)	
			fLayoutActionSet.dispose();

		super.dispose();
		if (doubleClickListener != null) {
			treeViewer.removeDoubleClickListener(doubleClickListener);
		}
	}

	/**
	 * @param obj
	 *            ItemProvider
	 * @return ProcessComponent associated with the given obj
	 */
	public ProcessComponent getProcessComponent(Object obj) {
		Object parent;
		for (parent = obj; (parent != null && !(parent instanceof ProcessComponent));) {
			ItemProviderAdapter adapter = (ItemProviderAdapter) adapterFactory
					.adapt(parent, ITreeItemContentProvider.class);
			parent = adapter.getParent(parent);
		}
		return (ProcessComponent) parent;
	}

	private static abstract class StatusWorkspaceModifyOperation extends
			WorkspaceModifyOperation {

		protected String errMsg;

		public String getErrorMessage() {
			return errMsg;
		}
	}

	/**
	 * opens a Method Library
	 * 
	 * @param path
	 *            path to the library
	 */
	public void openLibrary(final String path) {
		// Do the work within an operation because this is a long running
		// activity that modifies the workbench.
		StatusWorkspaceModifyOperation operation = new StatusWorkspaceModifyOperation() {

			// This is the method that gets invoked when the operation runs.
			public void execute(IProgressMonitor monitor) {
				monitor.beginTask(AuthoringUIResources.openingLibraryTask_name,
						2);
				try {
					monitor.worked(1);
					LibraryService.getInstance().closeCurrentMethodLibrary();
					MethodLibrary library = XMILibraryUtil
							.openMethodLibrary(path);
					LibraryService.getInstance().setCurrentMethodLibrary(
							library);
					LibraryUIPreferences.setSavedLibraryPath(path);
				} catch (Exception ex) {
					if (ex instanceof IOException) {
						String message = ex.getMessage();
						if (message.startsWith("###")) { //$NON-NLS-1$
							String projectFileName = message.substring(3);
							String prompt = AuthoringUIResources.bind(
									AuthoringUIResources.ElementsView_35,
									(new Object[] { projectFileName }));
							if (MsgBox.prompt(prompt, SWT.RETRY | SWT.CANCEL) == SWT.RETRY) {
								openLibrary(path);
							}
						}
					} else {
						AuthoringUIPlugin
								.getDefault()
								.getMsgDialog()
								.displayError(
										AuthoringUIResources.errorDialog_title,
										AuthoringUIResources.openLibraryError_msg,
										ex);
					}
				} finally {
					monitor.done();
				}
			}
		};

		try {
			// This runs the options, and shows progress.
			new ProgressMonitorDialog(getSite().getShell()).run(true, false,
					operation);
			if (operation.getErrorMessage() == null) {
				getSite().getPage().closeAllEditors(false);
			}
		} catch (Exception e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.authoring.ui.views.AbstractBaseView#handleActivate(org.eclipse.ui.IWorkbenchPart)
	 */
	protected void handleActivate(IWorkbenchPart part) {
		super.handleActivate(part);

		// TODO: Review implementation.
		// Make sure that the method library open is not closed.
		XMILibraryUtil.openMethodLibraryProject(LibraryService.getInstance()
				.getCurrentMethodLibrary(), getViewSite().getActionBars()
				.getStatusLineManager().getProgressMonitor());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.authoring.ui.views.SaveableLibraryViewPart#isSaveAsAllowed()
	 */
	public boolean isSaveAsAllowed() {
		// This view should not participate in all the save commands.
		return false;
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.views.SaveableLibraryViewPart#doSaveAs()
	 */
	public void doSaveAs() {
	}
	
	private static FeatureValueWrapperItemProvider getWrapper(List listeners, Object value) {
		for (Iterator iter = listeners.iterator(); iter.hasNext();) {
			Object listener = (Object) iter.next();
			if(listener instanceof FeatureValueWrapperItemProvider
					&& TngUtil.unwrap(listener) == value) {
				return (FeatureValueWrapperItemProvider) listener;
			}
		}
		return null;
	}
	
	/**
	 * Used by org.eclipse.epf.authoring.ui.actions.LinkWithEditor Given an
	 * object that is a MethodElement, selects that object in the Lib Nav
	 * 
	 * @param o
	 */
	public void setSelectionToViewer(Object object) {
		Object o = TngUtil.unwrap(object);
		if (!(o instanceof MethodElement))
			return;
		if (o instanceof MethodConfiguration) {
			super.setSelectionToViewer(Arrays.asList(new Object[] { o }));
			return;
		}
		try {
			MethodPlugin plugin = UmaUtil.getMethodPlugin((MethodElement) o);
			treeViewer.setExpandedState(plugin, true);

			ITreeItemContentProvider pluginAdapter = (ITreeItemContentProvider) TngUtil
					.getAdapter(plugin, ITreeItemContentProvider.class);

			if (o instanceof BreakdownElement) {				
				Process proc = TngUtil.getOwningProcess((BreakdownElement)o);
				if(proc != null) {
					o = proc.eContainer();
				}
			}
			if (o instanceof ProcessComponent || o instanceof ProcessPackage) {

				treeViewer.setExpandedState(pluginAdapter.getChildren(plugin)
						.toArray()[1], true);
				// Expand the process packages.
				expandTreeViewerPackages(((MethodElement) o).eContainer());

			} else {
				ITreeItemContentProvider methodContentPkg = (ITreeItemContentProvider) pluginAdapter
						.getChildren(plugin).toArray()[0];
				treeViewer.setExpandedState(methodContentPkg, true);

				if (o instanceof CustomCategory) {					
					CustomCategory rootCC = TngUtil
							.getRootCustomCategory(plugin);
										
					// find the tree path to the custom category from the root custom category
					//
					final List treePath = new ArrayList();
					for(CustomCategory cc = (CustomCategory) o; cc != rootCC;) {
						treePath.add(0, cc);
						cc = (CustomCategory) AssociationHelper.getCustomCategories(cc).get(0);						 
					}
					Object parent = rootCC;
					int size = treePath.size();
					for (int i = 0; i < size; i++) {
						Object e = treePath.get(i);
						treeViewer.setExpandedState(parent, true);
						// get wrapper
						//
						CustomCategoryItemProvider adapter = (CustomCategoryItemProvider) adapterFactory.adapt(e, ITreeItemContentProvider.class);
						find_wrapper:
						for (Iterator iterator = adapter.getNotifyChangedListeners().iterator(); iterator.hasNext();) {
							Object listener = iterator.next();
							if(listener instanceof FeatureValueWrapperItemProvider
									&& TngUtil.unwrap(listener) == e) {
								FeatureValueWrapperItemProvider wrapper = (FeatureValueWrapperItemProvider) listener;
								for(;wrapper != null && wrapper.getOwner() != parent; 
									wrapper = getWrapper(wrapper.getNotifyChangedListeners(), e)) {									
								}
								if(wrapper != null) {
									parent = wrapper;
									break find_wrapper;
								}
							}
						}
					}
					o = parent;
				} else if (o instanceof ContentCategory) {
					Object stdCats = methodContentPkg.getChildren(o).toArray()[1];
					treeViewer.setExpandedState(stdCats, true);

				} else {
					Object coreContent = methodContentPkg.getChildren(o)
							.toArray()[0];
					treeViewer.setExpandedState(coreContent, true);

					// Expand the content packages.
					expandTreeViewerPackages(((MethodElement) o).eContainer());
				}
			}
		} catch (Exception ex) {
			AuthoringUIPlugin.getDefault().getLogger().logError(ex);
		}

		super.setSelectionToViewer(Arrays.asList(new Object[] { o }));

		if(o instanceof ProcessComponent && object instanceof BreakdownElement) {
			// open the process in its editor and select the breakdown element
			//
			IEditorKeeper.REFERENCE.getEditorKeeper().openEditor(o);
			IEditorPart editor = getSite().getPage().findEditor(new MethodElementEditorInput((MethodElement) o));
			if(editor instanceof ProcessEditor) {
				ProcessEditor procEditor = ((ProcessEditor)editor);
				String pageId;
				if(object instanceof RoleDescriptor || object instanceof TeamProfile) {
					pageId = ProcessEditor.TA_FORM_ID;
				}
				else if(object instanceof WorkProductDescriptor) {
					pageId = ProcessEditor.WPBS_FORM_ID;
				}
				else {
					pageId = ProcessEditor.WBS_FORM_ID;
				}
				procEditor.setActivePage(pageId);
				procEditor.setSelectionToViewer(Collections.singletonList(object));
			}
		}
	}

	private void expandTreeViewerPackages(EObject e) {
		if (e == null)
			return;
		if (e instanceof ContentPackage || e instanceof ProcessPackage) {
			expandTreeViewerPackages(e.eContainer());
			treeViewer.setExpandedState(e, true);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.epf.persistence.util.IRefreshHandler#refresh(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void refresh(final IProgressMonitor monitor) {
		Control ctrl = getViewer().getControl();
		if (ctrl == null || ctrl.isDisposed())
			return;

		if (ctrl.getDisplay().getThread() == Thread.currentThread()) {
			doRefresh(getSite().getShell());
		} else {
			ctrl.getDisplay().syncExec(new Runnable() {

				public void run() {
					doRefresh(null);
				}

			});
		}

	}

	private void blockingRefresh(final ArrayList removedResources,
			final ArrayList changedResources,
			final Collection addedWorkspaceResources,
			final boolean refreshViews, Shell shell) {
		final IRunnableWithProgress runnable = new IRunnableWithProgress() {

			public void run(IProgressMonitor monitor)
					throws InvocationTargetException, InterruptedException {
				monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
				monitor
						.subTask(AuthoringUIResources._UI_RefreshViewer_menu_item);
				monitor.worked(1);
				try {
					// monitor.worked(1);
					doRefresh(removedResources, changedResources,
							addedWorkspaceResources, refreshViews);
				} finally {
					monitor.done();
				}
			}

		};

		IRunnableContext context = new ProgressMonitorDialog(shell);
		try {
			getSite().getWorkbenchWindow().getWorkbench().getProgressService()
					.runInUI(
							context,
							runnable,
							new LibrarySchedulingRule(LibraryService
									.getInstance().getCurrentMethodLibrary()));
		} catch (Exception e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
			String title = AuthoringUIResources.ProcessEditor_refreshErrorTitle;
			AuthoringUIPlugin.getDefault().getMsgDialog().displayError(title,
					e.toString(), e);
		}
	}

	/**
	 * Must be synchronized to avoid stepping on each other in reloading
	 * resources/refreshing UI
	 * 
	 * @param removedResources
	 * @param changedResources
	 * @param addedWorkspaceResources
	 *            collection of IResource objects that are just newly added to
	 *            the library
	 * @param refreshViews
	 */
	private synchronized void doRefresh(Collection removedResources,
			Collection changedResources, Collection addedWorkspaceResources,
			boolean refreshViews) {
		HashSet editorsToRefresh = new HashSet();
		if (!removedResources.isEmpty()) {
			handleRemovedResources(removedResources, editorsToRefresh);
			refreshViews = true;
		}
		if (!changedResources.isEmpty()) {
			handleChangedResources(changedResources, editorsToRefresh,
					refreshViews);
		} else {
			if (refreshViews) {
				refreshViews();
			}

			if (!editorsToRefresh.isEmpty()) {
				// refresh the editors that handleRemovedResources requested
				//
				for (Iterator iter = editorsToRefresh.iterator(); iter
						.hasNext();) {
					Object editor = iter.next();
					if (editor instanceof MethodElementEditor) {
						((MethodElementEditor) editor).refresh();
					}
				}
			}
		}
		if (addedWorkspaceResources != null
				&& !addedWorkspaceResources.isEmpty()) {
			ILibraryManager mgr = LibraryService.getInstance()
					.getCurrentLibraryManager();
			if (mgr != null) {
				ResourceSet resourceSet = mgr.getEditingDomain()
						.getResourceSet();
				if (resourceSet instanceof MultiFileResourceSetImpl) {
					((MultiFileResourceSetImpl) resourceSet)
							.loadNewResources(addedWorkspaceResources);
				}
			}
		}
	}

	private boolean isViewObject(Object o) {
		return o instanceof MethodElement
				&& !(o instanceof ContentDescription
						|| o instanceof ProcessElement || (o instanceof ProcessPackage && UmaUtil
						.getProcessComponent((MethodElement) o) == null));
	}

	private void doRefresh(IRefreshEvent event, Shell shell) {
		if (DEBUG) {
			System.out
					.println("Refreshed objects: " + event.getRefreshedObjects()); //$NON-NLS-1$
		}
		boolean refresh = false;
		for (Iterator iter = event.getRefreshedObjects().iterator(); iter
				.hasNext();) {
			Object e = iter.next();
			if (isViewObject(e)) {
				refresh = true;
				break;
			}
		}
		if (refresh) {
			refreshViews();
		}
	}

	/**
	 * Refreshes the Library View
	 * 
	 * @param shell
	 */
	private void doRefresh(Shell shell) {
		ArrayList movedResources = new ArrayList(RefreshJob.getInstance().getMovedResources());
		if (!movedResources.isEmpty()) {
			for (Iterator iter = movedResources.iterator();iter.hasNext();) {
				Object o = iter.next();
				if (o instanceof IProject) {
					try {
						if (((IProject)o).hasNature(MethodLibraryProjectNature.NATURE_ID)) {
							// TODO: safe to assume XMI library?
							XMILibraryUtil.openMethodLibrary(((IProject)o).getLocation().toString());
							return;
						}
					} catch (LibraryServiceException e) {
						AuthoringUIPlugin.getDefault().getLogger().logError(e);
					} catch (CoreException e) { 
						AuthoringUIPlugin.getDefault().getLogger().logError(e);
					}
				}
			}
		}
		final boolean refreshViews = !RefreshJob.getInstance()
				.getReloadedBeforeRefreshResources().isEmpty()
				|| !RefreshJob.getInstance().getAddedResources().isEmpty();
		ArrayList removedResources = new ArrayList(RefreshJob.getInstance()
				.getRemovedResources());
		ArrayList changedResources = new ArrayList(RefreshJob.getInstance()
				.getChangedResources());
		ArrayList addedWsResources = new ArrayList(RefreshJob.getInstance()
				.getAddedWorkspaceResources());

		if (!removedResources.isEmpty() || !changedResources.isEmpty()
				|| !addedWsResources.isEmpty() || refreshViews) {
			blockingRefresh(removedResources, changedResources,
					addedWsResources, refreshViews, shell);
		}

		if (!removedResources.isEmpty()) {
			RefreshJob.getInstance().getRemovedResources().removeAll(
					removedResources);
		}
		if (!changedResources.isEmpty()) {
			RefreshJob.getInstance().getChangedResources().removeAll(
					changedResources);
		}
		if (!addedWsResources.isEmpty()) {
			RefreshJob.getInstance().getAddedWorkspaceResources().removeAll(
					addedWsResources);
		}
		if (refreshViews) {
			RefreshJob.getInstance().getReloadedBeforeRefreshResources()
					.clear();
			RefreshJob.getInstance().getAddedResources().clear();
		}
	}

	/**
	 * @param removedResources2
	 */
	private Collection handleRemovedResources(Collection removedResources,
			Collection editorsToRefresh) {
		IWorkbenchPage workbenchPage = getSite().getPage();
		IEditorReference[] editorReferences = workbenchPage
				.getEditorReferences();
		ArrayList dirtyEditorsWithConflict = new ArrayList();
		ArrayList removedResourceList = new ArrayList(removedResources);
		if (editorsToRefresh == null) {
			editorsToRefresh = new ArrayList();
		}
		// find all editor with dirty conflict
		//
		for (int i = 0; i < editorReferences.length; i++) {
			IEditorReference reference = editorReferences[i];
			IEditorPart editor = reference.getEditor(true);
			if (editor instanceof MethodElementEditor && editor.isDirty()) {
				MethodElementEditorInput input = (MethodElementEditorInput) editor
						.getEditorInput();
				Resource resource = input.getMethodElement() != null ? input
						.getMethodElement().eResource() : null;
				if (!removedResources.contains(resource)) {
					Collection usedResources = ((MethodElementEditor) editor)
							.getUsedResources();
					check_resource: for (int j = 0; j < removedResourceList
							.size(); j++) {
						resource = (Resource) removedResourceList.get(j);
						if (usedResources.contains(resource)) {
							dirtyEditorsWithConflict.add(editor);
							break check_resource;
						}
					}
				} else {
					editorsToRefresh.add(editor);
				}
			}
		}

		if (!dirtyEditorsWithConflict.isEmpty()) {
			Object[] selected = selectDirtyEditors(dirtyEditorsWithConflict);
			for (int i = 0; i < selected.length; i++) {
				editorsToRefresh.add(selected[i]);
			}
		}

		// Unload the removed resources.
		for (Iterator iter = removedResources.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			ILibraryResourceSet resourceSet = (ILibraryResourceSet) resource
					.getResourceSet();
			try {
				resourceSet.unload(resource, Collections.EMPTY_MAP);
			} catch (Exception e) {
				CommonPlugin.INSTANCE.log(e);
			}
		}

		ILibraryManager manager = (ILibraryManager) LibraryService
				.getInstance().getCurrentLibraryManager();
		if (manager != null) {
			ResourceSet resourceSet = manager.getEditingDomain()
					.getResourceSet();
			if (resourceSet != null) {
				resourceSet.getResources().removeAll(removedResources);
			}
		}

		for (int i = 0; i < editorReferences.length; i++) {
			IEditorReference reference = editorReferences[i];
			IEditorPart editor = reference.getEditor(true);
			if (editor instanceof MethodElementEditor && !editor.isDirty()) {
				Collection usedResources = ((MethodElementEditor) editor)
						.getUsedResources();
				check_resource: for (int j = 0; j < removedResourceList.size(); j++) {
					Resource resource = (Resource) removedResourceList.get(j);
					if (usedResources.contains(resource)) {
						editorsToRefresh.add(editor);
						break check_resource;
					}
				}
			}
		}

		return removedResources;
	}

	/**
	 * 
	 * @param changedResources
	 * @return resources that have been reloaded
	 */
	private Collection handleChangedResources(Collection changedResources,
			Collection editorsToRefresh, boolean forceRefreshViews) {
		if (!forceRefreshViews) {
			for (Iterator iter = changedResources.iterator(); iter.hasNext();) {
				Resource resource = (Resource) iter.next();
				if (resource instanceof ILibraryResource
						&& ((ILibraryResource) resource).getLoadStamp() > lastRefreshTimeStamp) {
					forceRefreshViews = true;
					break;
				}
			}
		}
		return handleChangedResources(changedResources, null,
				forceRefreshViews, editorsToRefresh);
	}

	/**
	 * updates Library View when resources change
	 * 
	 * @param changedResources
	 * @param editorsNotToRefresh
	 * @param forceRefreshViews
	 * @param editorsToRefresh
	 * @return List of changed resources
	 */
	public Collection handleChangedResources(Collection changedResources,
			Collection editorsNotToRefresh, boolean forceRefreshViews,
			Collection editorsToRefresh) {
		Control ctrl = getViewer().getControl();
		if (ctrl == null || ctrl.isDisposed())
			return Collections.EMPTY_LIST;

		IWorkbenchPage workbenchPage = getSite().getPage();
		IEditorReference[] editorReferences = workbenchPage
				.getEditorReferences();
		ArrayList dirtyEditorsWithConflict = new ArrayList();
		ArrayList changedResourceList = new ArrayList(changedResources);
		// find all editor with dirty conflict
		//
		for (int i = 0; i < editorReferences.length; i++) {
			IEditorReference reference = editorReferences[i];
			IEditorPart editor = reference.getEditor(true);
			if (editor instanceof MethodElementEditor && editor.isDirty()) {
				Collection usedResources = ((MethodElementEditor) editor)
						.getUsedResources();
				check_resource: for (int j = 0; j < changedResourceList.size(); j++) {
					Resource resource = (Resource) changedResourceList.get(j);
					if (usedResources.contains(resource)) {
						dirtyEditorsWithConflict.add(editor);
						break check_resource;
					}
				}
			}
		}
		final ArrayList editorListToRefresh = new ArrayList();
		if (editorsToRefresh != null) {
			editorListToRefresh.addAll(editorsToRefresh);
		}
		if (!dirtyEditorsWithConflict.isEmpty()) {
			Object[] result = selectDirtyEditors(dirtyEditorsWithConflict);
			for (int i = 0; i < result.length; i++) {
				Object editor = result[i];
				if ((editorsNotToRefresh == null || !editorsNotToRefresh
						.contains(editor))
						&& (editorsToRefresh == null || !editorsToRefresh
								.contains(editor))) {
					editorListToRefresh.add(editor);
					dirtyEditorsWithConflict.remove(editor);
				}
			}
			// remove all resources used by dirty editors with conflict from the
			// collection of changed resources
			//
			for (int i = 0; i < dirtyEditorsWithConflict.size(); i++) {
				MethodElementEditor editor = (MethodElementEditor) dirtyEditorsWithConflict
						.get(i);
				Collection usedResources = editor.getUsedResources();
				changedResourceList.removeAll(usedResources);
			}
		}

		boolean refreshViews = false;
		if (!changedResourceList.isEmpty()) {
			for (int i = 0; i < editorReferences.length; i++) {
				IEditorReference reference = editorReferences[i];
				IEditorPart editor = reference.getEditor(true);
				if (editor instanceof MethodElementEditor && !editor.isDirty()) {
					Collection usedResources = ((MethodElementEditor) editor)
							.getUsedResources();
					check_resource: for (int j = 0; j < changedResourceList
							.size(); j++) {
						Resource resource = (Resource) changedResourceList
								.get(j);
						if (usedResources.contains(resource)) {
							editorListToRefresh.add(editor);
							break check_resource;
						}
					}
				}
			}

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

				refreshViews = !reloadedResources.isEmpty();
			}
		}
		if (forceRefreshViews || refreshViews) {
			refreshViews();
		}
		if (!editorListToRefresh.isEmpty()) {
			for (int i = 0; i < editorListToRefresh.size(); i++) {
				MethodElementEditor editor = (MethodElementEditor) editorListToRefresh
						.get(i);
				try {
					editor.refresh();
				} catch (Exception e) {
					AuthoringUIPlugin.getDefault().getLogger().logError(e);
				}
			}
		}
		return changedResourceList;
	}

	/**
	 * Refreshes Library and Configuration views if necessary
	 * 
	 */
	public synchronized void refreshViews() {
		EObject input = (EObject) getViewer().getInput();
		if (input != null) {
			if (input.eIsProxy()) {
				setInputForViewer(RefreshJob.getInstance().resolve(input));
			} else {
				ISelection selection = getViewer().getSelection();
				getViewer().refresh();
				updateLastRefreshTimestamp();
				if (selection instanceof IStructuredSelection) {
					IStructuredSelection structuredSelection = (IStructuredSelection) selection;
					Object o = null;
					if (structuredSelection.size() == 1
							&& (o = structuredSelection.getFirstElement()) instanceof EObject
							&& ((EObject) o).eIsProxy()) {
						o = RefreshJob.getInstance().resolve((EObject) o);
						try {
							setSelectionToViewer(o);
						} catch (Exception e) {
							AuthoringUIPlugin.getDefault().getLogger()
									.logError(e);
						}
					} else {
						restoreSelection(getViewer(), selection);
					}
				}
			}
		}

		ConfigurationView configView = ConfigurationView.getView();
		if (configView != null) {
			Control ctrl = configView.getViewer().getControl();
			if (ctrl != null && !ctrl.isDisposed()) {
				input = (EObject) configView.getViewer().getInput();
				if (input != null) {
					if (input.eIsProxy()) {
						configView.setInputForViewer(RefreshJob.getInstance()
								.resolve(input));
					} else {
						ISelection selection = configView.getViewer()
								.getSelection();
						configView.getViewer().refresh();
						restoreSelection(configView.getViewer(), selection);
					}
				}
			}
		}
	}

	private Object[] selectDirtyEditors(List dirtyEditors) {
		String title = AuthoringUIResources._UI_FileConflict_label;
		String msg = AuthoringUIResources.selectEditorsToDiscardConflictChanges;
		return selectEditors(dirtyEditors, title, msg);
	}

	private Object[] selectEditors(List editors, String title, String msg) {
		// prompt user to discard changes in editors that conflict with outside
		// change
		//
		IStructuredContentProvider contentProvider = new IStructuredContentProvider() {
			List fContents;

			public Object[] getElements(Object inputElement) {
				if (fContents != null && fContents == inputElement)
					return fContents.toArray();
				return new Object[0];
			}

			public void dispose() {
			}

			public void inputChanged(Viewer viewer, Object oldInput,
					Object newInput) {
				if (newInput instanceof List)
					fContents = (List) newInput;
				else
					fContents = null;

			}

		};
		ILabelProvider labelProvider = new LabelProvider() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
			 */
			public String getText(Object element) {
				if (element instanceof IEditorPart) {
					return ((IEditorPart) element).getTitle();
				}
				return super.getText(element);
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
			 */
			public Image getImage(Object element) {
				if (element instanceof IEditorPart) {
					return ((IEditorPart) element).getTitleImage();
				}
				return super.getImage(element);
			}
		};
		ListSelectionDialog dlg = new ListSelectionDialog(getSite().getShell(),
				editors, contentProvider, labelProvider, msg);
		dlg.setTitle(title);
		dlg.setBlockOnOpen(true);
		dlg.open();
		return dlg.getResult();
	}

	private static void restoreSelection(Viewer viewer, ISelection selection) {
		if (selection instanceof IStructuredSelection && !selection.isEmpty()) {
			IStructuredSelection structuredSelection = (IStructuredSelection) selection;
			boolean restore = false;
			ArrayList resolvedList = new ArrayList();
			for (Iterator iter = structuredSelection.iterator(); iter.hasNext();) {
				Object object = iter.next();
				if (object instanceof EObject) {
					EObject eObj = (EObject) object;
					if (eObj.eIsProxy()) {
						eObj = RefreshJob.getInstance().resolve(eObj);
						restore = true;
					}
					if (!eObj.eIsProxy()) {
						resolvedList.add(eObj);
					}
				}
			}
			if (restore) {
				viewer
						.setSelection(new StructuredSelection(resolvedList),
								true);
			}
		}
	}

	/**
	 * rename an element
	 * 
	 * @param e
	 *            element to rename
	 * @param newName
	 *            the new name
	 */
	public static void runRename(final NamedElement e, final String newName) {
		Display.getDefault().syncExec(new Runnable() {
			public void run() {
				doRename(e, newName);
			}
		});
	}

	private static void doRename(final NamedElement e, final String newName) {
		String oldName = e.getName();

		if (false) {
			System.out.println("LD> oldName: " + oldName); //$NON-NLS-1$
			System.out.println("LD> newName: " + newName); //$NON-NLS-1$
			System.out.println(""); //$NON-NLS-1$
		}

		e.setName(newName);

		// Special handling for ProcessComponent to keep its
		// name and the name of its process in sync.
		if (e instanceof ProcessComponent) {
			Process proc = ((ProcessComponent) e).getProcess();
			proc.setName(newName);
		}

		Runnable runnable = new Runnable() {

			public void run() {
				// Save the modified file(s).
				ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil
						.getCurrentPersister().getFailSafePersister();
				try {
					persister.save(e.eResource());
					persister.commit();

					Collection renamedResources = new ArrayList();
					if (e instanceof ContentElement
							&& ContentDescriptionFactory
									.hasPresentation((MethodElement) e)) {
						renamedResources.add(((ContentElement) e)
								.getPresentation().eResource());
					}
					renamedResources.add(e.eResource());

					persister.adjustLocation(renamedResources);
				} catch (Exception e1) {
					AuthoringUIPlugin.getDefault().getLogger().logError(e1);

					persister.rollback();

					String details = e1.getMessage() != null ? MessageFormat
							.format(": {0}", new Object[] { e1.getMessage() }) : ""; //$NON-NLS-1$ //$NON-NLS-2$
					String msg = MessageFormat.format(
							AuthoringUIResources.ElementsView_err_saving,
							new Object[] {
									e.eResource().getURI().toFileString(),
									details });
					throw new MessageException(msg);
				}
			}

		};

		if (!UserInteractionHelper.runWithProgress(runnable,
				AuthoringUIResources.ElementsView_renaming_text)) {
			// restore old name
			e.setName(oldName);
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.IShowInTarget#show(org.eclipse.ui.part.ShowInContext)
	 */
	public boolean show(ShowInContext context) {
		if (context.getInput() instanceof MarkerAdapter) {
			IViewPart view = getViewSite().getPage().findView(
					"org.eclipse.ui.views.ProblemView"); //$NON-NLS-1$
			ISelectionProvider selectionProvider = view.getViewSite()
					.getSelectionProvider();
			StructuredSelection selection = (StructuredSelection) selectionProvider
					.getSelection();
			Object o = selection.getFirstElement();
			if (o instanceof IMarker) {
				IMarker marker = (IMarker) o;
				try {
					String guid = (String) marker
							.getAttribute(LibraryValidationMarkerHelper.GUID);
					if (guid != null) {
						IResource wsRes = marker.getResource();
						ILibraryManager libMgr = LibraryService.getInstance().getCurrentLibraryManager();						
						Resource resource = libMgr.getEditingDomain().getResourceSet()
								.getResource(
										URI.createFileURI(wsRes.getLocation()
												.toString()), false);
						Object element;
						if(resource != null) {
							element = resource.getEObject(guid);
						}
						else {
							element = libMgr.getMethodElement(guid);
						}
						if(element != null) {
							setSelectionToViewer(element);
							return true;
						}
					}
				} catch (CoreException e) {
					AuthoringUIPlugin.getDefault().getLogger().logError(e);
				}
			}
		} else if (context.getSelection() instanceof TreeSelection) {
			// from search results view
			TreeSelection sel = (TreeSelection)context.getSelection();
			setSelectionToViewer(sel.getFirstElement());
		}
		return false;
	}
}
