//------------------------------------------------------------------------------
// 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.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
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.IProgressMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.epf.dataexchange.util.ContentProcessor;
import org.eclipse.epf.dataexchange.util.IResourceHandler;
import org.eclipse.epf.diagram.ui.service.DiagramImageService;
import org.eclipse.epf.export.services.DiagramHandler;
import org.eclipse.epf.export.xml.ExportXMLPlugin;
import org.eclipse.epf.export.xml.ExportXMLResources;
import org.eclipse.epf.library.IConfigurationManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.util.DescriptorPropUtil;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.MethodElementPropertyHelper;
import org.eclipse.epf.library.edit.util.ModelStructure;
import org.eclipse.epf.library.edit.util.ProcessScopeUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.layout.ElementLayoutManager;
import org.eclipse.epf.library.services.SafeUpdateController;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.library.util.MigrationUtil;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.Diagram;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodElementProperty;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkOrder;
import org.eclipse.epf.uma.WorkOrderType;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ecore.IModelObject;
import org.eclipse.epf.uma.util.Scope;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.osgi.util.NLS;

/**
 * XmlExport service class to process the exporting task
 * 
 * @author Jinhua Xi
 * @since 1.0
 */
public class ExportXMLService {

	// String xmlPath;
	private ExportXMLData data;
	
	private boolean debug = ExportXMLPlugin.getDefault().isDebugging();

	private XMLLibrary xmlLib;

	private List discardedElements = new ArrayList();

	ExportXMLLogger logger = null;

	// in case we need to mapping the uma objects to xml objects
	// such as the content categories
	private Map umaIdToXmlIdMap = new HashMap();
	
	private DiagramHandler diagramHandler;
	
	//tds with steps
	private Map<String, TaskDescriptor> tdMap;
	
	private Set<WorkOrder> successors;

	/**
	 * Creates a new instance.
	 */
	public ExportXMLService(ExportXMLData data) {
		this.data = data;
		logger = new ExportXMLLogger(new File(this.data.xmlFile)
				.getParentFile());
	}
	/**
	 * Gets the logger file.
	 */
	public File getLogPath() {
		return logger.getLogPath();
	}

	/**
	 * Dispose
	 */
	public void dispose() {
		logger.dispose();
	}

	/**
	 * Does XML library export.
	 */
	public void doExport(IProgressMonitor monitor) {
		try {

			IResourceHandler handler = new ExportResourceHandler(
					new File(LibraryService.getInstance()
							.getCurrentMethodLibraryLocation()), new File(data
							.getXMLFile()).getParentFile());
			ContentProcessor contentProc = new ContentProcessor(handler,
					this.logger);
			
			diagramHandler = new DiagramHandler(
					new File(LibraryService.getInstance()
							.getCurrentMethodLibraryLocation()), new File(data
							.getXMLFile()).getParentFile()) {
				
				public void visitElementMap(int passId) {
					if (passId != 0) {
						return;
					}
/*					String libFolderPath = getSourceLibRoot().getAbsolutePath();
					int ix = libFolderPath.length();*/
					
					Map<String, MapEntryValue> map = getElementMap();
					for (Iterator<MapEntryValue> it = map.values().iterator(); it.hasNext(); ) {
						MapEntryValue value = it.next();
						if (value.targetFile == null) {
							continue;
						} else if (value.sourceFile != null) {
							IModelObject xmlObj = getXmlObject(value.element);
							if (xmlObj instanceof org.eclipse.epf.xml.uma.Process) {
								org.eclipse.epf.xml.uma.Process proc = 
													(org.eclipse.epf.xml.uma.Process) xmlObj;
								String uri = value.sourceFile.getAbsolutePath();
								String srcRootFolderPath = getRoot(value.element).getAbsolutePath();
								int ix = srcRootFolderPath.length();
								
								uri = uri.substring(ix + 1);
								uri = URI.createFileURI(uri).toString();
								proc.setDiagramURI(uri);
							}		
						} 
					}	
				}
				
				public void execute() {
					super.execute();
					SafeUpdateController.syncExec(new Runnable() {
						public void run() {
							exportDiagramImageFiles();
						}
					});
				}

				private void exportDiagramImageFiles() {
					String folderPath = LibraryService.getInstance().getCurrentMethodLibraryLocation();
					
					DiagramImageService diagramService = new DiagramImageService(null);
					diagramService.setForXMLExport(true);
					
					try {
						Map<String, MapEntryValue> map = getElementMap();
						for (Iterator<MapEntryValue> it = map.values().iterator(); it.hasNext(); ) {
							MapEntryValue value = it.next();
							org.eclipse.epf.uma.Process proc = (org.eclipse.epf.uma.Process) value.element;
							MethodConfiguration config = proc.getDefaultContext();
							if (config == null) {
								config = ProcessScopeUtil.getInstance().loadScope(proc);
								if (config == null) {
									continue;
								}
							}
							diagramService.setConfig(config);
							IConfigurationManager mgr = LibraryService.getInstance().getConfigurationManager(config);
							if (mgr == null) {
								continue;
							}
							ElementLayoutManager layoutMgr = mgr.getElementLayoutManager();
							if (layoutMgr == null) {
								continue;
							}
							IFilter filter = layoutMgr.getDiagramAdapterFactory().getFilter();
							
							File diagramXmiFile = value.targetFile;
							if (diagramXmiFile == null || !diagramXmiFile.exists()) {
								continue;
							}
							diagramService.setPubDir(diagramXmiFile.getParentFile());
							
							Map activities = MigrationUtil.getActivities(proc, true);	
							for (Activity act: (Collection<Activity>) activities.values()) {
								String[] types = {	ResourceHelper.DIAGRAM_TYPE_WORKFLOW,
													ResourceHelper.DIAGRAM_TYPE_ACTIVITY_DETAIL,
													ResourceHelper.DIAGRAM_TYPE_WP_DEPENDENCY};
								
								for (int i = 0; i < types.length; i++) {
									String imagePath = ResourceHelper.getXmlExportedDiagramImageFileName(act, types[i], ResourceHelper.FILE_EXT_JPEG);
									try {
										diagramService.saveDiagram(act, imagePath, types[i], filter, Suppression.getSuppression(proc));
									} catch (Exception e) {
										if (debug) {
											logger.logError(NLS.bind(ExportXMLResources.exportXMLService_error,
													e.getMessage()), e);
										}
									}
								}
							}
						}
						
					} catch (Exception e) {
						if (debug) {
							logger.logError(NLS.bind(ExportXMLResources.exportXMLService_error,
									e.getMessage()), e);
						}
					} finally {										
						diagramService.dispose();
					}
				}
			};

			// FeatureManager.INSTANCE.printFeatureNameMapping();

			// export the current library to the xml file
			// get the current library instance and export all to the xml
			MethodLibrary src = LibraryService.getInstance()
					.getCurrentMethodLibrary();

			this.xmlLib = new XMLLibrary(contentProc, logger, data
					.getXMLFile());

			this.xmlLib.createLibrary(src.getGuid(), src.getName());
			IModelObject target = this.xmlLib.getRoot();

			creatEDataObjectTree(src, target);
			iteratEDataObject(src);
			handleSuccessors();

			this.xmlLib.fixLibraryForExport();
			this.xmlLib.fixTaskDescriptorsForExport(tdMap);
			
			diagramHandler.visitElementMap(0);
			if (data.exportType == ExportXMLData.EXPORT_METHOD_PLUGINS) {
				xmlLib.storeExtraInfo(src.getMethodPlugins());
			}
			this.xmlLib.save();
			diagramHandler.execute();

		} catch (Exception e) {
			logger.logError(NLS.bind(ExportXMLResources.exportXMLService_error,
					e.getMessage()), e);
		}
	}

	private boolean isPluginSelected(MethodPlugin plugin) {
		if (data.exportType == ExportXMLData.EXPORT_METHOD_LIBRARY) {
			return true;
		} else if (data.exportType == ExportXMLData.EXPORT_METHOD_PLUGINS) {
			return (data.selectedPlugins != null)
					&& data.selectedPlugins.contains(plugin);
		} else if (data.exportType == ExportXMLData.EXPORT_METHOD_CONFIGS) {
			//return false;
			return true;	//hot fix
		} else {
			return true;
		}
	}

	private boolean isConfigExcluded(MethodConfiguration config) {
		if (data.exportType == ExportXMLData.EXPORT_METHOD_PLUGINS) {
			return data.associatedConfigs == null || 
					!data.associatedConfigs.contains(config.getGuid());
		} 
		return false;
	}
	
	private void creatEDataObjectTree(MethodElement srcObj,
			IModelObject targetObj) {

		// if it's a plugin, skip all the system packages
		// and find the top most user packages
		if (srcObj instanceof MethodPlugin) {

			MethodPlugin plugin = (MethodPlugin) srcObj;
			if (!isPluginSelected(plugin)) {
				return;
			}

			// all system packages are discarded
			discardedElements.addAll(TngUtil.getAllSystemPackages(plugin));

			List topmostUserPackages = getTopmostUserPackage(plugin);
			List categoryPkgs = TngUtil.getContentCategoryPackages(plugin);

			org.eclipse.epf.xml.uma.ContentCategoryPackage xmlPkg = (org.eclipse.epf.xml.uma.ContentCategoryPackage) this.xmlLib
					.getContentCategoryPackage(plugin.getGuid());
			String contentCategoryPackageId = xmlPkg.getId();

			for (Iterator itp = topmostUserPackages.iterator(); itp.hasNext();) {
				MethodPackage pkg = (MethodPackage) itp.next();

				// if it's a category package,
				// create all contained elements in the single custom category
				// package
				if (categoryPkgs.contains(pkg)) {

					// set the it mapping
					setIdMapping(pkg.getGuid(), contentCategoryPackageId);
					creatEDataObjectTree(pkg, xmlPkg);
				} else {
					creatEDataObjectTree(pkg, targetObj);
				}
			}
		} else {
			for (Iterator it = srcObj.eContents().iterator(); it.hasNext();) {
				Object nextObj = it.next();
				MethodElement child = nextObj instanceof MethodElement ?
						(MethodElement) nextObj : null;
				if (child == null) {
					continue;
				}

				// in uma model, WorkOrder is contained in package
				// in xml model, WorkOrder is contained by the owning
				// WorkBreakdownElement,
				// so delay the creation if the owner is a package
				if (child instanceof WorkOrder
						&& srcObj instanceof MethodPackage) {
					WorkOrder workOrder = (WorkOrder) child;
					MethodElementProperty prop = MethodElementPropertyHelper
					.getProperty(
							workOrder,
							MethodElementPropertyHelper.WORK_ORDER__SUCCESSOR);
					if (prop != null) {
						getSuccessors().add(workOrder);
					}					
					continue;
				}

				if ((child instanceof MethodPlugin)
						&& !isPluginSelected((MethodPlugin) child)) {
					continue;
				}
				
				if (child instanceof MethodConfiguration &&
					isConfigExcluded((MethodConfiguration) child)) {
					continue;
				}

				if (!isDiscarded(child)) {
					createXmlObject(child, targetObj);
				}
			}
		}
	}

	private void setIdMapping(String umaId, String xmlId) {
		if (!umaIdToXmlIdMap.containsKey(umaId)) {
			umaIdToXmlIdMap.put(umaId, xmlId);
		}
	}

	private String getXmlId(String umaId) {
		if (umaIdToXmlIdMap.containsKey(umaId)) {
			return (String) umaIdToXmlIdMap.get(umaId);
		}
		return umaId;
	}

	private boolean isDiscarded(Object o) {
		if (o instanceof Diagram) {
			return true;
		}
		return discardedElements.contains(o);
	}

	private IModelObject getXmlObject(MethodElement srcObj) {
		String id = srcObj.getGuid();
		if (umaIdToXmlIdMap.containsKey(id)) {
			id = (String) umaIdToXmlIdMap.get(id);
		}
		return this.xmlLib.getElement(id);
	}

	/**
	 * create an xml element for the container, based on the uma element
	 * 
	 * @param umaElement
	 * @param targetContainer
	 */
	private void createXmlObject(MethodElement umaElement,
			IModelObject targetContainer) {
		EStructuralFeature feature = umaElement.eContainmentFeature();
		createXmlObject(umaElement, targetContainer, feature.getName());
	}

	/**
	 * create an xml element for the container, based on the uma element
	 * 
	 * @param umaElement
	 * @param targetContainer
	 */
	private void createXmlObject(MethodElement umaElement,
			IModelObject targetContainer, String containmentFeature) {

		try {
			if (umaElement == null) {
				return;
			}

			// get the containment feature so we can create the object of the
			// same type
			String elementType = umaElement.getType().getName();
			IModelObject xmlElement = xmlLib.createElement(targetContainer,
					containmentFeature, umaElement.eClass().getName(),
					elementType, umaElement.getGuid());
			
			if (umaElement instanceof TaskDescriptor) {					
				TaskDescriptor td = (TaskDescriptor) umaElement;
				if (td.getTask() != null) {
					List steps = td.getSelectedSteps();
					if (steps != null && !steps.isEmpty()) {
						if (tdMap == null) {
							tdMap = new HashMap<String, TaskDescriptor>();
						}
						tdMap.put(td.getGuid(), td);
					}
				}			
			}
			
			if (xmlElement != null) {
				if (umaElement instanceof WorkOrder
						&& xmlElement instanceof org.eclipse.epf.xml.uma.WorkOrder) {
					xmlLib.getSuccessOrWorkOrderMap().put(
							(org.eclipse.epf.xml.uma.WorkOrder) xmlElement,
							(WorkOrder) umaElement);
				}
				
				// recursive
				creatEDataObjectTree(umaElement, xmlElement);
			}

		} catch (Exception e) {
			// log the error and continue???
			e.printStackTrace();
		}
	}

	private void iteratEDataObject(MethodElement srcObj) {
		Scope scope = null;	
		Process proc = null;
		try {
			if (srcObj instanceof Process) {
				proc = (Process) srcObj;
				scope = ProcessScopeUtil.getInstance().getScope(proc);
				if (scope != null) {
					setScope(proc, null);
				}
			}
			iteratEDataObject_(srcObj);
		} finally {
			if (scope != null && proc != null) {
				setScope(proc, scope);
			}
		}
	}
	
	private void setScope(Process proc, Scope scope) {
		boolean oldDeliver = proc.eDeliver();
		try {
			proc.eSetDeliver(false);
			proc.setDefaultContext(scope);
			proc.getValidContext().clear();
			if (scope != null) {
				proc.getValidContext().add(scope);
			}
		} finally {
			proc.eSetDeliver(oldDeliver);
		}
	}
	
	private void iteratEDataObject_(MethodElement srcObj) {
		diagramHandler.registerElement(srcObj, true);
		
		if (srcObj instanceof MethodPlugin) {
			MethodPlugin plugin = (MethodPlugin) srcObj;
			if (!isPluginSelected(plugin)) {
				return;
			}
		}

		if (isProcessed(srcObj.getGuid())) {
			return;
		}
		setProcessed(srcObj.getGuid());

		IModelObject targetObj = getXmlObject(srcObj);

		// if object is not created,
		// which means it's either a system package or something wrong
		if (targetObj == null) {
			if (srcObj instanceof MethodPackage) {
				// iterate the child packages
				for (Iterator it = ((MethodPackage) srcObj).getChildPackages()
						.iterator(); it.hasNext();) {
					iteratEDataObject((MethodElement) it.next());
				}
			}

			// // elements can be reference in other plugins
			// // don't need to care about this
			// else if (!isDiscarded(srcObj) ) {
			// logger.logWarning("Warning: xml object not created for " +
			// LibraryUtil.getTypeName(srcObj) );
			// }

			return;
		}
		
		handleDescriptorExtraReferences(srcObj, targetObj);		

		EClass eClass = srcObj.eClass();

		EList features = eClass.getEAllStructuralFeatures();
		for (Iterator it = features.iterator(); it.hasNext();) {
			EStructuralFeature feature = (EStructuralFeature) it.next();

			Object value = srcObj.eGet(feature);

			try {
				if (value instanceof List && ! feature.getName().equals("methodElementProperty")) {//$NON-NLS-1$	
					for (Iterator itv = ((List) value).iterator(); itv
							.hasNext();) {
						MethodElement src_value = (MethodElement) itv.next();

						// handle the
						// UmaPackage#getWorkBreakdownElement_LinkToPredecessor
						// feature value
						// the WorkOrder in uma is a process element in a
						// package
						// in xml model, it's an EDataObject contained by the
						// WorkBreakdownElement
						if (src_value instanceof WorkOrder) {
							// get the owner of the WorkOrder
							IModelObject workOrder = getXmlObject(src_value);
							if (workOrder == null) {
								createXmlObject(src_value, targetObj, feature
										.getName());
							}
							// System.out.println("workorder value");
						}

						// set the reference
						String xmlId = getXmlId(src_value.getGuid());
						xmlLib.setReferenceValue(targetObj, feature.getName(),
								xmlId, src_value.getType());

						iteratEDataObject(src_value);
					}
				} else if (value instanceof MethodElement) {
					// get the xml object and iterate again
					MethodElement src_value = (MethodElement) value;

					// if ( src_value instanceof WorkOrder ) {
					// System.out.println("workorder value");
					// }

					// elements like Presentation may not have a Content
					// Description
					// the one returned may not have a container
					if (src_value.eContainer() != null) {
						String xmlId = getXmlId(src_value.getGuid());
						xmlLib.setReferenceValue(targetObj, feature.getName(),
								xmlId, src_value.getType());

						iteratEDataObject(src_value);
					}
				} else if (!isDiscarded(srcObj)) {
					// if ( targetObj instanceof ContentCategoryPackage) {
					// System.out.println("hrre");
					// }

					if (value instanceof WorkOrderType) {
						value = ((WorkOrderType) value).getName();
					}

					xmlLib.setAtributeFeatureValue(targetObj,
							feature.getName(), value);
				}
			} catch (Exception e) {
				String msg = NLS.bind(
						ExportXMLResources.exportXMLService_feature_error,
						LibraryUtil.getTypeName(srcObj), feature.getName());
				logger.logError(msg, e);
			}

		}

	}

	// goid of processed element
	private List processedElements = new ArrayList();

	private boolean isProcessed(String guid) {
		return processedElements.contains(guid);
	}

	private void setProcessed(String guid) {
		if (!processedElements.contains(guid)) {
			processedElements.add(guid);
		}
	}

	private List getTopmostUserPackage(MethodPlugin plugin) {

		MethodPackage pkg_core_content = UmaUtil.findMethodPackage(plugin,
				ModelStructure.DEFAULT.coreContentPath);

		MethodPackage pkg_custom_categories = UmaUtil.findMethodPackage(plugin,
				ModelStructure.DEFAULT.customCategoryPath);

		MethodPackage pkg_disciplines = UmaUtil.findMethodPackage(plugin,
				ModelStructure.DEFAULT.disciplineDefinitionPath);

		MethodPackage pkg_domains = UmaUtil.findMethodPackage(plugin,
				ModelStructure.DEFAULT.domainPath);

		MethodPackage pkg_rolesets = UmaUtil.findMethodPackage(plugin,
				ModelStructure.DEFAULT.roleSetPath);

		MethodPackage pkg_tools = UmaUtil.findMethodPackage(plugin,
				ModelStructure.DEFAULT.toolPath);

		MethodPackage pkg_wptypes = UmaUtil.findMethodPackage(plugin,
				ModelStructure.DEFAULT.workProductTypePath);

		MethodPackage pkg_cp = UmaUtil.findMethodPackage(plugin,
				ModelStructure.DEFAULT.capabilityPatternPath);

		MethodPackage pkg_dp = UmaUtil.findMethodPackage(plugin,
				ModelStructure.DEFAULT.deliveryProcessPath);

		MethodPackage pkg_proc_contribution = UmaUtil.findMethodPackage(plugin,
				ModelStructure.DEFAULT.processContributionPath);

		List pkgs = new ArrayList();
		pkgs.add(pkg_core_content);
		pkgs.add(pkg_custom_categories);
		pkgs.add(pkg_disciplines);
		pkgs.add(pkg_domains);
		pkgs.add(pkg_rolesets);
		pkgs.add(pkg_tools);
		pkgs.add(pkg_wptypes);
		pkgs.add(pkg_cp);
		pkgs.add(pkg_dp);

		if ( pkg_proc_contribution != null ) {
			pkgs.add(pkg_proc_contribution);
		}
		
		return pkgs;

		// List systemPkgs = TngUtil.getAllSystemPackages(plugin);
		//		
		// List unprocessedPkgs = new ArrayList(plugin.getMethodPackages());
		// while (unprocessedPkgs.size() > 0 ) {
		// MethodPackage pkg = (MethodPackage) unprocessedPkgs.remove(0);
		// if ( !systemPkgs.contains(pkg) ) {
		// if ( !pkgs.contains(pkg) ) {
		// pkgs.add(pkg);
		// }
		// continue;
		// }
		//			
		// for ( Iterator it = pkg.getChildPackages().iterator(); it.hasNext();
		// ) {
		// MethodPackage p = (MethodPackage)it.next();
		// if ( systemPkgs.contains(p) )
		// {
		// if ( !unprocessedPkgs.contains(p) ) {
		// unprocessedPkgs.add(p);
		// }
		// } else {
		// if ( !pkgs.contains(p) ) {
		// pkgs.add(p);
		// }
		// }
		// }
		//			
		// if ( unprocessedPkgs.size() == 0 ) {
		// break;
		// }
		// }
		//		
		// // need to include the content packages
		// pkgs.addAll(TngUtil.getContentCategoryPackages(plugin));

	}
	public ExportXMLLogger getLogger() {
		return logger;
	}
	
	private Set<WorkOrder> getSuccessors() {
		if (successors == null) {
			successors = new HashSet<WorkOrder>();
		}
		return successors;
	}
	
	private void  handleSuccessors() {
		if (getSuccessors() == null) {
			return;
		}
		
		String fname = "linkToPredecessor";	//$NON-NLS-1$
		for (WorkOrder srcWorkOrder : getSuccessors()) {
			WorkBreakdownElement wbe = srcWorkOrder.getPred();
			if (wbe == null) {
				continue;
			}			
			IModelObject targetObj = getXmlObject(wbe);
			if (targetObj == null) {
				continue;
			}			
			IModelObject tgtWorkOrder = getXmlObject(srcWorkOrder);
			if (tgtWorkOrder == null) {
				createXmlObject(srcWorkOrder, targetObj, fname);
			}			
			String xmlId = getXmlId(srcWorkOrder.getGuid());
			if (xmlId == null) {
				continue;
			}
			try {
				xmlLib.setReferenceValue(targetObj, fname, xmlId, srcWorkOrder
						.getType());
			} catch (Exception e) {
				String msg = NLS.bind(
						ExportXMLResources.exportXMLService_feature_error,
						LibraryUtil.getTypeName(wbe), fname);
				logger.logError(msg, e);
			}
		}
	}
	
	private void handleDescriptorExtraReferences(MethodElement srcObj,
			IModelObject targetObj) {
		try {
			handleDescriptorExtraReferences_(srcObj, targetObj);
		} catch (Exception e) {
			logger.logError(e.getMessage(), e);
		}
	}
	
	private void handleDescriptorExtraReferences_(MethodElement srcObj,
			IModelObject targetObj) {
		if (!(srcObj instanceof Descriptor)) {
			return;
		}

		boolean ok = targetObj instanceof org.eclipse.epf.xml.uma.RoleDescriptor
				|| targetObj instanceof org.eclipse.epf.xml.uma.WorkProductDescriptor
				|| targetObj instanceof org.eclipse.epf.xml.uma.TaskDescriptor;

		if (!ok) {
			return;
		}

		Descriptor srcDes = (Descriptor) srcObj;
		org.eclipse.epf.xml.uma.BreakdownElement tgtDes = (org.eclipse.epf.xml.uma.BreakdownElement) targetObj;
		List<EReference> refList = LibraryEditUtil.getInstance()
				.getExcludeRefList(srcDes);
		
		for (EReference ref : refList) {
			handleExtraRef(srcDes, tgtDes, ref);		
		}		
		handleExtraRef(srcDes, tgtDes, org.eclipse.epf.uma.UmaPackage.eINSTANCE.getDescriptor_GuidanceExclude());	
		handleExtraRef(srcDes, tgtDes, org.eclipse.epf.uma.UmaPackage.eINSTANCE.getDescriptor_GuidanceAdditional());	
	}
	
	private void handleExtraRef(Descriptor srcDes,
			org.eclipse.epf.xml.uma.BreakdownElement tgtDes, EReference ref) {
		org.eclipse.epf.xml.uma.UmaPackage xmlUp = org.eclipse.epf.xml.uma.UmaPackage.eINSTANCE;
		EClass mepClass = xmlUp.getMethodElementProperty();
		
		List<MethodElement> refValueList = (List<MethodElement>) srcDes
				.eGet(ref);
		if (refValueList != null && !refValueList.isEmpty()) {
			List<org.eclipse.epf.xml.uma.MethodElementProperty> xmlMepList = tgtDes
					.getMethodElementProperty();
			org.eclipse.epf.xml.uma.MethodElementProperty xmlMep = (org.eclipse.epf.xml.uma.MethodElementProperty) EcoreUtil
					.create(mepClass);
			xmlMep.setName("XML_" + ref.getName()); //$NON-NLS-1$
			String value = ""; //$NON-NLS-1$

			for (int i = 0; i < refValueList.size(); i++) {
				MethodElement elem = refValueList.get(i);
				if (value.length() > 0) {
					value += DescriptorPropUtil.infoSeperator;
				}
				value += elem.getGuid();
			}
			xmlMep.setValue(value);

			xmlMepList.add(xmlMep);
		}
	}
	
}
