//------------------------------------------------------------------------------
// 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.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.common.ui.util.MsgBox;
import org.eclipse.epf.common.ui.util.MsgDialog;
import org.eclipse.epf.common.ui.util.PerspectiveUtil;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.FeatureValueWrapperItemProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.Misc;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.ui.LibraryUIManager;
import org.eclipse.epf.persistence.refresh.RefreshJob;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.BreakdownElementDescription;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.DescribableElement;
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.ProcessComponent;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;

/**
 * A helper class for managing the views and editors in the Authoring
 * perspective.
 * 
 * @author Phong Nguyen Le
 * @author Kelvin Low
 * @author Jinhua Xi
 * @since 1.0
 */
public final class ViewHelper {

	/**
	 * Prompts the user to save the open library if it has been modified.
	 * 
	 * @return <code>true<code> if the user saved or discarded the change,
	 * 		   <code>false</code> if the user cancelled the action that
	 *         triggered this call.
	 */
	public static boolean promptSave() {
		ILibraryManager manager = (ILibraryManager) LibraryService
				.getInstance().getCurrentLibraryManager();
		if (manager != null && manager.isMethodLibraryModified()) {
			int ret = MsgBox.prompt(AuthoringUIResources.saveLibraryDialog_title, 
					AuthoringUIResources.saveLibraryDialog_text, 
					SWT.YES | SWT.NO | SWT.CANCEL);
			switch (ret) {
			case SWT.YES:
				try {
					LibraryService.getInstance().saveCurrentMethodLibrary();
				} catch (Exception e) {
					MsgDialog dialog = AuthoringUIPlugin.getDefault()
							.getMsgDialog();
					dialog
							.displayError(
									AuthoringUIResources.saveLibraryDialog_title, 
									AuthoringUIResources.saveLibraryError_msg, 
									AuthoringUIResources.error_reason, e); 

					return dialog
							.displayPrompt(
									AuthoringUIResources.openLibraryDialog_title, 
									AuthoringUIResources.openLibraryDialog_text); 
				}
				break;
			case SWT.NO:
				// Discard all changes by resetting all resources as unchanged.
				manager.discardMethodLibraryChanges();
				break;
			case SWT.CANCEL:
				return false;
			}
		}
		return true;
	}

	/**
	 * Prompts the user to save the open library if it has been modified.
	 * 
	 * @return the choice the user made when prompted to save - one of SWT.YES, SWT.NO, SWT.CANCEL
	 */
	public static int promptSaveInt() {
		ILibraryManager manager = (ILibraryManager) LibraryService
				.getInstance().getCurrentLibraryManager();
		if (manager != null && manager.isMethodLibraryModified()) {
			int ret = MsgBox.prompt(AuthoringUIResources.saveLibraryDialog_title, 
					AuthoringUIResources.saveLibraryDialog_text, 
					SWT.YES | SWT.NO | SWT.CANCEL);
			switch (ret) {
			case SWT.YES:
				try {
					LibraryService.getInstance().saveCurrentMethodLibrary();
				} catch (Exception e) {
					MsgDialog dialog = AuthoringUIPlugin.getDefault()
							.getMsgDialog();
					dialog
							.displayError(
									AuthoringUIResources.saveLibraryDialog_title, 
									AuthoringUIResources.saveLibraryError_msg, 
									AuthoringUIResources.error_reason, e); 
				}
				return SWT.YES;
			case SWT.NO:
				// Discard all changes by resetting all resources as unchanged.
				manager.discardMethodLibraryChanges();
				return SWT.NO;
			case SWT.CANCEL:
				return SWT.CANCEL;
			}
		}

		return SWT.CANCEL;
	}

	/**
	 * closes all editors on the active page
	 *
	 */
	public static void closeAllEditors() {
		PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
				.closeAllEditors(true);
	}

//	/**
//	 * closes the MessageView (error view)
//	 *
//	 */
//	public static void closeMessageView() {
//		PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
//				.hideView(MessageView.getView());
//	}

	/**
	 * handles a dangling object
	 * @param object
	 * @return
	 * 			Object
	 */
	public static Object handleDangling(Object object) {
		if (object instanceof MethodElement
				&& ((EObject) object).eResource() == null) {
			AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
					AuthoringUIResources.errorDialog_title, 
					AuthoringUIResources.bind(AuthoringUIResources.elementAlreadyDeletedError_msg, ((MethodElement) object).getName()));
			return null;
		} else if (object instanceof FeatureValueWrapperItemProvider) {
			FeatureValueWrapperItemProvider adapter = (FeatureValueWrapperItemProvider) object;
			Object value = adapter.getValue();
			if (value instanceof MethodElement
					&& ((EObject) value).eResource() == null) {
				Object owner = TngUtil.unwrap(adapter.getParent(value));
				if (owner instanceof ItemProviderAdapter) {
					// This is a UI item provider.
					owner = ((ItemProviderAdapter) owner).getTarget();
				}
				String ownerName = ((MethodElement) owner).getName();
				EStructuralFeature feature = adapter.getFeature();
				if (feature != null) {
					if (AuthoringUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayPrompt(
									AuthoringUIResources.deleteDialog_title, 
									AuthoringUIResources.bind(AuthoringUIResources.ViewHelper_alreadydeletedconfirm_text, ((MethodElement) value)
									.getName(), ownerName))) { 
						// Remove the association.
						if (feature.isMany()) {
							((Collection) ((EObject) owner).eGet(feature))
									.remove(value);
						}
					}
				} else {
					AuthoringUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayError(
									AuthoringUIResources.errorDialog_title, 
									AuthoringUIResources.bind(AuthoringUIResources.elementAlreadyDeletedError_msg, ((MethodElement) value)
									.getName()));
				}
				return null;
			}
		}
		return object;
	}

	/* TODO: Is this still needed?
	public static void loadAllAndSaveAll() {
		final MethodLibrary lib = LibraryService.getInstance()
				.getCurrentMethodLibrary();
		if (lib == null)
			return;

		// Do the work within an operation because this is a long running
		// activity that modifies the workbench.
		WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
			// This is the method that gets invoked when the operation runs.
			public void execute(IProgressMonitor monitor) {
				monitor.beginTask(AuthoringUIResources
						.getString("AuthoringUI.upgradingLibraryTask.name"), 3); //$NON-NLS-1$
				try {
					try {
						monitor.worked(1);
						monitor
								.setTaskName(AuthoringUIResources
										.getString("AuthoringUI.loadingLibraryElementsTask.name")); //$NON-NLS-1$
						ModelStorage.loadAllProxies(lib);
					} catch (Exception e) {
						AuthoringUIPlugin
								.getDefault()
								.getMsgDialog()
								.displayError(
										AuthoringUIResources
												.getString("AuthoringUI.upgradeLibraryDialog.title"), //$NON-NLS-1$
										AuthoringUIResources
												.getString("AuthoringUI.upgradeLibraryError.msg"), //$NON-NLS-1$
										AuthoringUIResources
												.getString("AuthoringUI.upgradeLibraryError.reason"), //$NON-NLS-1$
										e);
						return;
					}
					try {
						monitor.worked(1);
						monitor
								.setTaskName(AuthoringUIResources
										.getString("AuthoringUI.savingUpgradedElementsTask.name")); //$NON-NLS-1$
						MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) lib
								.eResource().getResourceSet();
						resourceSet.save(LibraryProcessor.getInstance()
								.getSaveOptions(), true);
					} catch (Exception e) {
						AuthoringUIPlugin
								.getDefault()
								.getMsgDialog()
								.displayError(
										AuthoringUIResources
												.getString("AuthoringUI.upgradeLibraryDialog.title"), //$NON-NLS-1$
										AuthoringUIResources
												.getString("AuthoringUI.upgradeLibraryError.msg"), //$NON-NLS-1$
										AuthoringUIResources
												.getString("AuthoringUI.saveUpgradedLibraryError.reason"), //$NON-NLS-1$
										e);
					}
				} finally {
					monitor.done();
				}
			}
		};

		try {
			// Run the operation and display the progress.
			new ProgressMonitorDialog(Display.getDefault().getActiveShell())
					.run(true, false, operation);
		} catch (Exception e) {
			AuthoringUIPlugin
					.getDefault()
					.getMsgDialog()
					.displayError(
							AuthoringUIResources
									.getString("AuthoringUI.upgradeLibraryDialog.title"), //$NON-NLS-1$
							AuthoringUIResources
									.getString("AuthoringUI.upgradeLibraryError.msg"), //$NON-NLS-1$
							AuthoringUIResources
									.getString("AuthoringUI.internalError.reason"), //$NON-NLS-1$
							e);
		}
	}
	*/

	/**
	 * Checks if the current selection is locked.
	 */
	public static boolean isLocked(IStructuredSelection selection) {
		for (Iterator iter = selection.iterator(); iter.hasNext();) {
			Object element = iter.next();
			while (element instanceof ITreeItemContentProvider) {
				element = ((ITreeItemContentProvider) element).getParent(null);
			}
			element = TngUtil.unwrap(element);
			if (element instanceof EObject
					&& TngUtil.isLocked((EObject) element)) {
				return true;
			}
		}

		return false;
	}
	
	/**
	 * Judge if there is a defined customized locker
	 * @return true
	 */
	public static boolean hasCustomizedLocker(IStructuredSelection selection){
		for (Iterator iter = selection.iterator(); iter.hasNext();) {
			Object element = iter.next();
			while (element instanceof ITreeItemContentProvider) {
				element = ((ITreeItemContentProvider) element).getParent(null);
			}			
			element = TngUtil.unwrap(element);			
			if (element instanceof EObject ) {	
				AbstractLocker locker = null;
				if(element instanceof MethodConfiguration ){
					locker = LockerFactory.getInstance().getLocker(element);	
				}else{
					MethodPlugin plugin = UmaUtil.getMethodPlugin((EObject)element);
					if(plugin != null  ){
						locker = LockerFactory.getInstance().getLocker(plugin);						
					}
				}				
				if(locker != null ){
					return true;
				}				
			}
		}
		return false;
	}

	/**
	 * Checks if the current selection is locked.
	 * If there is a customized locker, use it, otherwise check it with the locked flag of 
	 * Method plugin
	 * @param selection
	 * @return
	 */
	public static boolean isLockedWithCustomizedLocker(IStructuredSelection selection) {
		for (Iterator iter = selection.iterator(); iter.hasNext();) {			
			Object selectedItem = iter.next();
			Object element = selectedItem;
			while (element instanceof ITreeItemContentProvider) {
				element = ((ITreeItemContentProvider) element).getParent(null);
			}			
			Object unwrapElement = TngUtil.unwrap(element);
			
			if (unwrapElement instanceof EObject ) {	
				
				if(element instanceof MethodConfiguration ){
					AbstractLocker locker = LockerFactory.getInstance().getLocker(element);					
					if(locker != null ){
						if( locker.isLocked(element)){
							return true;
						}
					}
				}
				
				MethodPlugin plugin = UmaUtil.getMethodPlugin((EObject)unwrapElement);
				if(plugin != null ){
					AbstractLocker locker = LockerFactory.getInstance().getLocker(plugin);					
					if(locker != null ){
						if( locker.isLocked(selectedItem)){
							return true;
						}
					}else if( TngUtil.isLocked((EObject) unwrapElement)){
						return true;
					}
				}				
			}
		}

		return false;
	}
	
	/**
	 * Check whether the destination is locked by a customized locker.
	 * Note: Some item could be locked by a extented locker.
	 * @return
	 */
	public static boolean isExtendedLocked(Object destination) {
		try {
			if (destination == null) {
				return false;
			}
			Object element = destination;
			while (element instanceof ITreeItemContentProvider) {
				element = ((ITreeItemContentProvider) element).getParent(null);
			}
			element = TngUtil.unwrap(element);
			if (element instanceof EObject) {
				MethodPlugin plugin = UmaUtil
				.getMethodPlugin((EObject) element);
				if (plugin != null) {
					AbstractLocker locker = LockerFactory.getInstance()
					.getLocker(plugin);
					if (locker != null && locker.isLocked(destination)) {
						return true;
					}
				}
			}
		} catch (Exception e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return false;
	}

	/**
	 * Fixes the content description GUIDs.
	 */
	public static void fixContentDescriptionGUIDs() {
		final MethodLibrary lib = LibraryService.getInstance()
				.getCurrentMethodLibrary();
		if (lib == null)
			return;

		org.eclipse.epf.library.edit.util.IRunnableWithProgress runnable = new org.eclipse.epf.library.edit.util.IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
					throws InvocationTargetException, InterruptedException {
				HashSet modifiedResources = new HashSet();
				for (Iterator iter = lib.eAllContents(); iter.hasNext();) {
					InternalEObject element = (InternalEObject) iter.next();
					if (element.eProxyURI() == null) {
						if (element instanceof ContentDescription) {
							ContentDescription content = (ContentDescription) element;
							DescribableElement container = (DescribableElement) element
									.eContainer();
							if (container != null) {
								String guid = UmaUtil.generateGUID(container
										.getGuid());
								if (!guid.equals(content.getGuid())) {
									content.setGuid(guid);
									modifiedResources.add(content.eResource());
									modifiedResources
											.add(container.eResource());
								}
							}
						}
					} else {
						AuthoringUIPlugin
								.getDefault()
								.getLogger()
								.logError(
										"Unresolved proxy in '" + element.eResource().getURI().toFileString() + "': " + element); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}

				monitor.subTask(AuthoringUIResources.savingFilesTask_name);
				ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil.getCurrentPersister().getFailSafePersister();
				try {
					for (Iterator iter = modifiedResources.iterator(); iter
							.hasNext();) {
						Resource resource = (Resource) iter.next();
						monitor.subTask(AuthoringUIResources.bind(AuthoringUIResources.savingTask_name, resource.getURI().toFileString()));
						persister.save(resource);
					}
					persister.commit();
				} catch (Exception e) {
					persister.rollback();
					throw new WrappedException(e);
				}
			}

		};
		UserInteractionHelper
				.runWithProgress(
						runnable,
						AuthoringUIResources.fixingContentDescriptionGUIDsTask_name); 
	}

	private static String checkProxy(InternalEObject element, EReference ref,
			Object value) {
		if (value instanceof InternalEObject) {
			InternalEObject eObj = (InternalEObject) value;
			if (eObj.eIsProxy()) {
				EObject resolved = element.eResolveProxy(eObj);
				String errMsg = null;
				if (resolved == eObj) {
					errMsg = "Unresolved proxy"; //$NON-NLS-1$
				} else if (!ref.getEType().isInstance(resolved)) {
					errMsg = "Invalid data"; //$NON-NLS-1$
				}
				if (errMsg != null) {
					String path;
					if (element instanceof NamedElement) {
						path = ref.getEType().getName()
								+ "(" + Misc.getPathRelativeToLibrary((NamedElement) element) + ")." + ref.getName() + " = "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
					} else {
						path = ""; //$NON-NLS-1$
					}
					return errMsg
							+ " in '" + element.eResource().getURI().toFileString() + "': " + path + resolved; //$NON-NLS-1$ //$NON-NLS-2$
				}
			}
		}
		return null;
	}

	/**
	 * Library health check
	 *
	 */
	public static void checkLibraryHealth() {
		final MethodLibrary lib = LibraryService.getInstance()
				.getCurrentMethodLibrary();
		if (lib == null)
			return;

		org.eclipse.epf.library.edit.util.IRunnableWithProgress runnable = new org.eclipse.epf.library.edit.util.IRunnableWithProgress() {

			public void run(IProgressMonitor monitor)
					throws InvocationTargetException, InterruptedException {
				AuthoringUIPlugin.getDefault().getLogger().logInfo(
						"++++ LIBRARY HEALTH CHECK REPORT - START +++"); //$NON-NLS-1$
				StringWriter strWriter = new StringWriter();
				PrintWriter printWriter = new PrintWriter(strWriter);
				printWriter.println();
				printWriter
						.println("UNRESOLVED/INVALID PROXIES IN X-REFERENCES"); //$NON-NLS-1$
				printWriter
						.println("------------------------------------------"); //$NON-NLS-1$
				for (Iterator iter = lib.eAllContents(); iter.hasNext();) {
					InternalEObject element = (InternalEObject) iter.next();
					if (element.eProxyURI() == null) {
						if (element instanceof ContentDescription) {
							ContentDescription content = (ContentDescription) element;
							DescribableElement container = (DescribableElement) element
									.eContainer();
							if (container != null) {
								String guid = UmaUtil.generateGUID(container
										.getGuid());
								if (!guid.equals(content.getGuid())) {
									AuthoringUIPlugin
											.getDefault()
											.getLogger()
											.logError(
													"ContentDescription with invalid GUID: " + content.getGuid() + " in '" + content.eResource().getURI().toFileString() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
								}
							} else {
								AuthoringUIPlugin
										.getDefault()
										.getLogger()
										.logError(
												"ContentDescription without a container: " + content); //$NON-NLS-1$
							}

							if (content instanceof BreakdownElementDescription) {
								// check if the content.xmi of the process is in
								// the right place
								ProcessComponent procComp = UmaUtil
										.getProcessComponent(content);
								if (procComp != null) {
									String modelPath = procComp.eResource()
											.getURI().toFileString();
									File dir = new File(modelPath)
											.getParentFile();
									String contentPath = content.eResource()
											.getURI().toFileString();

									// System.out.println("model path: " +
									// modelPath);
									// System.out.println("content path: " +
									// contentPath);
									// System.out.println();

									File contentDir = new File(contentPath)
											.getParentFile();
									if (!dir.equals(contentDir)) {
										AuthoringUIPlugin
												.getDefault()
												.getLogger()
												.logError(
														"Content file of " + container.eClass().getName() + " '" + container.getName() + "' in '" + modelPath + " is misplaced: " + contentPath); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
									}
								}
							}
						}

						// check for unresolved proxies in cross references
						ArrayList xReferences = new ArrayList(element.eClass()
								.getEAllReferences());
						xReferences.removeAll(element.eClass()
								.getEAllContainments());
						for (Iterator iterator = xReferences.iterator(); iterator
								.hasNext();) {
							EReference ref = (EReference) iterator.next();
							Object value = element.eGet(ref, false);
							if (ref.isMany()) {
								if (value instanceof InternalEList) {
									InternalEList list = (InternalEList) value;
									for (Iterator iter1 = list.basicIterator(); iter1
											.hasNext();) {
										String msg = checkProxy(element, ref,
												iter1.next());
										if (msg != null) {
											printWriter.println(msg);
										}
									}
								}
							} else {
								String msg = checkProxy(element, ref, value);
								if (msg != null) {
									printWriter.println(msg);
								}
							}
						}
					} else {
						AuthoringUIPlugin
								.getDefault()
								.getLogger()
								.logError(
										"Unresolved proxy in '" + element.eResource().getURI().toFileString() + "': " + element); //$NON-NLS-1$ //$NON-NLS-2$
					}

				}
				AuthoringUIPlugin.getDefault().getLogger().logError(
						strWriter.toString());
				AuthoringUIPlugin.getDefault().getLogger().logInfo(
						"++++ LIBRARY HEALTH CHECK REPORT - END +++"); //$NON-NLS-1$
			}

		};
		if (UserInteractionHelper
				.runWithProgress(runnable, AuthoringUIResources.viewHelper_performHealthCheck)) { 
			String title = AuthoringUIResources.viewHelperHealthCheckDialog_title; 
			String message = AuthoringUIResources.viewHelperHealthCheckDialog_message; 
			AuthoringUIPlugin.getDefault().getMsgDialog().displayInfo(title,
					message);
		}
	}

	/**
	 * removes invalid reference in the open library
	 *
	 */
	public static void removeInvalidReferences() {
		final MethodLibrary lib = LibraryService.getInstance()
				.getCurrentMethodLibrary();
		if (lib == null)
			return;

		org.eclipse.epf.library.edit.util.IRunnableWithProgress runnable = new org.eclipse.epf.library.edit.util.IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
					throws InvocationTargetException, InterruptedException {
				HashSet modifiedResources = new HashSet();
				for (Iterator iter = lib.eAllContents(); iter.hasNext();) {
					InternalEObject element = (InternalEObject) iter.next();
					if (element.eProxyURI() == null) {
						ArrayList xReferences = new ArrayList(element.eClass()
								.getEAllReferences());
						xReferences.removeAll(element.eClass()
								.getEAllContainments());
						for (Iterator iterator = xReferences.iterator(); iterator
								.hasNext();) {
							EReference ref = (EReference) iterator.next();
							Object value = element.eGet(ref, false);
							if (ref.isMany()) {
								if (value instanceof InternalEList) {
									InternalEList list = (InternalEList) value;
									ArrayList invalidProxies = new ArrayList();
									for (Iterator iter1 = list.basicIterator(); iter1
											.hasNext();) {
										Object v = iter1.next();
										if (isInvalidReference(element, ref, v)) {
											invalidProxies.add(v);
										}
									}
									if (!invalidProxies.isEmpty()) {
										removeInvalidReferences(element, list,
												invalidProxies);
										modifiedResources.add(element
												.eResource());
									}
								}
							} else {
								if (isInvalidReference(element, ref, value)) {
									element.eSet(ref, null);
									modifiedResources.add(element.eResource());
								}
							}
						}
					} else {
						AuthoringUIPlugin
								.getDefault()
								.getLogger()
								.logError(
										"Unresolved proxy in '" + element.eResource().getURI().toFileString() + "': " + element); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}

				monitor.subTask(AuthoringUIResources.savingFilesTask_name); 
				ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil.getCurrentPersister().getFailSafePersister();
				try {
					for (Iterator iter = modifiedResources.iterator(); iter
							.hasNext();) {
						Resource resource = (Resource) iter.next();
						monitor.subTask(AuthoringUIResources.bind(AuthoringUIResources.savingTask_name, resource.getURI().toFileString()));
						persister.save(resource);
					}
					persister.commit();
				} catch (Exception e) {
					persister.rollback();
					throw new WrappedException(e);
				}
			}

			private boolean isInvalidReference(InternalEObject element,
					EReference ref, Object value) {
				if (value instanceof InternalEObject) {
					InternalEObject eObj = (InternalEObject) value;
					if (eObj.eIsProxy()) {
						EObject resolved = element.eResolveProxy(eObj);
						if (!ref.getEType().isInstance(resolved)) {
							return true;
						}
					}
				}
				return false;
			}

			private void removeInvalidReferences(InternalEObject element,
					InternalEList values, Collection invalidProxies) {
				ArrayList list = new ArrayList(values.basicList());
				list.removeAll(invalidProxies);
				values.clear();
				int max = list.size() - 1;
				for (int i = max; i > -1; i--) {
					list.set(i, element.eResolveProxy((InternalEObject) list
							.get(i)));
				}
				values.addAll(list);
			}

		};
		UserInteractionHelper.runWithProgress(runnable, AuthoringUIResources.deletingInvalidReferencesTask_name); 

	}

	/**
	 * reloads the current library.  Used on a rollback error
	 * @param shell
	 */
	public static void reloadCurrentLibaryOnRollbackError(Shell shell) {
		reloadCurrentLibrary(shell, AuthoringUIResources.ViewHelper_reloadLibOnRollbackError);
	}

	/**
	 * displays the message and reloads the current library 
	 * @param shell
	 * @param message
	 */
	public static void reloadCurrentLibrary(final Shell shell, final String message) {
		Display display = MsgBox.getDisplay();
		Runnable runnable = new Runnable() {

			public void run() {
				doReloadCurrentLibrary(shell, message); 
			}
			
		};
		if(display != null) {
			display.asyncExec(runnable);
		}
		else {
			runnable.run();
		}		

	}
	
	private static void doReloadCurrentLibrary(Shell shell, String message) {
		if (shell == null) {
			MsgBox.getDefaultShell();
		}
		String title = AuthoringUIResources.reloadDialog_title; 
		if (message == null) {
			message = AuthoringUIResources.reloadDialog_message; 
		}
		AuthoringUIPlugin.getDefault().getMsgDialog().displayInfo(title,
				message);

		// The library needs to be reloaded.
		String libDir = LibraryService.getInstance()
				.getCurrentMethodLibraryLocation();
		LibraryUIManager.getInstance().openLibrary(libDir);
	}

	/**
	 * opens the given viewId
	 * @param viewId
	 * @return
	 * 			View
	 */
	public static IViewPart openView(String viewId) {
		return findView(viewId, true);
	}
	
	
	/**
	 * opens the given viewId
	 * @param viewId
	 * @return
	 * 			View
	 */
	public static IViewPart findView(String viewId, boolean show) {
		try {
			IWorkbenchPage activePage = PlatformUI.getWorkbench()
					.getActiveWorkbenchWindow().getActivePage();
			if (activePage != null) {
				IViewPart view = activePage.findView(viewId);
				if (view == null) {
					
					// always create the view
					view = activePage.showView(viewId);					
				}
				
				if ( !show ) {
					activePage.hideView(view);
				}
				
				return view;
			}
		} catch (Exception e) {
			AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
					AuthoringUIResources.errorDialog_title, 
					AuthoringUIResources.internalError_msg, 
					e);
		}
		return null;

	}
	
	public static boolean isViewInCurrentPerspective(String viewId) {		
		String perspectiveId = PerspectiveUtil.getActivePerspectiveId();
		return isViewInPerspective(viewId, perspectiveId);
	}
	
	/**
	 * Deciede whether the view definded in the perspective or not
	 * 
	 * @author david zhongwei
	 * @param viewId
	 * @param perpectiveId
	 * @return
	 */
	public static boolean isViewInPerspective(String viewId, String perspectiveId) {
		if (viewId == null || perspectiveId == null) {
			return false;
		}

		final String NAMESPACE = "org.eclipse.ui";//$NON-NLS-1$
		final String EXTENSIONPOINT_ID = "perspectiveExtensions";//$NON-NLS-1$
		final String TARGET_ID = "targetID";//$NON-NLS-1$
		final String VIEW = "view";//$NON-NLS-1$
		final String ID = "id";//$NON-NLS-1$
		final String VIEWSHORTCUT = "viewShortcut";//$NON-NLS-1$

		IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
		IExtensionPoint extensionPoint = null;
		if (extensionRegistry != null) {
			extensionPoint = extensionRegistry.getExtensionPoint(NAMESPACE, EXTENSIONPOINT_ID);
		}

		if (extensionPoint != null) {
			IExtension[] extensions = extensionPoint.getExtensions();
			for (int i = 0; i < extensions.length; i++) {
				IExtension extension = extensions[i];
				IConfigurationElement[] configElements = extension.getConfigurationElements();
				for (int j = 0; j < configElements.length; j++) {
					IConfigurationElement configElement = configElements[j];
					try {
						String id = configElement.getAttribute(TARGET_ID);
						if (perspectiveId.equals(id)) {

							// decide whether is defined in "view"
							IConfigurationElement[] configElementsForView = configElement.getChildren(VIEW);
							for (int k = 0; k < configElementsForView.length; k++) {
								IConfigurationElement configurationElement = configElementsForView[k];
								if (viewId.equals(configurationElement.getAttribute(ID))) {
									return true;
								}
							}

							// decide whether is defined in "viewShortcut"
							IConfigurationElement[] configElementsForViewShortcut = configElement
							        .getChildren(VIEWSHORTCUT);
							for (int l = 0; l < configElementsForViewShortcut.length; l++) {
								IConfigurationElement configurationElement = configElementsForViewShortcut[l];
								if (viewId.equals(configurationElement.getAttribute(ID))) {
									return true;
								}
							}

						}
					}
					catch (Exception e) {
						AuthoringUIPlugin.getDefault().getLogger().logError(e);
					}
				}
			}
		}
		return false;
	}
	
	public static void refreshView(AbstractBaseView configView) {
		Control ctrl = configView.getViewer().getControl();
		if (ctrl != null && !ctrl.isDisposed()) {
			Object input =  configView.getViewer().getInput();
			if (input instanceof EObject) {
				EObject eObject = (EObject) input;
				if (eObject.eIsProxy()) {
					configView.setInputForViewer(RefreshJob.getInstance()
							.resolve(eObject));
				} else {
					ISelection selection = configView.getViewer()
							.getSelection();
					configView.getViewer().refresh();
					restoreSelection(configView.getViewer(), selection);
				}
			}
		}

	}

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