//------------------------------------------------------------------------------
// 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.export.xml.services;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
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.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.sdo.EDataObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xml.type.XMLTypeFactory;
import org.eclipse.emf.ecore.xml.type.XMLTypePackage;
import org.eclipse.epf.common.service.versioning.VersionUtil;
import org.eclipse.epf.dataexchange.util.ContentProcessor;
import org.eclipse.epf.dataexchange.util.ILogger;
import org.eclipse.epf.export.xml.ExportXMLResources;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.util.MethodElementPropertyHelper;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.xml.uma.BreakdownElement;
import org.eclipse.epf.xml.uma.ContentCategoryPackage;
import org.eclipse.epf.xml.uma.ContentElement;
import org.eclipse.epf.xml.uma.ContentPackage;
import org.eclipse.epf.xml.uma.DocumentRoot;
import org.eclipse.epf.xml.uma.MethodElement;
import org.eclipse.epf.xml.uma.MethodElementProperty;
import org.eclipse.epf.xml.uma.MethodLibrary;
import org.eclipse.epf.xml.uma.MethodPackage;
import org.eclipse.epf.xml.uma.MethodPlugin;
import org.eclipse.epf.xml.uma.ProcessComponent;
import org.eclipse.epf.xml.uma.ProcessElement;
import org.eclipse.epf.xml.uma.ProcessPackage;
import org.eclipse.epf.xml.uma.Section;
import org.eclipse.epf.xml.uma.UmaFactory;
import org.eclipse.epf.xml.uma.UmaPackage;
import org.eclipse.epf.xml.uma.VariabilityType;
import org.eclipse.epf.xml.uma.WorkBreakdownElement;
import org.eclipse.epf.xml.uma.WorkOrder;
import org.eclipse.epf.xml.uma.WorkOrderType;
import org.eclipse.epf.xml.uma.util.UmaResourceFactoryImpl;
import org.eclipse.osgi.util.NLS;

import com.ibm.icu.text.SimpleDateFormat;
import commonj.sdo.Type;

/**
 * XmlLibrary represents a method library loaded from a specified xml file The
 * xml file should be valid to the xml schema for MethodLibrary
 * 
 * @author Jinhua Xi
 * @since 1.0
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=162153
 */
public class XMLLibrary {

	public static final String WorkOrderPropStringSep = "\n\n";			//$NON-NLS-1$
	public static final String WorkOrderPropStringFieldSep = "\n";			//$NON-NLS-1$
	
	private String filePath;

	private ILogger logger;

	private ContentProcessor contentProc = null;

	private MethodLibrary rootObject;

	// map of content category package for each plugin id
	private Map contentCategoryPkgMap = new HashMap();

	// map of created elements, guid - EDataObject
	private Map elementsMap = new HashMap();
	
	private Map<String, String> guidToPlugNameMap;
	
	private Map<WorkOrder, org.eclipse.epf.uma.WorkOrder> successOrWorkOrderMap;

	/**
	 * Creates a new instance.
	 */
	public XMLLibrary(ContentProcessor contentProc, ILogger logger,
			String filePath) {
		this.contentProc = contentProc;
		this.logger = logger;
		this.filePath = filePath;

	}

	/**
	 * @return root object.
	 */
	public EDataObject getRoot() {
		return this.rootObject;
	}

	/**
	 * @return file path string.
	 */
	public String getFilePath() {
		return this.filePath;
	}

	/**
	 * get an array of plugin ids in the library
	 * 
	 * @return
	 */
	public String[] getPluginIds() {
		List plugins = rootObject.getMethodPlugin();
		String[] ids = new String[plugins.size()];
		for (int i = 0; i < plugins.size(); i++) {
			ids[i] = ((MethodPlugin) plugins.get(i)).getId();
		}

		return ids;
	}

	/**
	 * @param id
	 * @param name
	 * @return a new XML library.
	 */
	public EDataObject createLibrary(String id, String name) {

		MethodLibrary root = UmaFactory.eINSTANCE.createMethodLibrary();
		String version = "";								//$NON-NLS-1$	
		for (Iterator iter = VersionUtil.getAllToolIDs().iterator();iter.hasNext();) {
			String toolID = (String)iter.next();
			String toolVersion = VersionUtil.getVersions(toolID).getMinToolVersionForCurrentXMLSchemaVersion().getToolVersion().toString();
			if (version.length() > 0) {
				version += VersionUtil.XML_VERSIONS_SEPARATOR;
			}
			version += toolID + VersionUtil.XML_TOOL_VERSION_SEPARATOR + toolVersion;		
		}
		if (version.length() > 0) {
			root.setTool(version);
		}
		return create(id, name, root);
	}

	/**
	 * Loads the xml file.
	 */
	public void load() throws Exception {
/*		try {*/
			ResourceSet resourceSet = new ResourceSetImpl();

			// Get the URI of the model file.
			//
			URI fileURI = URI.createFileURI((new File(this.filePath)).getAbsolutePath());

			// Create a resource for this file.
			//
			// Resource resource = resourceSet.createResource(fileURI);
			Resource resource = new UmaResourceFactoryImpl()
					.createResource(fileURI);
			resourceSet.getResources().add(resource);

			resource.load(new HashMap());

			// Resource resource = resourceSet.getResource(fileURI, false);

			// EClass eClass =
			// ExtendedMetaData.INSTANCE.getDocumentRoot(umaPackage);

			DocumentRoot root = (DocumentRoot) resource.getContents().get(0);
			for (Iterator itr = root.eContents().iterator(); itr.hasNext();) {
				Object o = itr.next();
				if (o instanceof MethodLibrary) {
					this.rootObject = (MethodLibrary) o;
					break;
				}
			}
/*
			// System.out.println("Resource loaded");
		} catch (IOException e) {
			logger.logError(NLS.bind(
					ExportXMLResources.xmlLibrary_error_load_xml, filePath), e);
		}*/
	}

	/**
	 * create the library and return the root object
	 * 
	 * @param filePath
	 * @return
	 */
	private MethodLibrary create(String id, String name, MethodElement root) {

		// Create a resource set
		//
		ResourceSet resourceSet = new ResourceSetImpl();

		// Get the URI of the model file.
		//
		File file = new File(this.filePath);
		URI fileURI = URI.createFileURI(file.getAbsolutePath());

		// Create a resource for this file.
		//
		// Resource resource = resourceSet.createResource(fileURI);
		Resource resource = new UmaResourceFactoryImpl()
				.createResource(fileURI);
		resourceSet.getResources().add(resource);

		// Add the initial model object to the contents.
		// root.setId(id);
		// root.setName(name);

		setElement(id, root);

		// this.rootObject = root;
		if (root != null) {
			resource.getContents().add(root);
		}

		try {
			Map options = new HashMap();
			options.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
			resource.save(options);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (root instanceof MethodLibrary) {
			this.rootObject = (MethodLibrary) root;
		}

		return this.rootObject;
	}

	/**
	 * @param pluginId
	 * @return a content catergory package in the plugin given by pluginId.
	 */
	public EDataObject getContentCategoryPackage(String pluginId) {

		ContentCategoryPackage pkg = (ContentCategoryPackage) contentCategoryPkgMap
				.get(pluginId);
		if (pkg != null) {
			return pkg;
		}

		MethodPlugin plugin = (MethodPlugin) getElement(pluginId);
		if (plugin == null) {
			logger.logWarning(NLS.bind(ExportXMLResources.xmlLibrary_no_plugin,
					pluginId));
			return null;
		}

		pkg = UmaFactory.eINSTANCE.createContentCategoryPackage();
		pkg.setName("ContentCategories"); //$NON-NLS-1$

		setElement(EcoreUtil.generateUUID(), pkg);

		plugin.getMethodPackage().add(pkg);

		contentCategoryPkgMap.put(pluginId, pkg);
		return pkg;
	}

	/**
	 * Saves the xml file.
	 */
	public void save() throws Exception {
		// Save the contents of the resource to the file system.
		//
		Map options = new HashMap();
		options.put(XMLResource.OPTION_ENCODING, "UTF-8"); //$NON-NLS-1$
		Resource resource = rootObject.eResource();
		resource.save(options);
	}

	/**
	 * @return the root object.
	 */
	public EDataObject open() {
		return rootObject;
	}

	/**
	 * @param guid
	 * @return the corresponding base library element.
	 */
	public EDataObject getElement(String guid) {
		return (EDataObject) elementsMap.get(guid);
	}

	/**
	 * @param obj
	 * @return the corresponding base library element.
	 */
	public EDataObject getElement(Object obj) {
		if (obj instanceof MethodElement) {
			return getElement(((MethodElement) obj).getId());
		}

		return null;
	}

	
	/**
	 * @param obj
	 * @return elmenent id string.
	 */
	public String getElementId(EDataObject obj) {

		if (obj instanceof MethodElement) {
			return ((MethodElement) obj).getId();
		} else if (obj instanceof WorkOrder) {
			return ((WorkOrder) obj).getId();
		}

		return null;
	}

	private void setElement(String guid, EDataObject obj) {
		// addElementToContainer(container, obj);
		if (!elementsMap.containsKey(guid)) {

			if (obj instanceof MethodElement) {
				((MethodElement) obj).setId(guid);
			}

			elementsMap.put(guid, obj);
		}
	}

	// private void addElementToContainer(EDataObject container, EDataObject
	// child) {
	//		
	// try {
	// if ( container == null ) {
	// return;
	// }
	//			
	// if ( child instanceof MethodLibrary || child instanceof MethodPlugin ||
	// child instanceof MethodPackage ) {
	// return;
	// }
	//			
	// while ( !(container instanceof MethodPackage) && (container != null) ) {
	// container = container.eContainer();
	// }
	//			
	// if ( container instanceof ContentPackage ) {
	// ((ContentPackage)container).getContentElement().add(child);
	// } else if ( container instanceof ProcessPackage ) {
	// ((ProcessPackage)container).getProcessElement().add(child);
	// } else {
	// System.out.println("Don't know how to set element " + child);
	// }
	// } catch (RuntimeException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// }
	// }

	/**
	 * create a child element with the specified guid
	 * 
	 * @param container
	 *            container of the element to be created
	 * @param umaFeatureName
	 *            uma feature for the element to be created
	 * @param umaEClassName
	 *            uma EClass name for the feature
	 * @param umaElementType
	 *            uma element type for the element to be created
	 * @param guid
	 *            guid of the element to be created
	 * @return EDataObject the Xml uma element
	 */
	public EDataObject createElement(EDataObject container,
			String umaFeatureName, String umaEClassName, String umaElementType,
			String guid) {

		EDataObject obj = getElement(guid);
		if (obj == null) {
			if (FeatureManager.INSTANCE.isUnneededRmcFeature(umaFeatureName)) {
				return null;
			}
			EStructuralFeature feature = FeatureManager.INSTANCE.getXmlFeature(
					container.eClass(), umaFeatureName, umaElementType);
			if (feature == null) {
				logger.logWarning(NLS.bind(
						ExportXMLResources.xmlLibrary_no_feature, container
								.eClass().getName(), umaFeatureName));
				return null;
			}

			// if ( !(feature instanceof EReference) ) {
			// System.out.println("Error creating element: containment feature
			// should be EReference type. " + feature.getName());
			// //return null;
			// }

			// // this is an easier way, test it,
			// // does not work since feature.getEType() returns the base
			// element type, not the extended one
			// // for example, it returns MethodPackage instead of
			// ProcessPackage or ContentPackage
			// // so we need to make our own map
			// EClassifier c = feature.getEType();
			// if ( !c.getName().equals(umaEClassName) ) {
			// System.out.println("EClass name not match: " + c.getName() + "
			// --- " + umaEClassName);
			// }

			EClass objClass = FeatureManager.INSTANCE
					.getXmlEClass(umaEClassName);
			if (objClass == null) {
				logger.logWarning(NLS.bind(
						ExportXMLResources.xmlLibrary_no_class, umaEClassName));
				return null;
			}

			obj = (EDataObject) EcoreUtil.create(objClass);
			setElement(guid, obj);

			if (obj instanceof WorkOrder) {
				// WorkOrder is not contained in a processPackage in xml model
				// it's contained by the breakdownElement
				// so we save the element id-object to the map and continue
				// don't set the feature value
				
				// the workOrder in EPF UMA model is referenced by feature
				// WorkBreakDownElement_LinkToPredecessor,
				// the corresponding feature in the xml model is 
				// WorkBreakDownElement_Predecessor, 
				// the feature value is a list of guid of the WorkOrders
				// when this feature value is set in the setReferenceValue() call
				// get the XmlUma object, if it's WorkOrder, 
				// add to the current workorder to the WorkBreakDownElement
				// Jinhua Xi, 08/24/2006
				return obj;
			}

			// note: all element references are string type (id)
			// package references are object references
			if (feature.isMany()) {
				List values = (List) container.eGet(feature);
				try {
					if (feature instanceof EAttribute) {
						values.add(guid);

						// need to put the object in a container
						// for example, the ContaiedArtifacts
						addToContainer(container, obj);

					} else if (feature instanceof EReference) {
						try {
							values.add(obj);
						} catch (RuntimeException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					} else {
						logger
								.logWarning(NLS
										.bind(
												ExportXMLResources.xmlLibrary_error_create_element,
												feature.getName()));
					}
				} catch (RuntimeException e) {
					logger.logError(NLS.bind(
							ExportXMLResources.xmlLibrary_error_set_value, obj,
							container), e);
					// e.printStackTrace();
				}
			} else {
				if (feature instanceof EAttribute) {
					container.eSet(feature, guid);
					addToContainer(container, obj);
				} else if (feature instanceof EReference) {
					container.eSet(feature, obj);
				} else {
					logger.logWarning(NLS.bind(
							ExportXMLResources.xmlLibrary_error_create_element,
							feature.getName()));
				}
			}
		}

		return obj;
	}

	private void addToContainer(EObject container, EObject obj) {

		if (container == null) {
			return;
		}
		if (container instanceof ContentPackage) {
			((ContentPackage) container).getContentElement().add((ContentElement)obj);
		} else if (container instanceof ProcessPackage) {
			((ProcessPackage) container).getProcessElement().add((ProcessElement)obj);
			// } else if ( (obj instanceof Constraint) && (container instanceof
			// MethodElement) ) {
			// // the owner rule should be a containment 0..n feature, waiting
			// for model fix
			// //((MethodElement)container).setO
		} else {
			addToContainer(container.eContainer(), obj);
		}
	}

	/**
	 * Sets attribute feature value.
	 * @param obj
	 * @param featureName
	 * @param value
	 * @throws Exception
	 */
	public void setAtributeFeatureValue(EDataObject obj, String featureName,
			Object value) throws Exception {
		if (obj == null || featureName == null || value == null) {
			return;
		}

		if (value instanceof List || value instanceof EDataObject) {
			if (featureName.equals("methodElementProperty")) {		//$NON-NLS-1$
				setMepFeatureValue(obj, featureName, value);
				return;
			}
			logger.logWarning(NLS.bind(
					ExportXMLResources.xmlLibrary_invalid_feature_value,
					featureName, value));

			return;
		}

		// find the feature and set the value
		EStructuralFeature feature = FeatureManager.INSTANCE.getXmlFeature(obj
				.eClass(), featureName);
		if (feature == null) {

			// ignore missing features for WorkOrder
			if (!(obj instanceof WorkOrder)) {
				Object[] paras = new Object[] { featureName, obj, value };
				logger
						.logWarning(NLS
								.bind(
										ExportXMLResources.xmlLibrary_error_set_value_2,
										paras));
			}
			return;
		}

		// 158688 - Missing template files in exported xml library
		// process the attachment url
		if ( feature == UmaPackage.eINSTANCE.getGuidanceDescription_Attachment() ) {
			if ( value != null ) {
				value = contentProc.resolveAttachmentResources(obj, value.toString().trim());
			}
			obj.eSet(feature, value);
		}
		
		if (feature instanceof EAttribute) {
			try {
				if (feature.getName().equals("variabilityType")) { //$NON-NLS-1$
					value = VariabilityType.get(value.toString());
				} else if (feature.getName().equals("linkType")) { //$NON-NLS-1$
					value = WorkOrderType.get(value.toString());
				} else if (value instanceof java.util.Date) {
					// convert java.util.Date to xml Date
					value = getXmlDate((java.util.Date) value);
				} else if ((contentProc != null)
						&& (obj instanceof MethodElement)
						&& (value instanceof String)) {
					value = contentProc.resolveResourceFiles(
							(MethodElement) obj, (String) value);
				} else if (value instanceof java.net.URI) {									
					org.eclipse.epf.uma.MethodPlugin srcPlugin = ExportResourceHandler.getSourcePlugin((org.eclipse.epf.xml.uma.MethodElement) obj);		
					value = srcPlugin.getName() + "/" + ((java.net.URI) value).getPath(); ////$NON-NLS-1$
					if (contentProc != null) {
						contentProc.copyResource((String) value, obj, srcPlugin);
					}
				}
				obj.eSet(feature, value);
			} catch (RuntimeException e) {
				Object[] paras = new Object[] { featureName, obj, value };
				logger
						.logError(
								NLS
										.bind(
												ExportXMLResources.xmlLibrary_error_set_value_2,
												paras), e);
			}
		} else {
			System.out.println(ExportXMLResources.xmlLibrary_error_set_value_3); 
		}

	}

	private void setMepFeatureValue(EDataObject obj, String featureName, Object value) {
		List srcList = (List) value;
		if (srcList == null || srcList.isEmpty()) {
			return;
		}
		if (obj instanceof WorkOrder) {
			setMepFeatureValueForWorkOrder(srcList, (WorkOrder) obj);
			return;
		}
		
		EStructuralFeature feature = FeatureManager.INSTANCE.getXmlFeature(obj
				.eClass(), featureName);
		List tgtList = (List) obj.eGet(feature);
		for (int i=0; i < srcList.size(); i++) {
			Object srcItem = srcList.get(i);
			if (srcItem instanceof org.eclipse.epf.uma.MethodElementProperty) {
				org.eclipse.epf.uma.MethodElementProperty mep = 
						(org.eclipse.epf.uma.MethodElementProperty) srcItem;
				EClass objClass = FeatureManager.INSTANCE
				.getXmlEClass("MethodElementProperty");	//$NON-NLS-1$
				MethodElementProperty xmlMep = (MethodElementProperty) EcoreUtil.create(objClass);
				xmlMep.setValue(mep.getValue());
				xmlMep.setName(mep.getName());
				tgtList.add(xmlMep);
			}
		}
		//obj.eSet(feature, tgtList);
	}

	private void setMepFeatureValueForWorkOrder(List srcList, WorkOrder xmlWorkOrder) {
		Object obj = getSuccessOrWorkOrderMap().get(xmlWorkOrder);
		org.eclipse.epf.uma.WorkOrder umaWorkOrder = null;
		org.eclipse.epf.uma.ProcessElement scopeElement = null;
		if (obj instanceof org.eclipse.epf.uma.WorkOrder) {
			umaWorkOrder = (org.eclipse.epf.uma.WorkOrder) obj;
		}
		
		
		
		String propertiesValue = "";	//$NON-NLS-1$	
		for (Object srcItem : srcList) {
			if (srcItem instanceof org.eclipse.epf.uma.MethodElementProperty) {
				org.eclipse.epf.uma.MethodElementProperty mep = 
						(org.eclipse.epf.uma.MethodElementProperty) srcItem;
				String srcName = mep.getName();
				String srcValue = mep.getValue();
				if (srcName != null && srcValue != null
						&& srcName.length() > 0 && srcValue.length() > 0) {
					if (propertiesValue.length() > 0) {
						propertiesValue += WorkOrderPropStringSep;				//$NON-NLS-1$
					}
					propertiesValue += "name=" + srcName;		//$NON-NLS-1$
					propertiesValue += WorkOrderPropStringFieldSep + "value=" + srcValue;	//$NON-NLS-1$
					
					if (umaWorkOrder != null && srcName.equals(MethodElementPropertyHelper.WORK_ORDER__SUCCESSOR)) {
						if (scopeElement == null) {
							Object cont = umaWorkOrder.eContainer();
							if (cont instanceof org.eclipse.epf.uma.ProcessPackage) {
								List<org.eclipse.epf.uma.ProcessElement> peList = 
									((org.eclipse.epf.uma.ProcessPackage) cont).getProcessElements();
								if (peList != null) {
									for (org.eclipse.epf.uma.ProcessElement pe : peList) {
										if (pe instanceof org.eclipse.epf.uma.Activity) {
											scopeElement = pe;
											break;
										}
									}
								}
							}
						}
						if (scopeElement != null) {
							propertiesValue += WorkOrderPropStringFieldSep + "scope=" + scopeElement.getGuid();		//$NON-NLS-1$
						}
					}
					
				}
			}
		}
		if (propertiesValue.length() > 0) {
			xmlWorkOrder.setProperties(propertiesValue);
		}
	}

	/**
	 * set the id references for the object
	 * 
	 * @param obj
	 *            EDataObject the object
	 * @param featureName
	 *            String the feature of the object
	 * @param idValue
	 *            String the id reference value of the feature
	 * @param valueType
	 *            Type the object type of the reference. Need to have this to
	 *            determine the xml feature in case the feature mappting is not
	 *            unique
	 * @throws Exception
	 */
	public void setReferenceValue(EDataObject obj, String featureName,
			String idValue, Type valueType) throws Exception {
		if (obj == null || featureName == null || idValue == null) {
			return;
		}

		if (FeatureManager.INSTANCE.isUnneededRmcFeature(featureName)) {
			return;
		}

		// find the feature and set the value
		EStructuralFeature feature = FeatureManager.INSTANCE.getXmlFeature(obj
				.eClass(), featureName, valueType.getName());
		if (feature == null) {
			Object[] paras = new Object[] { featureName, obj, idValue };
			logger.logWarning(NLS.bind(
					ExportXMLResources.xmlLibrary_error_set_reference, paras));
			return;
		}

		String str = feature.getEType().getName();
		if (str.equals("String")) { //$NON-NLS-1$
			if (feature.isMany()) {
				List l = (List) obj.eGet(feature);
				if (!l.contains(idValue)) {
					l.add(idValue);
				}
			} else {
				obj.eSet(feature, idValue);
			}
		} else if (feature == UmaPackage.eINSTANCE
				.getActivity_BreakdownElement()) {
			// special handling for breakdown element. In uma, breakdown
			// elements are under process packages
			// in xml model, they are owned by the activity
			EDataObject v = getElement(idValue);
			if (v instanceof BreakdownElement) {
				EObject old_container = v.eContainer();
				List l = (List) obj.eGet(feature);
				if (!l.contains(v)) {
					l.add(v);
				}

				// if the old container package is empty, delete it
				if ((old_container instanceof ProcessPackage)
						&& (old_container.eContainer() instanceof ProcessComponent)) {
					if (((ProcessPackage) old_container).getProcessElement()
							.size() == 0) {
						((ProcessPackage) old_container.eContainer())
								.getMethodPackage().remove(old_container);
					}
				}
			}
		} else if ( feature == UmaPackage.eINSTANCE.getWorkBreakdownElement_Predecessor() ) {
			// the orker order needs to be added to the WorkBreakdownElement
			// since in Xml model the work order is contained by the WorkBreakdownElement
			// Jinhua Xi, 08/24/2006
			Object v = getElement(idValue);
			if (v instanceof WorkOrder) {
				((WorkBreakdownElement)obj).getPredecessor().add((WorkOrder)v);
			}
		} else {
			// not handled, add warning log
			// the id feature value is not set
			// JInhua Xi, TODO
		}
	}

	/**
	 * @param dt
	 * @return a Xml date.
	 */
	public Object getXmlDate(java.util.Date dt) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); //$NON-NLS-1$
		String dtStr = sdf.format(dt);
		dtStr = dtStr.replace(' ', 'T');
		EDataType type = XMLTypePackage.eINSTANCE.getDateTime();
		return XMLTypeFactory.eINSTANCE.createFromString(type, dtStr);

	}

	private String getString(Object obj) {
		String str = ""; //$NON-NLS-1$
		if (obj instanceof MethodElement) {
			MethodElement me = (MethodElement) obj;
			str = me.getType().getName() + ":" + me.getName(); //$NON-NLS-1$
		} else if (obj != null) {
			str = obj.toString();
		}

		return str;
	}

	/**
	 * fix the library so that it meets the uma library standards
	 * 
	 */
	public void fixLibraryForImport() {

		fixGuid((MethodElement) rootObject);

		if (rootObject instanceof MethodLibrary) {
			for (Iterator it = ((MethodLibrary) rootObject).getMethodPlugin()
					.iterator(); it.hasNext();) {
				fixPlugin((MethodPlugin) it.next());
			}
		} else if (rootObject instanceof MethodPlugin) {
			fixPlugin((MethodPlugin) rootObject);
		}
	}

	/**
	 * fix the library so that it meets the xml schema standards
	 * also remove possible structure errors such as ProcessComponent without process in it.
	 * 
	 */
	public void fixLibraryForExport() {

		List invalidItems = new ArrayList();
		for (Iterator it = ((MethodLibrary) rootObject).eAllContents(); it.hasNext();) {
			Object obj = it.next();
			if ( obj instanceof ProcessComponent ) {
				org.eclipse.epf.xml.uma.Process proc = ((ProcessComponent)obj).getProcess();
				if ( proc == null ) {
					invalidItems.add(obj);
				}
			}
		}

		// remove the objects
		while (invalidItems.size() > 0 ) {
			EObject obj = (EObject)invalidItems.remove(0);
			EcoreUtil.remove(obj);
		}
	}
	
	/**
	 * fix task descriptors for export
	 * 
	 */
	public void fixTaskDescriptorsForExport(Map<String, TaskDescriptor> tdMap) {
		if (tdMap == null || tdMap.isEmpty()) {
			return;
		}		
		for (Iterator<Map.Entry<String, TaskDescriptor>> it = tdMap.entrySet().iterator(); it.hasNext();) {
			Map.Entry<String, TaskDescriptor> entry = it.next();
			String guid = entry.getKey();
			TaskDescriptor td = entry.getValue();
			org.eclipse.epf.xml.uma.TaskDescriptor xmlTd = (org.eclipse.epf.xml.uma.TaskDescriptor) elementsMap.get(guid);
			assert(xmlTd != null);
			if (xmlTd == null) {
				continue;
			}
			List steps = td.getSelectedSteps();
			for (int i=0; i<steps.size(); i++) {
				org.eclipse.epf.uma.MethodElement step = (org.eclipse.epf.uma.MethodElement) steps.get(i);
				Section xmlStep =  (Section) elementsMap.get(step.getGuid());
				assert(xmlStep != null);
				if (xmlStep != null) {
					xmlStep = (Section) EcoreUtil.copy(xmlStep);
					xmlTd.getStep().add(xmlStep);
				}
			}			
		}		
	}
			
	/**
	 * get a list of referenced plugins for the library. The referenced plugins
	 * does not include the ones inside this library. When importing, these
	 * plugins must be in the target library already.
	 * 
	 * @return List a list of referenced plugins
	 */
	public List getReferencedPlugins() {

		List externalPlugins = new ArrayList();

		if (!(rootObject instanceof MethodLibrary)) {
			return externalPlugins;
		}

		List selectedPlugins = new ArrayList();
		for (Iterator it = ((MethodLibrary) rootObject).getMethodPlugin()
				.iterator(); it.hasNext();) {
			MethodPlugin plugin = (MethodPlugin) it.next();
			String id = plugin.getId();
			selectedPlugins.add(id);
			if (externalPlugins.contains(id)) {
				externalPlugins.remove(id);
			}

			for (Iterator itr = plugin.getReferencedMethodPlugin().iterator(); itr
					.hasNext();) {
				String ref = (String) itr.next();
				if (!selectedPlugins.contains(ref)
						&& !externalPlugins.contains(ref)) {
					externalPlugins.add(ref);
				}
			}
		}

		return externalPlugins;
	}

	private void fixGuid(MethodElement element) {
		if (element == null) {
			return;
		}

		// if the xml element does not have an id specified, create a new one
		String id = element.getId();
		if (id == null || id.equals("")) { //$NON-NLS-1$
			id = EcoreUtil.generateUUID();
			element.setId(id);
			String msg = NLS.bind(ExportXMLResources.xmlLibrary_new_id,
					getString(element), id);
			logger.logWarning(msg);
		} else {
			// check if the element has a unique id or not
			Object old = getElement(id);
			if ((old != null) && (old != element)) {
				if (! ( (old instanceof Section) && 
						(element instanceof Section) 
					   )) {
					logger.logWarning(NLS.bind(
						ExportXMLResources.xmlLibrary_id_not_unique, id));
				}
			}

			setElement(id, element);
		}
		// iterate the children
		for (Iterator it = element.eContents().iterator(); it.hasNext();) {
			Object o = it.next();
			if (o instanceof MethodElement) {
				fixGuid((MethodElement) o);
			}
		}
	}

	private void fixPlugin(MethodPlugin plugin) {

		// find all processes and make sure they are wrapped with a
		// ProcessComponent,
		// if not, create one.
		// collect the processes to be fixed,
		// don't fix within the iteration, may cause concurrent modification
		// exeception
		List procs = new ArrayList();
		for (Iterator it = plugin.eAllContents(); it.hasNext();) {
			EObject o = (EObject) it.next();
			if (isProcess(o)) {
				procs.add(o);
			}
		}

		if (procs.size() > 0) {
			for (Iterator it = procs.iterator(); it.hasNext();) {
				fixProcess((org.eclipse.epf.xml.uma.Process) it.next());
			}
		}
	}

	/**
	 * In EPF, a process (Capability pattern and Delivery Process) can be reside
	 * in a ProcessPackage or a ProcessComponent. If it's in a processComponent,
	 * it is treated as a root level process. If it's in a ProcessPackage, it is
	 * treated as a local copy of another process. So we need to check the
	 * parent and see it this process is contained by a ProcessComponent.
	 * 
	 * @param Obj
	 * @return boolean
	 */
	private boolean isProcess(EObject obj) {
		if (!(obj instanceof org.eclipse.epf.xml.uma.Process)) {
			return false;
		}

		obj = obj.eContainer();
		if (obj instanceof ProcessComponent) {
			return true;
		}

		// if it's immediate parent is not a ProcessComponent but it's within a
		// ProcessComponent
		// it's a local copy of the process
		while (((obj = obj.eContainer()) != null)
				&& (obj instanceof ProcessPackage)) {
			if (obj instanceof ProcessComponent) {
				return false;
			}
		}

		return true;
	}

	private void fixProcess(org.eclipse.epf.xml.uma.Process proc) {
		EDataObject container = (EDataObject) proc.eContainer();
		ProcessComponent pc = null;
		if (container instanceof ProcessComponent) {
			return;
		}

		if (!(container instanceof ProcessPackage)) {
			String msg = NLS
					.bind(
							ExportXMLResources.xmlLibrary_error_process_wrong_container,
							proc.getName(), container.getType().getName());
			logger.logWarning(msg);
			return;
		}

		pc = UmaFactory.eINSTANCE.createProcessComponent();
		String id = getTargetParentId(proc.getId());
		if (id == null) {
			id = EcoreUtil.generateUUID();
		}

		pc.setId(id);
		pc.setName(proc.getName());
		((ProcessPackage) container).getProcessElement().remove(proc);
		((ProcessPackage) container).getMethodPackage().add(pc);
		pc.setProcess(proc);

	}

	/**
	 * if the process exists in the target library, get the process component id
	 * from the target library
	 */
	private String getTargetParentId(String id) {
		ILibraryManager manager = LibraryService.getInstance()
				.getCurrentLibraryManager();
		if (manager != null) {
			EObject obj = manager.getMethodElement(id);
			if (obj != null) {
				obj = obj.eContainer();
				if (obj instanceof org.eclipse.epf.uma.MethodElement) {
					return ((org.eclipse.epf.uma.MethodElement) obj).getGuid();
				}
			}
		}

		return null;
	}

	/**
	 * @param pkg
	 * @return the list of all processes in pkg.
	 */
	public List getAllProcesses(MethodPackage pkg) {
		List processes = new ArrayList();
		_iteratePackageForProcesses(pkg, processes);

		return processes;
	}

	private void _iteratePackageForProcesses(MethodPackage pkg, List processes) {
		if (pkg instanceof ProcessComponent) {
			org.eclipse.epf.xml.uma.Process p = ((ProcessComponent) pkg)
					.getProcess();
			if (p != null && !processes.contains(p)) {
				processes.add(p);
			}
		}

		for (Iterator it = pkg.getMethodPackage().iterator(); it.hasNext();) {
			_iteratePackageForProcesses((MethodPackage) it.next(), processes);
		}
	}

	
	/**
	 * Save extra info (all plugin guids and names) in libTag's MethodElementProperty
	 */
	protected void storeExtraInfo(List<org.eclipse.epf.uma.MethodPlugin> plugins) {
		if (plugins == null) {
			return;
		}		
		
		EStructuralFeature feature = FeatureManager.INSTANCE.getXmlFeature(rootObject
				.eClass(), "methodElementProperty");		//$NON-NLS-1$
		
		List mepList = (List) rootObject.eGet(feature);
		EClass mepClass = FeatureManager.INSTANCE.getXmlEClass("MethodElementProperty");	//$NON-NLS-1$
		
		MethodElementProperty xmlMep = (MethodElementProperty) EcoreUtil.create(mepClass);
		
		//Version
		xmlMep.setValue("0");	//$NON-NLS-1$
		mepList.add(xmlMep);
					
		for (Iterator<org.eclipse.epf.uma.MethodPlugin> it = plugins.iterator(); it.hasNext();) {
			org.eclipse.epf.uma.MethodPlugin plug = it.next();
			
			xmlMep = (MethodElementProperty) EcoreUtil.create(mepClass);
			xmlMep.setValue(plug.getGuid());
			mepList.add(xmlMep);
			
			xmlMep = (MethodElementProperty) EcoreUtil.create(mepClass);
			xmlMep.setValue(plug.getName());
			mepList.add(xmlMep);
		}
		
	}
	
	/**
	 * Get guid to plugin map
	 */
	public Map<String, String> getGuidToPlugNameMap() {
		if (guidToPlugNameMap == null) {
			recallExtraInfo();
		}		
		return guidToPlugNameMap;
	}
	
	private void recallExtraInfo() {
		try {
			EStructuralFeature feature = FeatureManager.INSTANCE.getXmlFeature(rootObject
					.eClass(), "methodElementProperty");		//$NON-NLS-1$
			
			List<MethodElementProperty> mepList = (List<MethodElementProperty>) rootObject.eGet(feature);
			if (mepList == null || mepList.isEmpty()) {
				return;
			}
			guidToPlugNameMap = new HashMap<String, String>();
			
			MethodElementProperty mep = mepList.get(0);
			if (mep.getValue().equals("0")) { //$NON-NLS-1$  
				for (int i = 1; i < mepList.size();) {
					String guid = mepList.get(i).getValue();
					String name = mepList.get(i+1).getValue();
					guidToPlugNameMap.put(guid, name);
					i += 2;
				}
			}
		} catch (Exception e) {
			guidToPlugNameMap = new HashMap<String, String>();
			e.printStackTrace();
		}
	}

	public Map<WorkOrder, org.eclipse.epf.uma.WorkOrder> getSuccessOrWorkOrderMap() {
		if (successOrWorkOrderMap == null) {
			successOrWorkOrderMap = new HashMap<WorkOrder, org.eclipse.epf.uma.WorkOrder>();
		}
		return successOrWorkOrderMap;
	}
	
}
