//------------------------------------------------------------------------------
// 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.library.util;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.epf.common.serviceability.MsgBox;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.LibraryPlugin;
import org.eclipse.epf.library.LibraryResources;
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.IResourceAwareCommand;
import org.eclipse.epf.library.edit.util.ExtensionManager;
import org.eclipse.epf.library.edit.util.IOppositeFeatureLoader;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.edit.validation.IValidator;
import org.eclipse.epf.library.edit.validation.IValidatorFactory;
import org.eclipse.epf.persistence.MethodLibraryPersister;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElementDescription;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.NamedElement;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.util.AssociationHelper;
import org.eclipse.epf.uma.util.ContentDescriptionFactory;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;

/**
 * @author Phong Nguyen Le - Sep 13, 2006
 * @since  1.0
 */
public class TypeConverter {
	private static final Comparator activityFeatureComparator = new Comparator() {

		public int compare(Object arg0, Object arg1) {
			if(arg0 == UmaPackage.Literals.BREAKDOWN_ELEMENT__SUPER_ACTIVITIES) {
				return -1;
			}
			return 0;
		}
		
	};
	
	/**
	 * Converts the specified object to a object of new type specified by <code>newType</code> while still
	 * preserving as many attributes and relationships as possible
	 * 
	 * @param object
	 * @param newType
	 * @param oldFeatureToNewFeatureMap map of feature of <code>object</code> to feature of <code>newType</code>
	 * @return new object of type <code>newType</code>
	 */
	public static final EObject convert(EObject object, EClass newType,
			Map oldFeatureToNewFeatureMap, Comparator featureComparator, Set modifiedResources) 
	{
		TypeConversionCommand cmd = createTypeConversionCommand(object, newType, oldFeatureToNewFeatureMap, featureComparator);
		try {
			cmd.execute();
			modifiedResources.addAll(cmd.getModifiedResources());
			return (EObject) cmd.getResult().iterator().next();
		}
		finally {
			cmd.dispose();
		}
	}

//	public static final EObject convert(EObject object, EClass newType, Map oldFeatureToNewFeatureMap,
//			Set modifiedResources) {
//		EObject newObject = UmaFactory.eINSTANCE.create(newType);
//		
//		// copy all the features
//		//
//		List newObjectFeatures = newType.getEAllStructuralFeatures();
//		for (Iterator iter = object.eClass().getEAllStructuralFeatures().iterator(); iter.hasNext();) {
//			EStructuralFeature feature = (EStructuralFeature) iter.next();
//			if(!newObjectFeatures.contains(feature)) {
//				if(oldFeatureToNewFeatureMap != null) {
//					Object f = oldFeatureToNewFeatureMap.get(feature);
//					if(f != null && newObjectFeatures.contains(f)) {
//						feature = (EStructuralFeature) f;
//					}
//					else {
//						feature = null;
//					}
//				}
//			}
//			if(feature != null && feature.isChangeable()) {				
//				boolean featureHandled = false;
//				if(feature instanceof EReference) {
//					EReference ref = (EReference) feature;
//					if(ref == UmaPackage.Literals.DESCRIBABLE_ELEMENT__PRESENTATION) {
//						if(ContentDescriptionFactory.hasPresentation((MethodElement) object)) {
//							EObject value = (EObject) object.eGet(ref);
//							EClass contentDescType = ContentDescriptionFactory.getContentDescriptionType(newType);
//							if(contentDescType != null && contentDescType != value.eClass()) {
//								value = convert(value, contentDescType, null, modifiedResources);
//							}
//							newObject.eSet(ref, value);
//						}
//						featureHandled = true;
//					}					
//					else if(!ref.isContainment() && ref.getEOpposite() != null) {
//						// Reference is bi-directional. If opposite reference is a list, replace object
//						// with new object at the same position in the list.
//						//
//						EReference oppositeRef = ref.getEOpposite();						
//						if(oppositeRef.isMany()) {
//							Object value = object.eGet(ref);
//							if(value != null) {
//								if(ref.isMany()) {
//									for (Iterator iterator = ((Collection)value)
//											.iterator(); iterator.hasNext();) {
//										EObject otherEnd = (EObject) iterator.next();
//										List list = (List) otherEnd.eGet(oppositeRef);
//										int index = list.indexOf(object);
//										list.set(index, newObject);
//									}
//								}
//								else {
//									EObject otherEnd = (EObject) value;
//									List list = (List) otherEnd.eGet(oppositeRef);
//									int index = list.indexOf(object);
//									list.set(index, newObject);
//								}
//							}
//							featureHandled = true;
//						}
//					}
//				}
//				if(!featureHandled) {
//					newObject.eSet(feature, object.eGet(feature));
//				}
//			}
//		}
//		
//		if(object instanceof MethodElement) {
//			// redirect all incoming references of object to newObject
//			//
//			
//			MethodElement me = (MethodElement) object;
//			Collection oppositeFeatures = me.getOppositeFeatures();
//			if(!oppositeFeatures.isEmpty()) {
//				Resource resource = me.eResource();
//				if(resource != null) {
//					ResourceSet resourceSet = resource.getResourceSet();
//					if(resourceSet instanceof MultiFileResourceSetImpl) {
//						((MultiFileResourceSetImpl)resourceSet).loadOppositeFeatures(new ArrayList(oppositeFeatures), 
//								Collections.singleton(me.getGuid()));
//					}
//				}
//				
//				Map referencerToFeatureListMap = AssociationHelper.getReferenceMap(me);
//				for (Iterator iter = referencerToFeatureListMap.entrySet().iterator(); iter
//						.hasNext();) {
//					Map.Entry entry = (Map.Entry) iter.next();
//					EObject referencer = (EObject) entry.getKey();
//					for (Iterator iterator = ((Collection)entry.getValue()).iterator(); iterator
//							.hasNext();) {
//						EReference feature = (EReference) iterator.next();
//						if(feature.getEType().isInstance(newObject)) {
//							if(feature.isMany()) {
//								List list = (List) referencer.eGet(feature);
//								int index = list.indexOf(object);
//								list.set(index, newObject);
//							}
//							else {
//								referencer.eSet(feature, newObject);
//							}
//						}
//						else {							
//							if(feature.isMany()) {
//								List list = (List) referencer.eGet(feature);
//								list.remove(object);
//							}
//							else {
//								referencer.eSet(feature, feature.getDefaultValue());
//							}
//							resource = referencer.eResource();
//							if(resource != null) {
//								modifiedResources.add(resource);
//							}
//						}
//					}
//				}
//			}
//		}
//		
//		// replace object with newObject in the object's container
//		//
//		EObject container = object.eContainer();
//		if(container != null) {
//			EReference ref = object.eContainmentFeature();
//			if(ref.isMany()) {
//				List list = (List) container.eGet(ref);
//				int index = list.indexOf(object);
//				list.set(index, newObject);
//			}
//			else {
//				container.eSet(ref, newObject);
//			}
//			Resource resource = container.eResource();
//			if(resource != null) {
//				modifiedResources.add(resource);
//			}
//		}
//		
//		return newObject;
//	}
	
	private static class ResourceCopyTask {
		ContentResourceScanner scanner;
		MethodElement owner;
		String content;
		String contentPath;
		
		/**
		 * @param scanner
		 * @param owner
		 * @param content
		 * @param contentPath
		 */
		public ResourceCopyTask(ContentResourceScanner scanner, MethodElement owner, String content, String contentPath) {
			super();
			this.scanner = scanner;
			this.owner = owner;
			this.content = content;
			this.contentPath = contentPath;
		}	
				
	}
	
	public static class TypeConversionCommand extends CompoundCommand implements IResourceAwareCommand {

		private Collection result;
		private EObject object;
		private HashSet modifiedResources;
		private boolean gotModifiedResources;
		private List resourceCopyTasks;
		private Resource resource;
		private Collection illegalReferencers;

		/**
		 * @param object
		 */
		public TypeConversionCommand(EObject object) {
			this.object = object;
			modifiedResources = new HashSet();
			resource = object.eResource();
			if(resource != null) {
				modifiedResources.add(resource);
			}
			resourceCopyTasks = new ArrayList();
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.emf.common.command.CompoundCommand#dispose()
		 */
		public void dispose() {
			if(illegalReferencers != null) {
				illegalReferencers.clear();
			}
			if(modifiedResources != null) {
				modifiedResources.clear();
			}
			if(resourceCopyTasks != null) {
				resourceCopyTasks.clear();
			}
			super.dispose();
		}
				
		/**
		 * Gets referencers that become illegal after the type conversion
		 * 
		 * @return
		 */
		public Collection getIllegalReferencers() {
			if(illegalReferencers == null) {
				getModifiedResources();
			}
			return illegalReferencers;
		}
		
		public void copyResources() {
			if(!resourceCopyTasks.isEmpty()) {
				for (Iterator iter = resourceCopyTasks.iterator(); iter.hasNext();) {
					ResourceCopyTask t = (ResourceCopyTask) iter.next();
					File newResourcePath = new File(LibraryService.getInstance()
							.getCurrentMethodLibraryPath(), MethodLibraryPersister
							.getElementPath(t.owner));
					t.scanner.setTargetRootPath(newResourcePath);
					if(t.content != null) {
						t.scanner.resolveResources(t.owner, t.content, t.contentPath);
					}
					else {
						for (Iterator iterator = t.owner.eClass().getEAllAttributes().iterator(); iterator
								.hasNext();) {
							EAttribute attribute = (EAttribute) iterator.next();
							Object value = t.owner.eGet(attribute);
							if(value instanceof String) {
								t.scanner.resolveResources(t.owner, (String) value, t.contentPath);
							}
						}
					}
				}
			}
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.epf.library.edit.command.IResourceAwareCommand#getModifiedResources()
		 */
		public Collection getModifiedResources() {
			if(!gotModifiedResources) {
				illegalReferencers = new HashSet();
				for (Iterator iter = commandList.iterator(); iter.hasNext();) {
					Command cmd = (Command) iter.next();
					if(cmd instanceof RemoveCommand) {
						RemoveCommand removeCommand = (RemoveCommand) cmd;
						EObject owner = removeCommand.getOwner();
						Resource ownerResource = owner.eResource();
						if(ownerResource != null && ownerResource != resource) {
							modifiedResources.add(ownerResource);
						}
						if(ownerResource != null && owner != object && !UmaUtil.isContainedBy(owner, object)) {
							illegalReferencers.add(owner);
						}
					}
					else if(cmd instanceof SetCommand) {
						SetCommand setCommand = (SetCommand) cmd;
						EObject owner = setCommand.getOwner();
						Resource ownerResource = owner.eResource();
						if(ownerResource != null && ownerResource != resource && setCommand.getValue() instanceof EObject) {
							EObject value = (EObject) setCommand.getValue();
							if(value != object || !UmaUtil.isContainedBy(value, object)) {
								modifiedResources.add(ownerResource);
							}
						}
						if(ownerResource != null && owner != object && !UmaUtil.isContainedBy(owner, object)
								&& setCommand.getValue() == setCommand.getFeature().getDefaultValue()) {
							illegalReferencers.add(owner);
						}
					}
				}
				gotModifiedResources = true;
			}
			return modifiedResources;
		}
		
		private void setResult(Collection result) {
			this.result = result;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.emf.common.command.CompoundCommand#getResult()
		 */
		public Collection getResult() {
			return result;
		}
	}
	
	/**
	 * 
	 * @param object EObject
	 * @param newType EClass
	 * @param oldFeatureToNewFeatureMap Map
	 * @param featureComparator Comparator
	 * @return TypeConversionCommand
	 */
	public static final TypeConversionCommand createTypeConversionCommand(EObject object, EClass newType, 
			Map oldFeatureToNewFeatureMap, Comparator featureComparator) {
		return createTypeConversionCommand(object, newType, oldFeatureToNewFeatureMap, featureComparator, false, false);
	}
	
	/**
	 * 
	 * @param object EObject
	 * @param newType EClass
	 * @param oldFeatureToNewFeatureMap Map
	 * @param featureComparator Comparator
	 * @param removeIncomingReferences boolean
	 * @param removeVariability boolean
	 * @return TypeConversionCommand
	 */
	public static final TypeConversionCommand createTypeConversionCommand(EObject object, EClass newType, 
			Map oldFeatureToNewFeatureMap, Comparator featureComparator, 
			boolean removeIncomingReferences, boolean removeVariability) {
		TypeConversionCommand cmd = new TypeConversionCommand(object);
		EObject newObject = prepareConvert(object, newType, oldFeatureToNewFeatureMap, featureComparator, removeIncomingReferences, removeVariability, cmd);
		
		// replace object with newObject in the object's container
		//
		EObject container = object.eContainer();
		if(container != null) {
			EReference ref = object.eContainmentFeature();
			if(ref.isMany()) {
				List list = (List) container.eGet(ref);
				int index = list.indexOf(object);
				cmd.append(new SetCommand(null, container, ref, newObject, index));
			}
			else {
				cmd.append(new SetCommand(null, container, ref, newObject));
			}
		}
		
		cmd.setResult(Collections.singletonList(newObject));
		
		return cmd;
	}
	
	private static ContentResourceScanner createScanner(EObject object) {
		if(object instanceof ContentDescription && !(object instanceof BreakdownElementDescription)) {
			File oldResourcePath = new File(LibraryService.getInstance()
					.getCurrentMethodLibraryPath(), MethodLibraryPersister
					.getElementPath((MethodElement) object));
			ContentResourceScanner scanner = new ContentResourceScanner(oldResourcePath);
			return scanner;
		}
		return null;
	}	
	
	/**
	 * Prepares a compound command to do a type conversion
	 * 
	 * @param object
	 * @param newType
	 * @param oldFeatureToNewFeatureMap
	 * @param featureComparator used to sort the feature list of object to convert before copying/moving
	 *        feature values to new object.
	 * @param removeIncomingReferences if true will remove all incoming references 
	 * @param compoundCommand
	 * @return EObject
	 */
	public static final EObject prepareConvert(EObject object, EClass newType, Map oldFeatureToNewFeatureMap,
			Comparator featureComparator, boolean removeIncomingReferences, boolean removeVariability,
			TypeConversionCommand compoundCommand) {
		EObject newObject = UmaFactory.eINSTANCE.create(newType);
		
		if(object instanceof MethodElement) {
			// Handle incoming references.
			// If removeIncommingReferences is false, redirect all incoming references of object to newObject
			// If removeIncommingReferences is true, remove all of them.
			//			

			MethodElement me = (MethodElement) object;
			Collection oppositeFeatures = me.getOppositeFeatures();
			if(!oppositeFeatures.isEmpty()) {				
				
				// load opposite features
				//
				Collection collection = Collections.singletonList(object);
				for (Iterator iter = ExtensionManager.getOppositeFeatureLoaders().iterator(); iter
						.hasNext();) {
					IOppositeFeatureLoader loader = (IOppositeFeatureLoader) iter.next();
					loader.loadOppositeFeatures(collection);
				}
				
				Map referencerToFeatureListMap = AssociationHelper.getReferenceMap(me);
				for (Iterator iter = referencerToFeatureListMap.entrySet().iterator(); iter
						.hasNext();) {
					Map.Entry entry = (Map.Entry) iter.next();
					EObject referencer = (EObject) entry.getKey();
					for (Iterator iterator = ((Collection)entry.getValue()).iterator(); iterator
							.hasNext();) {
						EReference feature = (EReference) iterator.next();
						if(!removeIncomingReferences && feature.getEType().isInstance(newObject)) {
							// new type is compatible, reference can be preserved
							//
							if(feature.isMany()) {
								List list = (List) referencer.eGet(feature);
								int index = list.indexOf(object);
								compoundCommand.append(new SetCommand(null, referencer, feature, newObject, index));
							}
							else {
								compoundCommand.append(new SetCommand(null, referencer, feature, newObject));
							}
						}
						else {
							// new type is not compatible, reference must be removed
							//
							if(feature.isMany()) {
								compoundCommand.append(new RemoveCommand(null, referencer, feature, object));
							}
							else {
								compoundCommand.append(new SetCommand(null, referencer, feature, feature.getDefaultValue()));
							}
						}
					}
				}
			}
		}
		
		// copy all the features
		//
		List newObjectFeatures = newType.getEAllStructuralFeatures();
		List objectFeatures = new ArrayList(object.eClass().getEAllStructuralFeatures());
		if(removeVariability) {
			objectFeatures.remove(UmaPackage.Literals.VARIABILITY_ELEMENT__VARIABILITY_BASED_ON_ELEMENT);
			objectFeatures.remove(UmaPackage.Literals.VARIABILITY_ELEMENT__VARIABILITY_TYPE);
		}
		if(featureComparator != null) {
			Collections.sort(objectFeatures, featureComparator);
		}
		ContentResourceScanner scanner = createScanner(object);
		for (Iterator iter = objectFeatures.iterator(); iter.hasNext();) {
			EStructuralFeature feature = (EStructuralFeature) iter.next();
			if(!newObjectFeatures.contains(feature)) {
				if(oldFeatureToNewFeatureMap != null) {
					Object f = oldFeatureToNewFeatureMap.get(feature);
					if(f != null && newObjectFeatures.contains(f)) {
						feature = (EStructuralFeature) f;
					}
					else {
						feature = null;
					}
				}
				else {
					feature = null;
				}
			}
			if(feature != null && feature.isChangeable()) {				
				boolean featureHandled = false;
				if(feature instanceof EReference) {
					EReference ref = (EReference) feature;
					if(ref == UmaPackage.Literals.DESCRIBABLE_ELEMENT__PRESENTATION) {
						if(ContentDescriptionFactory.hasPresentation((MethodElement) object)) {
							ContentDescription content = (ContentDescription) object.eGet(ref);
							EClass contentDescType = ContentDescriptionFactory.getContentDescriptionType(newType);
							if(contentDescType != null && contentDescType != content.eClass()) {
								EObject newContent = prepareConvert(content, contentDescType, null, null, removeIncomingReferences, removeVariability, compoundCommand);
								
								// remove old content
								//
								EObject container = content.eContainer();
								if(container != null) {
									compoundCommand.append(new SetCommand(null, object, ref, null));
									Resource resource = content.eResource();
									if(resource != null) {
										compoundCommand.modifiedResources.add(content.eResource());
									}
								}
								
								content = (ContentDescription) newContent;
							}
							else {
								compoundCommand.resourceCopyTasks.add(new ResourceCopyTask(createScanner(content), content, null, "")); //$NON-NLS-1$
							}
							compoundCommand.append(new SetCommand(null, newObject, ref, content));
						}
						featureHandled = true;
					}					
					else if(!ref.isContainment() && ref.getEOpposite() != null) {
						// Reference is bi-directional. If opposite reference is a list, replace object
						// with new object at the same position in the list.
						//
						EReference oppositeRef = ref.getEOpposite();						
						if(oppositeRef.isMany()) {
							Object value = object.eGet(ref);
							if(value != null) {
								if(ref.isMany()) {
									for (Iterator iterator = ((Collection)value)
											.iterator(); iterator.hasNext();) {
										EObject otherEnd = (EObject) iterator.next();
										List list = (List) otherEnd.eGet(oppositeRef);
										int index = list.indexOf(object);
										compoundCommand.append(new SetCommand(null, otherEnd, oppositeRef, newObject, index));
									}
								}
								else {
									EObject otherEnd = (EObject) value;
									List list = (List) otherEnd.eGet(oppositeRef);
									int index = list.indexOf(object);
									compoundCommand.append(new SetCommand(null, otherEnd, oppositeRef, newObject, index));								}
							}
							featureHandled = true;
						}
					}
				}
				if(!featureHandled) {
					Object value = object.eGet(feature);
					if (feature == UmaPackage.Literals.NAMED_ELEMENT__NAME) {
						// validate name
						String newName = checkName(object, newType);
						if (newName != null) {
							value = newName;
						}
					}
					if(scanner != null && value instanceof String && object instanceof MethodElement) {
						String str = (String) value;
						if(!StrUtil.isBlank(str)) {
							compoundCommand.resourceCopyTasks.add(new ResourceCopyTask(scanner, (MethodElement)object, str, "")); //$NON-NLS-1$
						}
					}
					compoundCommand.append(new SetCommand(null, newObject, feature, value));
				}
			}
		}
						
		return newObject;
	}

	/**
	 * 
	 * @param oldActivity Activity
	 * @param newType EClass
	 * @return Activity
	 */
	public static Activity convertActivity(Activity oldActivity, EClass newType) {
		// activity is already this type
		//
		if (newType == oldActivity.eClass()) {
			return null;
		}
		
		HashSet modifiedResources = new HashSet();
		Activity newActivity = (Activity) TypeConverter.convert(oldActivity, newType, null, activityFeatureComparator, modifiedResources);

		// save modified resources
		//
		if (!modifiedResources.isEmpty()) {
			ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil.getCurrentPersister().getFailSafePersister();
			try {
				for (Iterator iter = modifiedResources.iterator(); iter
						.hasNext();) {
					Resource res = (Resource) iter.next();
					persister.save(res);
				}
				persister.commit();

			} catch (Exception e) {
				LibraryPlugin
						.getDefault()
						.getMsgDialog()
						.displayError(
								LibraryResources.convertActivityError_title,
								NLS
										.bind(
												LibraryResources.saveConvertedActivityError_msg,
												newActivity.getName()),
								LibraryResources.error_reason, e);

				persister.rollback();
			}
		}
		
		return newActivity;
	}		
	
	/**
	 * 
	 * @param typeID int
	 * @return EClass
	 */
	public static EClass getActivityType(int typeID) {
		switch (typeID) {
		case UmaPackage.ACTIVITY:
			return UmaPackage.Literals.ACTIVITY;
		case UmaPackage.ITERATION:
			return UmaPackage.Literals.ITERATION;
		case UmaPackage.PHASE:
			return UmaPackage.Literals.PHASE;
		default:
			return null;
		}
	}

	
	/**
	 * @param oldGuidance
	 * @param newGuidance
	 * @return
	 */
	private static String checkName(EObject object, EClass newType) {
		// TODO Auto-generated method stub
		if (object instanceof NamedElement) {
			NamedElement e = (NamedElement)object;
			final IValidator validator = IValidatorFactory.INSTANCE.createNameValidator(e.eContainer(), e, newType);
			String msg = validator.isValid(e.getName());
			if(msg != null) {
				String featureTxt = TngUtil.getFeatureText(UmaPackage.eINSTANCE
						.getNamedElement_Name());
				String title = LibraryEditResources.resolveNameConflictDialog_title; //$NON-NLS-1$			
				String dlgMsg = NLS.bind(
						LibraryEditResources.resolveNameConflictDialog_text,
						StrUtil.toLower(featureTxt), e.getName());
				String currentValue = (String) e.eGet(UmaPackage.eINSTANCE
						.getNamedElement_Name());
	
				IInputValidator inputValidator = new IInputValidator() {
					public String isValid(String newText) {
						return validator.isValid(newText);
					}
				};
	
				InputDialog inputDlg = new InputDialog(
						MsgBox.getDefaultShell(), title, dlgMsg, currentValue,
						inputValidator);
				if (inputDlg.open() == Window.CANCEL) {
					throw new OperationCanceledException();
				}
				return inputDlg.getValue();
			}
		}
		return null;
	}

}