//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.editors;

import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EventObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.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.runtime.CoreException;
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.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.authoring.ui.actions.LibraryValidateAction;
import org.eclipse.epf.authoring.ui.forms.ChecklistItemsPage;
import org.eclipse.epf.authoring.ui.forms.ContentElementGuidancePage;
import org.eclipse.epf.authoring.ui.forms.ContentPackageDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.CustomCategoryAssignPage;
import org.eclipse.epf.authoring.ui.forms.CustomCategoryDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.DisciplineDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.DisciplineGroupingDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.DisciplineGroupingDisciplinesPage;
import org.eclipse.epf.authoring.ui.forms.DisciplineReferenceWorkflowPage;
import org.eclipse.epf.authoring.ui.forms.DisciplineTasksPage;
import org.eclipse.epf.authoring.ui.forms.DomainDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.DomainWorkProductsPage;
import org.eclipse.epf.authoring.ui.forms.GuidanceDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.GuidanceWithAttachmentsDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.IExtensionFormPage;
import org.eclipse.epf.authoring.ui.forms.IRefreshable;
import org.eclipse.epf.authoring.ui.forms.MethodLibraryDescriptionFormPage;
import org.eclipse.epf.authoring.ui.forms.MethodPluginDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.PracticeDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.PracticeReferencesPage;
import org.eclipse.epf.authoring.ui.forms.RoleCategoriesPage;
import org.eclipse.epf.authoring.ui.forms.RoleDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.RoleSetDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.RoleSetGroupingDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.RoleSetGroupingRoleSets;
import org.eclipse.epf.authoring.ui.forms.RoleSetRolesPage;
import org.eclipse.epf.authoring.ui.forms.RoleWorkProductsPage;
import org.eclipse.epf.authoring.ui.forms.TaskCategoriesPage;
import org.eclipse.epf.authoring.ui.forms.TaskDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.TaskRolesPage;
import org.eclipse.epf.authoring.ui.forms.TaskStepsPage;
import org.eclipse.epf.authoring.ui.forms.TaskWorkProductsPage;
import org.eclipse.epf.authoring.ui.forms.ToolDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.ToolToolMentorsPage;
import org.eclipse.epf.authoring.ui.forms.WorkProductCategoriesPage;
import org.eclipse.epf.authoring.ui.forms.WorkProductDeliverablePartsPage;
import org.eclipse.epf.authoring.ui.forms.WorkProductDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.WorkProductTypeDescriptionPage;
import org.eclipse.epf.authoring.ui.forms.WorkProductTypeWorkProductsPage;
import org.eclipse.epf.authoring.ui.internal.MethodElementEditorErrorTickUpdater;
import org.eclipse.epf.authoring.ui.providers.MethodEditorPageProvider;
import org.eclipse.epf.authoring.ui.richtext.IMethodRichText;
import org.eclipse.epf.authoring.ui.util.LibraryValidationMarkerHelper;
import org.eclipse.epf.authoring.ui.views.ElementHTMLViewer;
import org.eclipse.epf.authoring.ui.views.LibraryView;
import org.eclipse.epf.authoring.ui.views.ViewHelper;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.command.ActionManager;
import org.eclipse.epf.library.edit.command.FullyRevertibleCommandStack;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.command.IResourceAwareCommand;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.persistence.ILibraryResource;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.util.ResourceUtil;
import org.eclipse.epf.library.xmi.XMILibraryUtil;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.persistence.MultiFileSaveUtil;
import org.eclipse.epf.persistence.MultiFileXMIResourceImpl;
import org.eclipse.epf.persistence.refresh.RefreshJob;
import org.eclipse.epf.persistence.util.PersistenceUtil;
import org.eclipse.epf.richtext.IRichText;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.services.Services;
import org.eclipse.epf.services.ILibraryPersister.FailSafeMethodLibraryPersister;
import org.eclipse.epf.uma.Checklist;
import org.eclipse.epf.uma.ContentPackage;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.Deliverable;
import org.eclipse.epf.uma.Discipline;
import org.eclipse.epf.uma.DisciplineGrouping;
import org.eclipse.epf.uma.Domain;
import org.eclipse.epf.uma.Guidance;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Practice;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleSet;
import org.eclipse.epf.uma.RoleSetGrouping;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.Tool;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.WorkProductType;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;

/**
 * The Method Element editor.
 * 
 * @author Shilpa Toraskar
 * @author Kelvin Low
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class MethodElementEditor extends AbstractBaseFormEditor implements
		ISelectionProvider {

	/**
	 * The editor ID.
	 */
	public static final String EDITOR_ID = MethodElementEditor.class.getName();

	protected int preview_page_index = -1;

	protected ElementHTMLViewer previewer = null;

	protected MethodElement elementObj = null;

	// The rich text control or editor whose content was last modified before
	// the Save or Save All button key is selected.
	protected IMethodRichText modifiedRichText = null;

	protected Adapter nameChangedListener = new AdapterImpl() {
		public void notifyChanged(org.eclipse.emf.common.notify.Notification msg) {
			switch (msg.getFeatureID(MethodElement.class)) {
			case UmaPackage.METHOD_ELEMENT__NAME:
				nameChanged();
				break;
			}
		}
	};

	protected Collection<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>();

	protected ISelection currentSelection = StructuredSelection.EMPTY;

	protected ActionManager actionMgr;

	private boolean dirty;

	private FailSafeMethodLibraryPersister persister;

	private Collection<Resource> resourcesToAdjustLocation = new HashSet<Resource>();

	private Collection<Object> widgetsToRestoreValue = new HashSet<Object>();

	private long changeTime = -1;

	public Object widgetToCheck;

	private Object currentFeatureEditor;

	private EStructuralFeature currentEditedFeature;

	protected ArrayList<Resource> removedResources = new ArrayList<Resource>();

	protected ArrayList<Resource> changedResources = new ArrayList<Resource>();
	
	protected MethodElementEditorErrorTickUpdater fMethodElementEditorErrorTickUpdater;
	
	/**
	 * Listens for workspace changes.
	 */
	protected IResourceChangeListener resourceChangeListener = new IResourceChangeListener() {
		public void resourceChanged(IResourceChangeEvent event) {
			System.out
					.println("MethodElementEditor.resourceChanged(): event = " + event); //$NON-NLS-1$

			if (elementObj.eIsProxy()) {
				return;
			}

			IResourceDelta delta = event.getDelta();
			try {
				class ResourceDeltaVisitor implements IResourceDeltaVisitor {
					protected Map URIToUsedResourceMap = getURIToUsedResourceMap();

					protected Collection<Resource> changedResources = new ArrayList<Resource>();

					protected Collection<Resource> removedResources = new ArrayList<Resource>();

					public boolean visit(IResourceDelta delta) {
						if (delta.getFlags() != IResourceDelta.MARKERS
								&& delta.getResource().getType() == IResource.FILE) {
							if ((delta.getKind() & (IResourceDelta.CHANGED | IResourceDelta.REMOVED)) != 0) {
								Resource resource = (Resource) URIToUsedResourceMap
										.get(URI.createFileURI(delta
												.getResource().getLocation()
												.toString()));
								if (resource != null) {
									if ((delta.getKind() & IResourceDelta.REMOVED) != 0) {
										removedResources.add(resource);
									} else {
										changedResources.add(resource);
									}
								}
							}
						}

						return true;
					}

					public Collection<Resource> getChangedResources() {
						return changedResources;
					}

					public Collection<Resource> getRemovedResources() {
						return removedResources;
					}
				}

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

				removedResources.addAll(visitor.getRemovedResources());
				if (!visitor.getRemovedResources().isEmpty() && !isDirty()) {
					getSite().getShell().getDisplay().asyncExec(new Runnable() {
						public void run() {
							MethodElementEditor.this.dispose();
						}
					});
				}

				changedResources.addAll(visitor.getChangedResources());
			} catch (CoreException e) {
				AuthoringUIPlugin.getDefault().getLogger().logError(e);
			}
		}
	};

	class ActivationListener implements IPartListener, IWindowListener {

		/** Cache of the active workbench part. */
		private IWorkbenchPart fActivePart;

		/** Indicates whether activation handling is currently be done. */
		private boolean fIsHandlingActivation = false;

		/**
		 * The part service.
		 * 
		 * @since 3.1
		 */
		private IPartService fPartService;

		/**
		 * Creates this activation listener.
		 * 
		 * @param partService
		 *            the part service on which to add the part listener
		 * @since 3.1
		 */
		public ActivationListener(IPartService partService) {
			fPartService = partService;
			fPartService.addPartListener(this);
			PlatformUI.getWorkbench().addWindowListener(this);
		}

		/**
		 * Disposes this activation listener.
		 * 
		 * @since 3.1
		 */
		public void dispose() {
			fPartService.removePartListener(this);
			PlatformUI.getWorkbench().removeWindowListener(this);
			fPartService = null;
		}

		/*
		 * @see IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partActivated(IWorkbenchPart part) {
			fActivePart = part;
			handleActivation();
		}

		/*
		 * @see IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partBroughtToTop(IWorkbenchPart part) {
		}

		/*
		 * @see IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partClosed(IWorkbenchPart part) {
		}

		/*
		 * @see IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partDeactivated(IWorkbenchPart part) {
			fActivePart = null;
		}

		/*
		 * @see IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart)
		 */
		public void partOpened(IWorkbenchPart part) {
			if (part == MethodElementEditor.this) {
				if (!isInputValid()) {
					AuthoringUIPlugin
							.getDefault()
							.getMsgDialog()
							.displayInfo(
									AuthoringUIResources.editors_MethodElementEditor_invalidEditorTitle, 
									AuthoringUIResources.editors_MethodElementEditor_invalidEditorMsg); 
					MethodElementEditor.this.close(false);
					return;
				}
				Collection usedResources = getUsedResources();
				if (ResourceUtil.hasOutOfSynch(usedResources)) {
					handleFileChanged(usedResources);
					return;
				}
				updateTimeStamps(usedResources);
			}
		}

		/**
		 * Handles the activation triggering a element state check in the
		 * editor.
		 */
		private void handleActivation() {
			if (fIsHandlingActivation || MethodElementEditor.this.disposed)
				return;

			if (fActivePart == MethodElementEditor.this) {
				fIsHandlingActivation = true;
				try {
					handleActivate(fActivePart);
				} finally {
					fIsHandlingActivation = false;
				}
			}
		}

		/*
		 * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow)
		 * @since 3.1
		 */
		public void windowActivated(IWorkbenchWindow window) {
			if (window == getEditorSite().getWorkbenchWindow()) {
				/*
				 * Workaround for problem described in
				 * http://dev.eclipse.org/bugs/show_bug.cgi?id=11731 Will be
				 * removed when SWT has solved the problem.
				 */
				window.getShell().getDisplay().asyncExec(new Runnable() {
					public void run() {
						handleActivation();
					}
				});
			}
		}

		/*
		 * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow)
		 * @since 3.1
		 */
		public void windowDeactivated(IWorkbenchWindow window) {
		}

		/*
		 * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow)
		 * @since 3.1
		 */
		public void windowClosed(IWorkbenchWindow window) {
		}

		/*
		 * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow)
		 * @since 3.1
		 */
		public void windowOpened(IWorkbenchWindow window) {
		}
	}

	private ActivationListener activationListener;

	private HashMap<Resource, Long> modificationTimeStampMap;

	private boolean checkFileChangedRequired = false;

	protected HashSet<Resource> lastUsedResources;

	private boolean disposed;

	private HashMap<Resource, Long> loadTimeStampMap;

	/**
	 * Creates a new instance.
	 */
	public MethodElementEditor() {
		super();
		
		fMethodElementEditorErrorTickUpdater= new MethodElementEditorErrorTickUpdater(this);

		actionMgr = new ActionManager() {

			protected FullyRevertibleCommandStack createCommandStack() {
				return new FullyRevertibleCommandStack(this) {
					public boolean doExecute(Command command) {
						// Check modify first.
						if (command instanceof IResourceAwareCommand) {
							Collection modifiedResources = ((IResourceAwareCommand) command)
									.getModifiedResources();
							if (modifiedResources != null
									&& !(modifiedResources.isEmpty())) {
								IStatus status = UserInteractionHelper
										.checkModify(modifiedResources,
												getSite().getShell());
								if (!status.isOK()) {
									MethodElementEditor.this
											.handleError(status);
									return false;
								}
							}
						} else {
							EObject owner = TngUtil.getOwner(command);
							if (owner != null) {
								IStatus status = TngUtil.checkEdit(owner,
										getSite().getShell());
								if (!status.isOK()) {
									AuthoringUIPlugin
											.getDefault()
											.getMsgDialog()
											.display(
													AuthoringUIResources.errorDialog_title, 
													AuthoringUIResources.editDialog_msgCannotEdit, 
													status);
									return false;
								}
							}
						}

						if (changeTime == -1) {
							changeTime = System.currentTimeMillis();
						}
						boolean ret = super.doExecute(command);
						if (!ret && changeTime != -1) {
							changeTime = -1;
						}
						return ret;
					}

				};
			}

			public boolean doAction(int actionType, EObject object,
					org.eclipse.emf.ecore.EStructuralFeature feature,
					Object value, int index) {
				IStatus status = TngUtil
						.checkEdit(object, getSite().getShell());
				if (status.isOK()) {
					return super.doAction(actionType, object, feature, value,
							index);
				} else {
					AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
							AuthoringUIResources.editDialog_title, 
							AuthoringUIResources.editDialog_msgCannotEdit, 
							status);
					return false;
				}
			}

			protected void save(Resource resource) {
				// don't save resource that is changed outside of this editor
				//
				if (changedResources.contains(resource)) {
					return;
				}
				
				boolean canSave;
				if(resource.getURI().isFile()) {
					File file = new File(resource.getURI().toFileString());
					canSave = file.lastModified() > changeTime;
				}
				else {
					canSave = true;
				}				
				try {
					if(canSave) {
						ILibraryPersister.FailSafeMethodLibraryPersister persister = getPersister();
						try {
							persister.save(resource);
							persister.commit();
						} catch (Exception e) {
							AuthoringUIPlugin.getDefault().getLogger()
							.logError(e);
							try {
								persister.rollback();
							} catch (Exception ex) {
								ViewHelper
								.reloadCurrentLibaryOnRollbackError(getEditorSite()
										.getShell());
							}
						}
					}
				} finally {
					changeTime = -1;
				}
			}
		};

		actionMgr.getCommandStack().addCommandStackListener(
				new CommandStackListener() {
					public void commandStackChanged(EventObject event) {
						firePropertyChange(IEditorPart.PROP_DIRTY);
					}
				});

		ILibraryManager manager = (ILibraryManager) LibraryService
				.getInstance().getCurrentLibraryManager();
		if (manager != null) {
			manager.startListeningTo(actionMgr.getCommandStack());
		}
	}

	private void nameChanged() {
		SafeUpdateController.asyncExec(new Runnable() {

			public void run() {
				setPartName();
				if (pages != null) {
					for (Iterator iter = pages.iterator(); iter.hasNext();) {
						Object page = iter.next();

						if (page instanceof IRefreshable) {
							((IRefreshable) page).refreshName(elementObj
									.getName());
						}
					}
				}
			}
			
		});
	}
	
	public IActionManager getActionManager() {
		return actionMgr;
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormEditor#init(IEditorSite,
	 *      IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		setSite(site);
		setInput(input);
		site.setSelectionProvider(this);
		activationListener = new ActivationListener(site.getWorkbenchWindow()
				.getPartService());

		ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
				TngAdapterFactory.INSTANCE
						.getNavigatorView_ComposedAdapterFactory());
		Image titleImage = labelProvider.getImage(elementObj);
		labelProvider.dispose();
		setTitleImage(titleImage);
	}

	/**
	 * 
	 * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
	 */
	protected void setInput(IEditorInput input) {
		super.setInput(input);

		// Get method element object from Editor input.
		//
		MethodElementEditorInput methodElementInput = (MethodElementEditorInput) input;
		elementObj = methodElementInput.getMethodElement();

		setPartName();
		elementObj.eAdapters().add(nameChangedListener);
		
		if (fMethodElementEditorErrorTickUpdater != null)
			fMethodElementEditorErrorTickUpdater.updateEditorImage(elementObj);

	}

	private void updateTimeStamps(Collection usedResources) {
		updateModificationTimeStampMap(usedResources);
		updateLoadTimeStampMap(usedResources);
	}

	private void updateModificationTimeStampMap(Collection usedResources) {
		if (modificationTimeStampMap == null) {
			modificationTimeStampMap = new HashMap<Resource, Long>();
		} else {
			modificationTimeStampMap.clear();
		}
		for (Iterator iter = usedResources.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			if(resource.getURI().isFile()) {
				modificationTimeStampMap.put(resource, new Long(new File(resource
						.getURI().toFileString()).lastModified()));
			}
		}
		checkFileChangedRequired = true;
	}

	private void updateLoadTimeStampMap(Collection usedResources) {
		if (loadTimeStampMap == null) {
			loadTimeStampMap = new HashMap<Resource, Long>();
		} else {
			loadTimeStampMap.clear();
		}
		for (Iterator iter = usedResources.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			if(resource instanceof ILibraryResource) {
				loadTimeStampMap.put(resource, new Long(((ILibraryResource)resource)
						.getLoadStamp()));
			}
		}
	}

	/**
	 * Checks if there is any resource in the given <code>usedResources</code>
	 * that has been reloaded since last update of load time stamps by this
	 * editor
	 * 
	 * @param usedResource
	 * @return
	 */
	private boolean checkReloaded(Collection usedResources) {
		ResourceSet resourceSet = getResourceSet(usedResources);
		boolean xmi = resourceSet instanceof ILibraryResourceSet 
			&& ((ILibraryResourceSet)resourceSet).getPersistenceType().equals(Services.XMI_PERSISTENCE_TYPE);
		for (Iterator iter = usedResources.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			if(resource instanceof ILibraryResource) {
				Long oldTime = (Long) loadTimeStampMap.get(resource);
				long currentTime = ((ILibraryResource)resource).getLoadStamp();
				if (oldTime != null && oldTime.longValue() != currentTime) {
					if(xmi) {
						IResource wsRes = FileManager.getResourceForLocation(resource
								.getURI().toFileString());
						if (wsRes != null) {
							return true;
						}
					}
					else {
						return true;
					}
				}
			}
		}
		return false;
	}
	
	private static ResourceSet getResourceSet(Collection resources) {
		ResourceSet resourceSet = null;
		for (Iterator iter = resources.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			resourceSet = resource.getResourceSet();
			if (resourceSet != null) {
				break;
			}
		}
		return resourceSet;
	}

	private boolean checkFileChanged(Collection usedResources) {
		// check resource set type and continue to check for changed file if the
		// type is XMI
		//
		ResourceSet resourceSet = getResourceSet(usedResources);
		if (resourceSet instanceof ILibraryResourceSet
				&& ((ILibraryResourceSet) resourceSet).getPersistenceType().equals(Services.XMI_PERSISTENCE_TYPE)) {
			for (Iterator iter = usedResources.iterator(); iter.hasNext();) {
				Resource resource = (Resource) iter.next();
				String filePath = FileManager.toFileString(resource.getURI(), resourceSet.getURIConverter());
				Long oldTime = (Long) modificationTimeStampMap.get(resource);
				boolean checkForSynch = false;
				if (oldTime == null) {
					// editor is being open or new saved file
					//
					checkForSynch = MultiFileSaveUtil
							.checkSynchronized(resource) != 1;
				} else {
					File file = new File(filePath);
					if (!file.exists()) {
						return true;
					}
					long currentTime = file.lastModified();
					if (MultiFileSaveUtil
							.same(currentTime, oldTime.longValue())) {
						// some team providers changed the timestamp of last
						// file
						// modification by removing second fraction
						// even the file was not changed
						//
						modificationTimeStampMap.put(resource, new Long(
								currentTime));
					} else {
						checkForSynch = oldTime.longValue() != currentTime;
					}
				}

				if (checkForSynch) {
					IResource wsRes = FileManager
							.getResourceForLocation(filePath);
					if (wsRes != null
							&& !wsRes.isSynchronized(IResource.DEPTH_ZERO)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	protected boolean promptReloadFiles() {
		String title = AuthoringUIResources.editor_error_activated_outofsync_title;
		String msg = AuthoringUIResources.editor_error_activated_outofsync_message;
		return AuthoringUIPlugin.getDefault().getMsgDialog().displayPrompt(
				title, msg);
	}

	private boolean handleFileChanged(final Collection usedResources) {
		boolean ret = promptReloadFiles();
		if (ret) {
			IRunnableWithProgress runnable = new IRunnableWithProgress() {

				public void run(IProgressMonitor monitor)
						throws InvocationTargetException, InterruptedException {
					monitor.beginTask("", 10); //$NON-NLS-1$
					monitor.subTask(AuthoringUIResources.refresh_text); 
					monitor.worked(1);
					try {

						Collection<Resource> removedResources = new ArrayList<Resource>();
						for (Iterator iter = usedResources.iterator(); iter
								.hasNext();) {
							Resource resource = (Resource) iter.next();
							if (!new File(resource.getURI().toFileString())
									.exists()) {
								removedResources.add(resource);
							}
						}
						Collection changedResources = ResourceUtil
								.getOutOfSynchResources(usedResources);
						monitor.worked(2);

						// unload the removed resources
						//
						for (Iterator iter = removedResources.iterator(); iter
								.hasNext();) {
							MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) iter
									.next();
							try {
								resource.unloadWithoutRemove();
							} catch (Exception e) {
								CommonPlugin.INSTANCE.log(e);
							}
						}
						monitor.worked(2);

						// Reload the changed resources.
						ILibraryManager manager = (ILibraryManager) LibraryService
								.getInstance().getCurrentLibraryManager();
						if (manager != null) {
							Collection<Resource> reloadedResources = manager
									.reloadResources(changedResources);
							if (!reloadedResources.isEmpty()) {
								RefreshJob.getInstance()
										.getReloadedBeforeRefreshResources()
										.addAll(reloadedResources);
							}

							if (!removedResources.isEmpty()
									|| !reloadedResources.isEmpty()) {
								// save changed resources before refresh so
								// action
								// manager will not try to save these changed
								// resources
								//
								MethodElementEditor.this.changedResources
										.addAll(reloadedResources);
								MethodElementEditor.this.lastUsedResources
										.removeAll(removedResources);
								refresh(true);
								MethodElementEditor.this.changedResources
										.clear();
							}
						}
						monitor.worked(4);

						// refresh out-of-synch resources
						//
						for (Iterator iter = changedResources.iterator(); iter
								.hasNext();) {
							FileManager.getInstance().refresh(
									(Resource) iter.next());
						}
						monitor.worked(1);
					} finally {
						monitor.done();
					}
				}

			};

			try {
				getSite()
						.getWorkbenchWindow()
						.getWorkbench()
						.getProgressService()
						.runInUI(
								new ProgressMonitorDialog(getSite().getShell()),
								runnable, null);
			} catch (Exception e) {
				AuthoringUIPlugin.getDefault().getLogger().logError(e);
				String title = AuthoringUIResources.ProcessEditor_refreshErrorTitle; 
				AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
						title, e.toString(), e);
			}
		} else {
			checkFileChangedRequired = false;
		}
		return ret;
	}

	public void setPartName() {
		String partName = elementObj.getName();
		if (partName == null) {
			partName = ""; //$NON-NLS-1$
		}
		setPartName(partName);
	}

	/**
	 * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
	 */
	public void addSelectionChangedListener(ISelectionChangedListener listener) {
		selectionChangedListeners.add(listener);
	}

	/**
	 * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
	 */
	public void removeSelectionChangedListener(
			ISelectionChangedListener listener) {
		selectionChangedListeners.remove(listener);
	}

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

	/**
	 * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection)
	 */
	public void setSelection(ISelection selection) {
		currentSelection = selection;

		for (Iterator listeners = new ArrayList<ISelectionChangedListener>(selectionChangedListeners)
				.iterator(); listeners.hasNext();) {
			ISelectionChangedListener listener = (ISelectionChangedListener) listeners
					.next();
			listener
					.selectionChanged(new SelectionChangedEvent(this, selection));
		}
	}

	/**
	 * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
	 */
	protected void addPages() {
		try {
			if (elementObj instanceof MethodLibrary) {
				addPage(new MethodLibraryDescriptionFormPage(this));
			} else if (elementObj instanceof MethodPlugin) {
				addPage(new MethodPluginDescriptionPage(this));
			} else if (elementObj instanceof ContentPackage) {
				addPage(new ContentPackageDescriptionPage(this));
			} else if (elementObj instanceof Role) {
				addPage(new RoleDescriptionPage(this));
				addPage(new RoleWorkProductsPage(this));
				addPage(new ContentElementGuidancePage(this));
				addPage(new RoleCategoriesPage(this));
			} else if (elementObj instanceof Task) {
				addPage(new TaskDescriptionPage(this));
				addPage(new TaskStepsPage(this));
				addPage(new TaskRolesPage(this));
				addPage(new TaskWorkProductsPage(this));
				addPage(new ContentElementGuidancePage(this));
				addPage(new TaskCategoriesPage(this));
			} else if (elementObj instanceof WorkProduct) {
				addPage(new WorkProductDescriptionPage(this));
				if (elementObj instanceof Deliverable) {
					addPage(new WorkProductDeliverablePartsPage(this));
				}
				addPage(new ContentElementGuidancePage(this));
				addPage(new WorkProductCategoriesPage(this));
			} else if (elementObj instanceof Guidance) {
				if (TngUtil.isAllowedAttachments(elementObj)) {
					addPage(new GuidanceWithAttachmentsDescriptionPage(this));
				} else if (elementObj instanceof Practice) {
					addPage(new PracticeDescriptionPage(this));
					addPage(new PracticeReferencesPage(this));
				} else if (elementObj instanceof Checklist) {
					addPage(new GuidanceDescriptionPage(this));
					addPage(new ChecklistItemsPage(this));
				} else {
					addPage(new GuidanceDescriptionPage(this));
				}
				if (!(elementObj instanceof Practice))
					addPage(new ContentElementGuidancePage(this));
			} else if (elementObj instanceof Discipline) {
				addPage(new DisciplineDescriptionPage(this));
				addPage(new DisciplineTasksPage(this));
				addPage(new DisciplineReferenceWorkflowPage(this));
				addPage(new ContentElementGuidancePage(this));
			} else if (elementObj instanceof DisciplineGrouping) {
				addPage(new DisciplineGroupingDescriptionPage(this));
				addPage(new DisciplineGroupingDisciplinesPage(this));
			} else if (elementObj instanceof Domain) {
				addPage(new DomainDescriptionPage(this));
				addPage(new DomainWorkProductsPage(this));
				addPage(new ContentElementGuidancePage(this));
			} else if (elementObj instanceof WorkProductType) {
				addPage(new WorkProductTypeDescriptionPage(this));
				addPage(new WorkProductTypeWorkProductsPage(this));
				addPage(new ContentElementGuidancePage(this));
			} else if (elementObj instanceof RoleSet) {
				addPage(new RoleSetDescriptionPage(this));
				addPage(new RoleSetRolesPage(this));
				addPage(new ContentElementGuidancePage(this));
			} else if (elementObj instanceof RoleSetGrouping) {
				addPage(new RoleSetGroupingDescriptionPage(this));
				addPage(new RoleSetGroupingRoleSets(this));
			} else if (elementObj instanceof Tool) {
				addPage(new ToolDescriptionPage(this));
				addPage(new ToolToolMentorsPage(this));
				addPage(new ContentElementGuidancePage(this));
			} else if (elementObj instanceof CustomCategory) {
				addPage(new CustomCategoryDescriptionPage(this));
				addPage(new CustomCategoryAssignPage(this));
			}

			setPartName(elementObj.getName());

			if (!(elementObj instanceof ContentPackage || elementObj instanceof MethodPlugin))
				createPreviewPage();

			if (elementObj instanceof Task) {
				// check for extenstion point and add the page if there
				List pageProviders = MethodEditorPageProvider.getInstance()
						.getPageProviders();

				if (pageProviders != null && pageProviders.size() > 0) {
					try {
						for (int i = 0; i < pageProviders.size(); i++) {
							Object page = pageProviders.get(i);
							if (page instanceof IExtensionFormPage) {
								IExtensionFormPage formPage = (IExtensionFormPage) page;
								formPage.setEditor(this);
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		} catch (Throwable t) {
			t.printStackTrace();
			dispose();
			throw (SWTError) t;
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.editors.AbstractBaseFormEditor#dispose()
	 */
	public void dispose() {
		try {
			// ResourcesPlugin.getWorkspace().removeResourceChangeListener(
			// resourceChangeListener);

			if (activationListener != null) {
				activationListener.dispose();
			}

			modifiedRichText = null;

			if (fMethodElementEditorErrorTickUpdater != null) {
				fMethodElementEditorErrorTickUpdater.dispose();
				fMethodElementEditorErrorTickUpdater= null;
			}
			
			ILibraryManager manager = (ILibraryManager) LibraryService
					.getInstance().getCurrentLibraryManager();
			if (manager != null) {
				manager.stopListeningTo(actionMgr.getCommandStack());
			}

			if (isDirty()) {
				actionMgr.undoAll();
			}
			actionMgr.dispose();
			elementObj.eAdapters().remove(nameChangedListener);
		} finally {
			super.dispose();
			disposed = true;
		}
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.editors.AbstractBaseFormEditor#isDirty()
	 */
	public boolean isDirty() {
		if (dirty)
			return true;
		dirty = actionMgr.isSaveNeeded();
		return dirty;
	}

	public FailSafeMethodLibraryPersister getPersister() {
		if (persister == null) {
			persister = LibraryServiceUtil.getCurrentPersister().getFailSafePersister();
		}
		return persister;
	}

	protected Collection<Resource> getModifiedResources() {
		return actionMgr.getModifiedResources();
	}

	/**
	 * Set modified rich text field
	 * @param modifiedRichText
	 */
	public void setModifiedRichText(IMethodRichText modifiedRichText) {
		this.modifiedRichText = modifiedRichText;
	}

	/**
	 * Save modified rich text 
	 * @param richText
	 */
	public void saveModifiedRichText(IMethodRichText richText) {
		if (richText != null && !richText.isDisposed()
				&& richText.getModified()) {
			EObject modalObject = richText.getModalObject();
			EStructuralFeature modalObjectFeature = richText
					.getModalObjectFeature();
			if (modalObject != null && modalObjectFeature != null) {
				Object oldContent = modalObject.eGet(modalObjectFeature);
				if (!mustRestoreValue(richText, oldContent)) {
					Object newContent = richText.getText();
					if (!newContent.equals(oldContent)) {
						actionMgr.doAction(IActionManager.SET, modalObject,
								modalObjectFeature, newContent, -1);
					}
				}
			}
		}
	}

	/**
	 * Save last modified rich text 
	 */
	public void saveModifiedRichText() {
		saveModifiedRichText(modifiedRichText);
	}
	
	protected LibraryValidateAction createValidateResourceAction() {
		return new LibraryValidateAction(false) {
			/* (non-Javadoc)
			 * @see org.eclipse.epf.authoring.ui.actions.LibraryValidateAction#refreshViews()
			 */
			protected void refreshViews() {
				LibraryView.getView().refreshViews();
			}
		};
	}
	
	public boolean validateResources(Collection modifiedResources) {
		ArrayList<EObject> elements = new ArrayList<EObject>();
		for (Iterator iter = modifiedResources.iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			elements.addAll(resource.getContents());
		}
		LibraryValidateAction validateAction = createValidateResourceAction();
		validateAction.updateSelection(new StructuredSelection(elements));
		validateAction.run();
		return validateAction.isSuccessful();
	}

	/**
	 * @see org.eclipse.epf.authoring.ui.editors.AbstractBaseFormEditor#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void doSave(IProgressMonitor monitor) {
		if (DEBUG) {
			System.out
					.println("MethodElementEditor.doSave: saving changes to method library"); //$NON-NLS-1$
		}

		saveModifiedRichText(modifiedRichText);

		getPersister();
		try {
			// check for modifiable
			//
			Collection<Resource> modifiedResources = getModifiedResources();

			// update version info in library resource if needed by adding
			// library resource to collection
			// of modified resources
			//
			HashSet<Resource> resourcesToUpdateVersionInfo = new HashSet<Resource>();
			if (!modifiedResources.isEmpty()) {
				for (Iterator iter = modifiedResources.iterator(); iter
						.hasNext();) {
					Resource resource = (Resource) iter.next();
					MethodElement me = PersistenceUtil
							.getMethodElement(resource);
					if (me != null) {
						MethodLibrary lib = UmaUtil.getMethodLibrary(me);
						if (lib != null) {
							Resource libResource = lib.eResource();
							if (libResource != null
									&& !modifiedResources.contains(libResource)
									&& !resourcesToUpdateVersionInfo
											.contains(libResource)
									&& PersistenceUtil
											.checkToolVersion(libResource) != 0) {
								resourcesToUpdateVersionInfo.add(libResource);
							}
						}
					}
				}
				modifiedResources.addAll(resourcesToUpdateVersionInfo);
			}

			IStatus status = UserInteractionHelper.checkModify(
					modifiedResources, getSite().getShell());
			if (!status.isOK()) {
				handleError(status);
				return;
			}

			// check for out-of-synch
			//
			if (checkFileChanged(modifiedResources)) {
				String title = LibraryEditResources.update_outofsynch_title;
				String msg = LibraryEditResources.update_outofsynch_msg;
				if (!AuthoringUIPlugin.getDefault().getMsgDialog()
						.displayPrompt(title, msg)) {
					return;
				}
			}

			// flag the resources to update version info as modified so they
			// will be saved
			//
			if (!resourcesToUpdateVersionInfo.isEmpty()) {
				for (Iterator iter = resourcesToUpdateVersionInfo.iterator(); iter
						.hasNext();) {
					Resource resource = (Resource) iter.next();
					resource.setModified(true);
				}
			}
			
			if(isValidateResourcesBeforeSaveRequired()) {
				// validate
				//
				if(!validateResources(modifiedResources)) {
					return;
				}
			}
			else {
				// no validation before save
				// remove all validation errors markers associated with current method element
				//
				LibraryValidationMarkerHelper.INSTANCE.deleteMarkers(elementObj);
			}

			// Save.
			//
			for (Iterator iter = modifiedResources.iterator(); iter.hasNext();) {
				Resource resource = (Resource) iter.next();
				try {
					persister.save(resource);
				} catch (Exception e) {
					String title = AuthoringUIResources.editors_MethodElementEditor_saveErrorTitle; 
					String msg = AuthoringUIResources.editors_MethodElementEditor_saveErrorMessage1; 
					String reason = e.getMessage() == null ? AuthoringUIResources.editors_MethodElementEditor_saveErrorReason1
							: e.getMessage(); 
					AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
							title, msg, reason, e);
					throw e;
				}
			}

			try {
				persister.commit();
				dirty = false;
				actionMgr.saveIsDone();
				changeTime = -1;

				updateTimeStamps(getUsedResources());
			} catch (Exception e) {
				String reason = e.getMessage();
				if (StrUtil.isBlank(reason)) {
					reason = AuthoringUIResources.editors_MethodElementEditor_saveErrorReason2; 
				}
				StringWriter details = new StringWriter();
				e.printStackTrace(new PrintWriter(details));
				String title = AuthoringUIResources.editors_MethodElementEditor_saveErrorTitle; 
				String message = AuthoringUIResources.editors_MethodElementEditor_saveErrorMessage2; 
				AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
						title, message, reason, details.toString(), e);
				throw e;
			}

			// Rename.
			if (!resourcesToAdjustLocation.isEmpty()) {
				try {
					persister.adjustLocation(resourcesToAdjustLocation);
				} catch (Exception e) {
					String title = AuthoringUIResources.editors_MethodElementEditor_renameErrorTitle; 
					String template = AuthoringUIResources.editors_MethodElementEditor_renameErrorMessage1; 
					StringBuffer fileList = new StringBuffer();
					for (Iterator iter = resourcesToAdjustLocation.iterator(); iter
							.hasNext();) {
						Resource resource = (Resource) iter.next();
						Object obj = FileManager.toFileString(resource.getURI());
						if(obj == null) {
							obj = resource;
						}
						fileList.append(obj).append(", "); //$NON-NLS-1$
					}
					String msg = MessageFormat.format(template,
							new Object[] { fileList });
					String reason = e.getMessage() == null ? AuthoringUIResources.editors_MethodElementEditor_saveErrorReason1
							: e.getMessage(); 
					AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
							title, msg, reason, e);
					throw e;
				}

				try {
					persister.commit();
				} catch (Exception e) {
					String reason = e.getMessage();
					if (StrUtil.isBlank(reason)) {
						reason = AuthoringUIResources.editors_MethodElementEditor_saveErrorReason2; 
					}
					StringWriter details = new StringWriter();
					e.printStackTrace(new PrintWriter(details));
					String title = AuthoringUIResources.editors_MethodElementEditor_renameErrorTitle; 
					String message = AuthoringUIResources.editors_MethodElementEditor_saveErrorMessage2; 
					AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
							title, message, reason, details.toString(), e);
					throw e;
				}

				resourcesToAdjustLocation.clear();
			}
		} catch (Exception e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
			try {
				persister.rollback();
			} catch (Exception ex) {
				AuthoringUIPlugin.getDefault().getLogger().logError(ex);
				ViewHelper.reloadCurrentLibaryOnRollbackError(getSite()
						.getShell());
			}
		}
	}

	/**
	 * @return
	 */
	protected boolean isValidateResourcesBeforeSaveRequired() {
		return false;
	}

	protected void saveResource(Resource resource) {
		if (resource != null && resource.isModified()) {
			try {
				getPersister().save(resource);
			} catch (Exception e) {
				String title = AuthoringUIResources.editors_MethodElementEditor_saveErrorTitle; 
				String template = AuthoringUIResources.editors_MethodElementEditor_saveErrorMessage1; 
				String msg = MessageFormat.format(template,
						new Object[] { resource.getURI().toFileString() });
				String reason = e.getMessage() == null ? AuthoringUIResources.editors_MethodElementEditor_saveErrorReason1
						: e.getMessage(); 
				AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
						title, msg, reason, e);
			}
		}
	}

	protected void createPreviewPage() {
		Composite parent = getContainer();
		Composite previewComposite = new Composite(parent, SWT.NONE);
		previewComposite.setLayout(new GridLayout());

		PreviewPage page = new PreviewPage(previewComposite);
		previewer = page.getPreviewViewer();

		preview_page_index = addPage(previewComposite);
		setPageText(preview_page_index, AuthoringUIResources.previewPage_title); 
	}

	/**
	 * Override this method to listen to the tab change.
	 */
	protected void pageChange(int newPageIndex) {
		super.pageChange(newPageIndex);

		if (preview_page_index == newPageIndex && previewer != null) {
			// Use the default layout manager.
			previewer.setLayoutManager(null);
			previewer.showElementContent(elementObj);
		}
	}

	private void setDirty() {
		dirty = true;
		firePropertyChange(PROP_DIRTY);
	}

	/**
	 * Restore value of the control
	 * @param control
	 * @param value
	 * @return
	 * 		boolean value to indicate whether control was restored or not
	 */
	public boolean mustRestoreValue(Object control, Object value) {
		if (widgetToCheck == control) {
			// the control is currently being checked for editable, but there is
			// still focus lost
			// event is being sent out even the check is not completed yet.
			// return true so the focusLost() will not make any change to the
			// control.
			//
			return true;
		}

		Object editControl = control;
		if (editControl instanceof MethodRichTextEditor) {
			editControl = ((MethodRichTextEditor) control).getRichTextControl();
		}
		boolean restore = widgetsToRestoreValue.contains(editControl);
		if (!restore) {
			synchronized (widgetsToRestoreValue) {
				restore = widgetsToRestoreValue.contains(editControl);
			}
		}
		if (restore) {
			if (editControl instanceof Text) {
				Text text = ((Text) editControl);
				text.setText((String) value);
			} else if (editControl instanceof IMethodRichText) {
				IMethodRichText richText = (IMethodRichText) editControl;
				richText.setText((String) value);
			}
			widgetsToRestoreValue.remove(editControl);
		}
		return restore;
	}

	/**
	 * Modify Listener 
	 *
	 */
	public class ModifyListener implements
			org.eclipse.swt.events.ModifyListener {

		private EObject element;

		private boolean checkContainerResource;

		private boolean disabled = false;

		/**
		 * Creates a new instance.
		 */
		public ModifyListener(EObject element, boolean checkContainer) {
			super();
			checkContainerResource = checkContainer;
			this.element = element;
		}

		private void restoreText(Object control, String txt) {
			boolean old = disabled;
			try {
				disabled = true;
				Object editControl = control;
				if (editControl instanceof MethodRichTextEditor) {
					editControl = ((MethodRichTextEditor) control)
							.getRichTextControl();
				}
				if (editControl instanceof Text) {
					Text text = ((Text) editControl);
					text.setText(txt);
				} else if (editControl instanceof IMethodRichText) {
					IMethodRichText richText = (IMethodRichText) editControl;
					richText.setText(txt);
				}
			} finally {
				disabled = old;
			}
		}

		private boolean checkEdit(EObject element, Object control,
				boolean checkContainerResource) {
			// keep a reference to the current widget so mustRestoreValue() can
			// use it to check
			// whether a focus lost event is triggered during a checkEdit.
			// mustRestoreValue() then
			// returns true so focusLost() will not try to make change to the
			// value bound to the widget
			//
			widgetToCheck = control;
			try {
				if (DEBUG) {
					System.out
							.println("MethodElementEditor.checkEdit: enter, control=" + control); //$NON-NLS-1$
				}
				IStatus status = null;
				if (widgetsToRestoreValue.contains(control)) {
					if (DEBUG) {
						System.out
								.println("MethodElementEditor.checkEdit: widget found in widgetsToRestoreValue, exit"); //$NON-NLS-1$
					}
					return false;
				}

				synchronized (widgetsToRestoreValue) {
					if (widgetsToRestoreValue.contains(control)) {
						if (DEBUG) {
							System.out
									.println("MethodElementEditor.checkEdit: widget found in widgetsToRestoreValue, exit"); //$NON-NLS-1$
						}
						return false;
					}

					status = TngUtil.checkEdit(element, getSite().getShell());

					if (!status.isOK()) {
						if (control instanceof IRichText) {
							((IRichText) control).restoreText();
						} else {
							if (control == currentFeatureEditor) {
								restoreText(control, (String) element
										.eGet(currentEditedFeature));
							} else {
								// Add the control to the list of widgets whose
								// value needs
								// to be restored to the original one..
								widgetsToRestoreValue.add(control);
								if (DEBUG) {
									System.out
											.println("MethodElementEditor.checkEdit: added widget to widgetsToRestoreValue"); //$NON-NLS-1$
								}
							}
						}
					} else if (checkContainerResource) {
						if (element.eContainer() != null
								&& element.eContainer().eResource() != element
										.eResource()) {
							status = TngUtil.checkEdit(element.eContainer(),
									getSite().getShell());
							if (!status.isOK()) {
								// // Add the control to the list of widgets
								// whose value
								// // needs to be restored to the original one.
								// if (debug) {
								// System.out
								// .println("MethodElementEditor.checkEdit:
								// added widget to widgetsToRestoreValue");
								// //$NON-NLS-1$
								// }
								if (control instanceof IRichText) {
									((IRichText) control).restoreText();
								} else {
									if (control == currentFeatureEditor) {
										restoreText(control, (String) element
												.eGet(currentEditedFeature));
									} else {
										widgetsToRestoreValue.add(control);
									}
								}
							}
						}
					}
				}

				if (status != null && !status.isOK()) {
					AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
							AuthoringUIResources.editDialog_title, 
							AuthoringUIResources.editDialog_msgCannotEdit, 
							status);
					return false;
				}

				return true;
			} finally {
				// clear the reference when the check is done
				//
				widgetToCheck = null;
			}
		}

		/**
		 * @see org.eclipse.swt.events.ModifyListener#modifyText(ModifyEvent)
		 */
		public void modifyText(ModifyEvent e) {
			if (DEBUG) {
				System.out
						.println("MethodElementEditor.ModifyListener.modifyText: enter, disabled=" + disabled); //$NON-NLS-1$
			}
			if (!disabled && element != null) {
				if (e.widget == null) {
					return;
				}

				Object widget = e.widget;
				if (widget instanceof Browser) {
					widget = ((Browser) widget)
							.getData(IMethodRichText.PROPERTY_NAME);
					if (widget == null) {
						widget = e.widget;
					}
				}
				if (DEBUG) {
					System.out
							.println("MethodElementEditor.ModifyListener.modifyText: widget=" + widget); //$NON-NLS-1$
				}

				if (widgetsToRestoreValue.contains(widget)) {
					if (DEBUG) {
						System.out
								.println("MethodElementEditor.ModifyListener.modifyText: widget found in widgetsToRestoreValue, exit"); //$NON-NLS-1$
					}
					return;
				}

				if (!checkEdit(element, widget, checkContainerResource)) {
					if (DEBUG) {
						System.out
								.println("MethodElementEditor.ModifyListener.modifyText: checkEdit failed, exit"); //$NON-NLS-1$
					}
					return;
				}

				if (widget instanceof IMethodRichText) {
					IMethodRichText richText = (IMethodRichText) widget;
					setModifiedRichText(richText);
					if (DEBUG) {
						System.out
								.println("MethodElementEditor.ModifyListener.modifyText: adding to modifiedRichTexts list"); //$NON-NLS-1$
					}
				}

				if (DEBUG) {
					System.out
							.println("MethodElementEditor.ModifyListener.modifyText: marking editor as dirty"); //$NON-NLS-1$
				}
				setDirty();
			}

			if (DEBUG) {
				System.out
						.println("MethodElementEditor.ModifyListener.modifyText: exit"); //$NON-NLS-1$
			}
		}

		/**
		 * Sets the underlying model element.
		 * 
		 * @param element
		 *            A method element.
		 */
		public void setElement(EObject element) {
			this.element = element;
		}

		/**
		 * Sets the disable flag.
		 * 
		 * @param disabled
		 *            If <code>true</code>, ignore the modify events.
		 */
		public void setDisable(boolean disabled) {
			this.disabled = disabled;
		}
	}

	/**
	 * Creates an new instance of ModifyListener that supports team and CM
	 * integration Any control in the editor, if it needs a ModifyListener, must
	 * use one created by this method
	 * 
	 * @param eObj
	 * 
	 * @return
	 */
	public ModifyListener createModifyListener(EObject eObj) {
		return createModifyListener(eObj, false);
	}

	/**
	 * Creates an new instance of ModifyListener that supports team and CM
	 * integration Any control in the editor, if it needs a ModifyListener, must
	 * use one created by this method
	 * 
	 * @param eObj
	 * @param checkContainer
	 *            if true will check the container of the given object for
	 *            editable as well when checking the given object for editable
	 * 
	 * @return
	 * 		Modify Listener
	 */
	public ModifyListener createModifyListener(EObject eObj,
			boolean checkContainer) {
		return new ModifyListener(eObj, checkContainer);
	}

	/**
	 * Sets the specified control to be the current editor of the specified
	 * feature.
	 * 
	 * @param control
	 * @param feature
	 */
	public void setCurrentFeatureEditor(Object control,
			EStructuralFeature feature) {
		currentFeatureEditor = control;
		currentEditedFeature = feature;
	}

	protected void monitorChange() {
		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IExtensionPoint point = registry
				.getExtensionPoint("org.eclipse.core.resources.refreshProviders"); //$NON-NLS-1$
		if (point == null)
			return;
		IExtension[] extensions = point.getExtensions();
		for (int i = 0; i < extensions.length; i++) {
			IExtension extension = extensions[i];
			if (DEBUG) {
				System.out
						.println("extension: UID=" + extension.getUniqueIdentifier() + ", " + extension); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	/**
	 * Add resource to adjust location
	 * @param resource
	 */
	public void addResourceToAdjustLocation(Resource resource) {
		resourcesToAdjustLocation.add(resource);
	}

	protected List getUsedFeatures() {
		return elementObj.eClass().getEAllStructuralFeatures();
	}

	/**
	 * Gets resources that are currently being used by this editors
	 * 
	 * @return
	 * 		list of used resources
	 */
	public Collection getUsedResources() {
		HashSet<Resource> resources = new HashSet<Resource>();
		Resource resource = elementObj.eResource();
		if (resource != null) {
			resources.add(resource);
		}
		List allFeatures = getUsedFeatures();
		for (int i = allFeatures.size() - 1; i > -1; i--) {
			EStructuralFeature feature = (EStructuralFeature) allFeatures
					.get(i);
			if (feature.isMany()) {
				List values = (List) elementObj.eGet(feature);
				for (int j = values.size() - 1; j > -1; j--) {
					EObject value = (EObject) values.get(j);
					if (value.eResource() != null) {
						resources.add(value.eResource());
					}
				}
			} else {
				Object value = elementObj.eGet(feature);
				if (value instanceof EObject
						&& (resource = ((EObject) value).eResource()) != null) {
					resources.add(resource);
				}
			}
		}
		lastUsedResources = resources;
		return resources;
	}

	private Map getURIToUsedResourceMap() {
		HashMap<URI, Resource> map = new HashMap<URI, Resource>();
		for (Iterator iter = getUsedResources().iterator(); iter.hasNext();) {
			Resource resource = (Resource) iter.next();
			map.put(resource.getURI(), resource);
		}
		return map;
	}

	protected void handleError(IStatus status) {
		AuthoringUIPlugin.getDefault().getMsgDialog().display(
				AuthoringUIResources.errorDialog_title, 
				AuthoringUIResources.editDialog_msgCannotEdit, 
				status);
	}

	/**
	 * Handles the activation of this view.
	 */
	protected void handleActivate(IWorkbenchPart part) {
		// TODO: Review implementation.
		// Make sure that the method library open is not closed.
		XMILibraryUtil.openMethodLibraryProject(LibraryService.getInstance()
				.getCurrentMethodLibrary(), getEditorSite().getActionBars()
				.getStatusLineManager().getProgressMonitor());

		if (checkFileChangedRequired) {
			Collection usedResources = getUsedResources();
			if (checkFileChanged(usedResources)) {
				handleFileChanged(usedResources);
			}
		}
	}

	/**
	 * Displays a dialog that asks if conflicting changes should be discarded.
	 */
	protected boolean handleDirtyConflict() {
		String title = AuthoringUIResources._UI_FileConflict_label;
		String msg = AuthoringUIResources._WARN_FileConflict;
		return AuthoringUIPlugin.getDefault().getMsgDialog().displayPrompt(
				title, msg);
	}

	/**
	 * Handles changed resources when this view is activated.
	 */
	protected void handleChangedResources() {
		if ((elementObj.eIsProxy() || !changedResources.isEmpty())
				&& (!isDirty() || handleDirtyConflict())) {
			// editingDomain.getCommandStack().flush();

			// for (Iterator i = changedResources.iterator(); i.hasNext();) {
			// Resource resource = (Resource) i.next();
			// if (resource.isLoaded()) {
			// if(resource instanceof MultiFileXMIResourceImpl) {
			// try {
			// ((MultiFileXMIResourceImpl)resource).reload(null);
			// } catch (IOException e) {
			// AuthoringUIPlugin.getDefault().getLogger().logError(e);
			// }
			// }
			// else {
			// resource.unload();
			// try {
			// resource.load(Collections.EMPTY_MAP);
			// } catch (IOException e) {
			// AuthoringUIPlugin.getDefault().getLogger().logError(e);
			// }
			// }
			// }
			// }
		}
	}

	/**
	 * Checks whether input is valid or not
	 * @return boolean value
	 */
	public boolean isInputValid() {
		if (elementObj != null && elementObj.eIsProxy()) {
			EObject e = RefreshJob.getInstance().resolve(elementObj);
			return (e instanceof MethodElement && !e.eIsProxy() && UmaUtil
					.getMethodLibrary(e) == LibraryService.getInstance()
					.getCurrentMethodLibrary());
		}
		return true;
	}

	protected void updatePages() {
		while (getPageCount() > 0) {
			removePage(0);
		}
		addPages();
	}

	protected MethodElementEditorInput createInput(MethodElement e) {
		return new MethodElementEditorInput(e);
	}

	public synchronized void refresh(final boolean force) {
		BusyIndicator.showWhile(getSite().getShell().getDisplay(),
				new Runnable() {

					public void run() {
						Collection usedResources = lastUsedResources;
						if (!force && !elementObj.eIsProxy()
								&& !checkReloaded(usedResources)) {
							// no resource reloaded, no need to refresh
							//
							return;
						}
						int activePageIndex = getActivePage();
						modifiedRichText = null;
						if (isDirty()) {
							actionMgr.undoAll();
							dirty = false;
						}
						if (elementObj.eIsProxy()) {
							elementObj.eAdapters().remove(nameChangedListener);
							EObject e = RefreshJob.getInstance().resolve(
									elementObj);
							if (e instanceof MethodElement
									&& !e.eIsProxy()
									&& UmaUtil.getMethodLibrary(e) == LibraryService
											.getInstance()
											.getCurrentMethodLibrary()) {
								setInput(createInput((MethodElement) e));
							} else {
								// input element is invalid, close the editor
								//
								close(false);
								return;
							}
						}
						updateTimeStamps(usedResources);
						updatePages();
						if (activePageIndex != -1) {
							setActivePage(activePageIndex);
						}
						firePropertyChange(IEditorPart.PROP_DIRTY);
					}

				});

	}

	/**
	 * Refreshes the editor
	 */
	public void refresh() {
		// save changed resources before refresh so action manager will not try
		// to save these changed resources
		//
		changedResources.addAll(RefreshJob.getInstance().getChangedResources());
		refresh(false);
		changedResources.clear();
	}


	/**
	 * Public method to refresh editor title image on certain action.
	 * e.g. If methodPlugin is locked, editor title image should be grey-ed out.
	 * 
	 * @param methodElement
	 */
	public void refreshTitleImage() {
		if (fMethodElementEditorErrorTickUpdater != null)
			fMethodElementEditorErrorTickUpdater.updateEditorImage(elementObj);
	}

	public void updatedTitleImage(Image image) {
		setTitleImage(image);
	}

}