//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.msp;

import java.io.File;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.edit.provider.AdapterFactoryTreeIterator;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.XMLUtil;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.configuration.ProcessConfigurator;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.process.ActivityWrapperItemProvider;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.process.RoleDescriptorWrapperItemProvider;
import org.eclipse.epf.library.edit.process.TaskDescriptorWrapperItemProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.ConfigurableComposedAdapterFactory;
import org.eclipse.epf.library.edit.util.PredecessorList;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.msproject.Assignment;
import org.eclipse.epf.msproject.DocumentRoot;
import org.eclipse.epf.msproject.MsprojectFactory;
import org.eclipse.epf.msproject.PredecessorLink;
import org.eclipse.epf.msproject.Project;
import org.eclipse.epf.msproject.Resource;
import org.eclipse.epf.msproject.Task;
import org.eclipse.epf.msproject.util.MsprojectResourceImpl;
import org.eclipse.epf.publishing.services.PublishManager;
import org.eclipse.epf.publishing.services.PublishOptions;
import org.eclipse.epf.publishing.ui.wizards.PublishProgressMonitorDialog;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.Descriptor;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Milestone;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.RoleDescriptor;
import org.eclipse.epf.uma.TaskDescriptor;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkOrder;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.swt.widgets.Display;

/**
 * The default Export Microsoft Project Plan Service implementation.
 * 
 * @author Bingxue Xu
 * @author Kelvin Low
 * @since 1.0
 * 
 * Bugs fixed: https://bugs.eclipse.org/bugs/show_bug.cgi?id=155089
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=155086
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=155095
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=157265
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=155155
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=156959
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=157321
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=159230
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=162336
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=168801
 * fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=176951
 */
public class ExportMSPXMLService {

	// If true, generate debug traces.
	private static boolean debug = ExportMSPPlugin.getDefault().isDebugging();

	// All Tasks referenced by the exported Project Template.
	private List referencedTasks = new ArrayList();

	private HashMap rolesToUidMap = new HashMap();

	private HashMap taskUidToWbsWapperPathMap = new HashMap();

	private HashMap wbsWapperPathToLocalPredListMap = new HashMap();

	private HashMap wbsGuidToTaskUidMap = new HashMap();

	private HashMap wbsWrapperPathToPredListMap = new HashMap();

	// The name of the content folder. This will be named after the context.
	private String contentFolderName;

	private String abTargetDir;

	// If true, only export breakdown elements with 'isPlanned' attributes set
	// to true.
	private boolean exportOnlyPlannedElements;

	private boolean publishContentSite = false;

	private int task_uid = 1;

	private int res_uid = 1;

	private int assign_uid = 1;

	private MsprojectFactory projectFactory = MsprojectFactory.eINSTANCE;

	// The process to be exported.
	private Process process;

	private ConfigurableComposedAdapterFactory wbsAdapterFactory;

	// The process configurator for filtering breakdown elements in a
	// configuration.
	private ProcessConfigurator breakdownElementFilter;

	private IStructuredContentProvider wbsContentProvider;

	// Map processes to suppression objects.
	private Map suppressionMap = new HashMap();

	// The suppression object associated with the selected process to be
	// exported.
	private Suppression suppression;

	// The WBS element paths.
	private Stack elementPaths = new Stack();

	private Object currentElement;

	private String currentElementPath;

	private PredecessorList currentPredList;

	/**
	 * Creates a new instance.
	 */
	public ExportMSPXMLService() {
		super();
	}

	/**
	 * Export a process to a Microsoft Project XML file.
	 * 
	 * @param process
	 *            a capability pattern or delivery process
	 * @param exportOptions
	 *            a collection of user specified export options
	 * @throws ExportMSPServiceException
	 *             if an error occurs while executing the operation
	 */
	public boolean export(Process process, ExportMSPOptions exportOptions)
			throws ExportMSPServiceException {
		String msprojectName = exportOptions.getMSProjectName();
		File exportDir = exportOptions.getExportDir();
		publishContentSite = exportOptions.getPublishWebSite();
		PublishOptions publishingOptions = exportOptions.getPublishingOptions();

		if (debug) {
			System.out.println("$$$ exporting to Microsoft Project!"); //$NON-NLS-1$
			System.out.println("$$$ process                   = " + process); //$NON-NLS-1$
			System.out.println("$$$ msprojectName             = " //$NON-NLS-1$
					+ msprojectName);
			System.out
					.println("$$$ targetDir                 = " + exportDir.getAbsolutePath()); //$NON-NLS-1$
			System.out.println("$$$ exportOnlyPlannedElements = " //$NON-NLS-1$
					+ exportOnlyPlannedElements);
			System.out.println("$$$ publishConfigOptions      = " //$NON-NLS-1$
					+ publishingOptions);
		}

		// construct the export target xml file path
		if (!exportDir.exists()) {
			exportDir.mkdirs();
		}
		abTargetDir = exportDir.getAbsolutePath();
		Path exportPath = new Path(abTargetDir);
		boolean endWithXmlExt = msprojectName.toLowerCase().endsWith(".xml"); //$NON-NLS-1$
		String exportPathStr = (exportPath.append(endWithXmlExt ? msprojectName
				: (msprojectName + ".xml"))).toOSString(); //$NON-NLS-1$
		if (debug)
			System.out.println("$$$ exportPathStr                 = " //$NON-NLS-1$
					+ exportPathStr);

		// construct the empty MS project xml template file path
		String emptyTemplateFile = ExportMSPPlugin.getDefault()
				.getInstallPath()
				+ "template" //$NON-NLS-1$
				+ File.separator + "msproject_2003_template.xml"; //$NON-NLS-1$
		if (debug)
			System.out.println("$$$ emptyTemplateFile             = " //$NON-NLS-1$
					+ emptyTemplateFile);

		// copy the empty template MS project xml file to the export target
		try {
			File src = new File(emptyTemplateFile);
			File dst = new File(exportPathStr);
			FileUtil.copyFile(src, dst);
		} catch (Exception e) {
			e.printStackTrace();
		}

		Project project = null;
		URI fileURI = URI.createFileURI(exportPathStr);

		try {

			XMLResource res = new MsprojectResourceImpl(fileURI);
			res.getDefaultSaveOptions().put(
					XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
			res.getDefaultLoadOptions().put(
					XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
			res.getDefaultSaveOptions().put(XMLResource.OPTION_SCHEMA_LOCATION,
					Boolean.TRUE);
			res.getDefaultSaveOptions().put(
					XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE,
					Boolean.TRUE);
			res.getDefaultLoadOptions().put(
					XMLResource.OPTION_USE_LEXICAL_HANDLER, Boolean.TRUE);
			res.load(null);

			DocumentRoot docRoot = (DocumentRoot) res.getEObject("/"); //$NON-NLS-1$
			project = (Project) docRoot.getProject();

			generateMSProject(process, project, exportOptions);

			res.save(null);

			if (debug) {
				printMSProject(project);
			}

		} catch (Exception e) {
			e.printStackTrace();
			throw new ExportMSPException(e);
		}

		return true;
	}

	/**
	 * Exports a capability pattern or delivery process to a Microsoft Project
	 * XML file.
	 * 
	 * @param process
	 *            a capability pattern or delivery process
	 * @param project
	 *            a Microsoft Project object
	 * @param exportOptions
	 *            a collection of user specified export options
	 * @throws ExportMSPServiceException
	 *             if an error occurs while executing the operation
	 */
	public boolean generateMSProject(Process process, Project project,
			ExportMSPOptions exportOptions) throws Exception {
		if (process == null || project == null) {
			throw new IllegalArgumentException();
		}

		try {
			MethodConfiguration config = exportOptions.getMethodConfiguration();
			if (config == null) {
				// Get the default method configuration associated with the
				// process.
				if (process instanceof DeliveryProcess) {
					config = ((DeliveryProcess) process).getDefaultContext();
				} else if (process instanceof CapabilityPattern) {
					config = ((CapabilityPattern) process).getDefaultContext();
				} else {
					throw new IllegalArgumentException();
				}
			}

			// Create the sub folder to store the published HTML content files.
			contentFolderName = config.getName();

			PublishOptions publishingOptions = exportOptions
					.getPublishingOptions();
			if (publishContentSite && publishingOptions != null) {
				File contentDir = new File(exportOptions.getExportDir(),
						contentFolderName);
				if (!contentDir.exists()) {
					contentDir.mkdirs();
				}
				if (debug) {
					System.out.println("$$$ vieBuilder methodConfig = " //$NON-NLS-1$
							+ config);
					System.out.println("$$$ vieBuilder publishConfigOptions = " //$NON-NLS-1$
							+ publishingOptions);
				}

				// Publish the associated configuration.
				if (!publishConfiguration(contentDir.getAbsolutePath(), config,
						publishingOptions)) {
					return false;
				}
			}

			exportOnlyPlannedElements = exportOptions
					.getExportOnlyPlannedWBSElements();

			// Generate the Microsoft Project XML file.
			// populate the project's attributes
			project.setName(process.getName());
			project.setStartDate(new Date());
			project.setCreationDate(new Date());
			project.setLastSaved(new Date());
			project.setFinishDate(new Date());

			generateProjectResources(process, config, project);
			generateProjectTasks(process, config, project);
			generateLinks(process, project);

			return true;
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * Sets the export options.
	 * 
	 * @param exportOptions
	 *            a collection of user specified export options
	 */
	protected void setExportOptions(ExportOptions exportOptions) {
		Boolean exportOnlyPlannedElements = (Boolean) exportOptions
				.get(ExportOptions.EXPORT_ONLY_PLANNED_ELEMENTS);
		this.exportOnlyPlannedElements = exportOnlyPlannedElements
				.booleanValue();
	}

	/**
	 * Generates the project resources for all the task descriptors in the
	 * process.
	 * 
	 * @param process
	 *            a process
	 * @param config
	 *            a method configuration used to filter the work breakdown
	 *            elements in the process
	 * @param project
	 *            an object to store the generated Microsoft Project WBS
	 * @throws Exception
	 *             if an error occurs while generating the Microsoft Project WBS
	 */
	protected void generateProjectResources(Process process,
			MethodConfiguration config, Project project) throws Exception {
		ComposedAdapterFactory adapterFactory = null;
		try {
			adapterFactory = TngAdapterFactory.INSTANCE
					.createTBSComposedAdapterFactory();
			if (adapterFactory instanceof ConfigurableComposedAdapterFactory) {
				((ConfigurableComposedAdapterFactory) adapterFactory)
						.setFilter(new ProcessConfigurator(config, null));
			}
			IStructuredContentProvider contentProvider = new AdapterFactoryContentProvider(
					adapterFactory);

			List elements = process.getBreakdownElements();
			if (elements.size() > 0) {
				generateProjectResource(contentProvider,
						(BreakdownElement) process, project);
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (adapterFactory != null) {
				adapterFactory.dispose();
			}
		}
	}

	/**
	 * Generates the project resources for all the role descriptors in the
	 * process.
	 */
	protected void generateProjectResource(
			IStructuredContentProvider contentProvider,
			BreakdownElement breakdownElement, Project project)
			throws Exception {
		if (breakdownElement instanceof WorkProductDescriptor
				|| breakdownElement.getSuppressed().booleanValue()
				|| (exportOnlyPlannedElements && !breakdownElement
						.getIsPlanned().booleanValue())) {
			return;
		}

		if (breakdownElement instanceof RoleDescriptor) {
			addResource(breakdownElement, project);
			return;
		}

		if (contentProvider != null) {
			Object[] elements = contentProvider.getElements(breakdownElement);
			for (int i = 0; i < elements.length; i++) {
				Object element = elements[i];
				if (element instanceof RoleDescriptorWrapperItemProvider) {
					RoleDescriptorWrapperItemProvider provider = (RoleDescriptorWrapperItemProvider) element;
					Object value = provider.getValue();
					if (value instanceof RoleDescriptor) {
						addResource((BreakdownElement) value, project);
					}
				} else if (element instanceof RoleDescriptor) {
					addResource((BreakdownElement) element, project);
				} else if (element instanceof BreakdownElementWrapperItemProvider) {
					BreakdownElementWrapperItemProvider provider = (BreakdownElementWrapperItemProvider) element;
					Object value = provider.getValue();
					if (value instanceof WorkBreakdownElement) {
						generateProjectResource(contentProvider,
								(WorkBreakdownElement) value, project);
					}
				} else if (element instanceof WorkBreakdownElement) {
					generateProjectResource(contentProvider,
							(WorkBreakdownElement) element, project);
				}
			}
		}

	}

	// for each RoleDescriptor, create a MS Project resource
	// for the RoleDescriptor and its underlying role, remember the assigned
	// res_uid
	protected void addResource(BreakdownElement breakdownElement, Project proj)
			throws Exception {
		if (!(breakdownElement instanceof RoleDescriptor)) {
			return;
		}

		// check the existence of the underlying role of this roleDescriptor
		// and skip the creation if a resource for the role already exists
		RoleDescriptor roleDescriptor = (RoleDescriptor) breakdownElement;
		if (debug)
			System.out.println("$$$ handle RoleDescriptor = " + roleDescriptor); //$NON-NLS-1$
		Role ref_edRole = roleDescriptor.getRole();
		if (debug)
			System.out.println("$$$ handle Ref-ed Role = " + ref_edRole); //$NON-NLS-1$

		// check the need to add a new resource based on RoleDescriptor's disply
		// name
		boolean newRDResource = true;
		String rdResourceName = getDisplayName(roleDescriptor);
		if (rolesToUidMap.get(rdResourceName) != null) {
			newRDResource = false;
		}

		// check the need to add a new resource based on associated role's
		// disply name
		boolean newRoleReource = false;
		String roleResourceName = null;
		if (ref_edRole != null
				&& rolesToUidMap
						.get((roleResourceName = getDisplayName(ref_edRole))) == null
				&& !roleResourceName.equalsIgnoreCase(rdResourceName)) {
			newRoleReource = true;
		}

		// create a resource for the RoleDescriptor
		if (newRDResource) {
			Resource aRes = projectFactory.createResource();

			aRes.setUID(BigInteger.valueOf(res_uid));
			aRes.setID(BigInteger.valueOf(res_uid));
			aRes.setName(rdResourceName);
			proj.getResources().getResource().add(aRes);

			rolesToUidMap.put(rdResourceName, BigInteger.valueOf(res_uid));
			res_uid++;
		}

		// create a resource for the underlying associated role too
		if (newRoleReource) {
			Resource aRes = projectFactory.createResource();

			aRes.setUID(BigInteger.valueOf(res_uid));
			aRes.setID(BigInteger.valueOf(res_uid));
			aRes.setName(roleResourceName);
			proj.getResources().getResource().add(aRes);

			rolesToUidMap.put(roleResourceName, BigInteger.valueOf(res_uid));
			res_uid++;
		}
	}

	/**
	 * Generates the MS Project WBS for a capability pattern or delivery
	 * process.
	 * 
	 * @param process
	 *            a process
	 * @param config
	 *            a method configuration used to filter the work breakdown
	 *            elements in the process
	 * @param project
	 *            an object to store the generated Microsoft Project WBS
	 * @throws Exception
	 *             if an error occurs while generating the Microsoft Project WBS
	 */
	protected void generateProjectTasks(Process process,
			MethodConfiguration config, Project project) throws Exception {
		// Save the reference to the exported process.
		this.process = process;

		wbsAdapterFactory = null;
		try {
			// Add the suppression object associated with the process to be
			// exported
			// to the suppression map.
			suppression = new Suppression(process);
			suppressionMap.put(process, suppression);

			wbsAdapterFactory = (ConfigurableComposedAdapterFactory) TngAdapterFactory.INSTANCE
					.createWBSComposedAdapterFactory();
			breakdownElementFilter = new ProcessConfigurator(config, null);
			wbsAdapterFactory.setFilter(breakdownElementFilter);

			wbsContentProvider = new AdapterFactoryContentProvider(
					wbsAdapterFactory);

			// test
			// enumerateProcessPredecessorLists();

			currentElement = process;
			if (process instanceof CapabilityPattern) {
				generateProjectTask(wbsContentProvider,
						(BreakdownElement) process, 1, project);
			} else {
				List breakdownElements = process.getBreakdownElements();
				if (breakdownElements.size() > 0) {
					generateProjectTask(wbsContentProvider,
							(BreakdownElement) process, 1, project);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (wbsAdapterFactory != null) {
				wbsAdapterFactory.dispose();
			}
			if (suppressionMap != null) {
				suppressionMap.clear();
				suppressionMap = null;
			}
			if (wbsContentProvider != null) {
				wbsContentProvider.dispose();
			}
		}
	}

	private void enumerateProcessPredecessorLists() {
		// WBS tree
		Iterator wbsTreeIterator = new AdapterFactoryTreeIterator(
				wbsAdapterFactory, process);
		Object obj;
		while (wbsTreeIterator.hasNext()) {
			obj = wbsTreeIterator.next();
			System.out.println("treeIterator: " + obj);
			IBSItemProvider adapter = (IBSItemProvider) wbsAdapterFactory
					.adapt(obj, ITreeItemContentProvider.class);
			PredecessorList predList = adapter.getPredecessors();
			for (Iterator iter = predList.iterator(); iter.hasNext();) {
				IBSItemProvider e = (IBSItemProvider) iter.next();
				System.out.println("    predList: " + e);
				if (e instanceof ItemProviderAdapter) {
					System.out.println("    unwrappedPredList: "
							+ ((ItemProviderAdapter) e).getTarget());
				}
			}
		}
	}

	/**
	 * Generates the Microsft Project task for a breakdown element.
	 * 
	 * @param contentProvider
	 *            a content provider
	 * @param breakdownElement
	 *            a breakdown element
	 * @param strBuf
	 *            a <code>StringBuffer</code> to store the generated XML
	 */
	protected void generateProjectTask(
			IStructuredContentProvider contentProvider,
			Object elementOrWrapper, int taskOLevel, Project proj)
			throws Exception {

		WorkBreakdownElement breakdownElement = (WorkBreakdownElement) TngUtil
				.unwrap(elementOrWrapper);

		// not really neccessary here
		if (breakdownElement instanceof WorkProductDescriptor
				|| breakdownElement instanceof RoleDescriptor
				|| breakdownElement.getSuppressed().booleanValue()
				|| (exportOnlyPlannedElements && !breakdownElement
						.getIsPlanned().booleanValue())) {
			return;
		}

		boolean isSubTasksPlanned = false;
		if (exportOnlyPlannedElements && breakdownElement instanceof Activity
				&& contentProvider != null) {
			Object[] elements = contentProvider.getElements(elementOrWrapper);
			for (int i = 0; i < elements.length; i++) {
				Object element = elements[i];
				if (element instanceof Activity) {
					if (!exportOnlyPlannedElements
							|| ((Activity) element).getIsPlanned()
									.booleanValue()) {
						isSubTasksPlanned = true;
						break;
					}
				} else if (element instanceof ActivityWrapperItemProvider) {
					Object wrappedElement = TngUtil.unwrap(element);
					if (wrappedElement instanceof Activity) {
						if (!exportOnlyPlannedElements
								|| ((Activity) wrappedElement).getIsPlanned()
										.booleanValue()) {
							isSubTasksPlanned = true;
							break;
						}
					}
				} else if (element instanceof TaskDescriptor) {
					TaskDescriptor descriptor = (TaskDescriptor) element;
					if (!exportOnlyPlannedElements
							|| descriptor.getIsPlanned().booleanValue()) {
						isSubTasksPlanned = true;
						break;
					}
				} else if (element instanceof TaskDescriptorWrapperItemProvider) {
					Object wrappedElement = TngUtil.unwrap(element);
					if (wrappedElement instanceof TaskDescriptor) {
						TaskDescriptor descriptor = (TaskDescriptor) wrappedElement;
						if (!exportOnlyPlannedElements
								|| descriptor.getIsPlanned().booleanValue()) {
							isSubTasksPlanned = true;
							break;
						}
					}
				}
			}
		}

		// create a task for the WorkBreakdownElement
		// decided just to check the isPlanned flag on the WBS
		boolean isPlannedTask = breakdownElement.getIsPlanned().booleanValue();
		Task newTask = null;
		if (!exportOnlyPlannedElements || exportOnlyPlannedElements
				&& isPlannedTask) {
			boolean suppressed = isSuppressed(breakdownElement);
			if (!suppressed) {
				newTask = addTask(elementOrWrapper, taskOLevel, proj);
			}
		}

		// if export planned only wbs, then we need to do the role rollup
		// calculation
		if (exportOnlyPlannedElements && newTask != null
				&& breakdownElement instanceof Activity
				&& contentProvider != null && !isSubTasksPlanned) {
			ArrayList rollupRoles = new ArrayList();
			boolean rb = calculateRollupRoles(contentProvider,
					breakdownElement, rollupRoles);
			// if the whole subtree of the breakdownElemnt is not planned
			// then roll up all the roles
			if (!rb) {
				HashSet rolesSet = new HashSet(rollupRoles);
				for (Iterator iter = rolesSet.iterator(); iter.hasNext();) {
					String roleName = (String) iter.next();
					addAssignment(roleName, newTask.getUID().intValue(), proj);
				}
			}
		}

		// export the next level wbs
		if (contentProvider != null) {
			boolean suppressed = isSuppressed(breakdownElement);
			if (!suppressed) {
				elementPaths.push(breakdownElement.getGuid());
				Object[] elements = contentProvider
						.getElements(elementOrWrapper);
				for (int i = 0; i < elements.length; i++) {
					Object element = elements[i];

					// get the current elementOrWrapper and the hierarcal guid
					// path to it
					currentElement = element;
					String[] paths = new String[elementPaths.size()];
					elementPaths.toArray(paths);
					StringBuffer pathStr = new StringBuffer();
					for (int j = 0; j < paths.length; j++) {
						pathStr.append(paths[j] + ".");
					}
					if (currentElement instanceof BreakdownElementWrapperItemProvider) {
						Object wrapped = TngUtil.unwrap(element);
						pathStr.append(((BreakdownElement) wrapped).getGuid());
					} else {
						pathStr.append(((BreakdownElement) currentElement)
								.getGuid());
					}
					currentElementPath = pathStr.toString();
					// if (debug) System.out.println(" path: " +
					// currentElementPath);

					generateProjectTask(contentProvider, element,
							taskOLevel + 1, proj);
				}
				generateLinks(process, proj);
				elementPaths.pop();
			}
		}

	}

	/**
	 * Checks whether the given object is a suppressed work breakdown element in
	 * its owning process.
	 * 
	 * @param object
	 *            an object
	 * @return <ocde>true</code> if the object is a suppressed work breakdown
	 *         element in its owning process.
	 */
	protected boolean isSuppressed(Object object) {
		if (object != null) {
			if (object instanceof Descriptor) {
				if (debug)
					System.out.println("Descriptor = "
							+ ((Descriptor) object).getName());
			}
			Process owningProcess = TngUtil.getOwningProcess(object);
			Suppression owningProcessSuppression = (Suppression) suppressionMap
					.get(owningProcess);
			if (owningProcessSuppression == null) {
				owningProcessSuppression = new Suppression(owningProcess);
				suppressionMap.put(owningProcess, owningProcessSuppression);
			}
			if (owningProcessSuppression.isSuppressed(object)) {
				return true;
			}
			if (owningProcess != process
					&& object instanceof WorkBreakdownElement) {
				elementPaths.push(((WorkBreakdownElement) object).getGuid());
				String[] paths = new String[elementPaths.size()];
				elementPaths.toArray(paths);
				Object wrapper = suppression.getObjectByPath(paths,
						wbsAdapterFactory);
				elementPaths.pop();
				return suppression.isSuppressed(wrapper);
			}
		}
		return false;
	}

	/**
	 * Adds a task to a Microsoft Project.
	 * 
	 * @param element
	 *            a work breakdown element
	 * @param taskOLevel
	 *            the outline level
	 * @param project
	 *            a Microsoft Project object
	 * @return the newly added task
	 * @throws Exception
	 *             if an error occurrs while performing the operation
	 */
	protected Task addTask(Object elementOrWrapper, int taskOLevel,
			Project project) throws Exception {

		if (elementOrWrapper == null) {
			return null;
		}

		WorkBreakdownElement element = (WorkBreakdownElement) TngUtil
				.unwrap(elementOrWrapper);

		Task task = projectFactory.createTask();
		task.setName(getDisplayName(element));
		task.setOutlineLevel(BigInteger.valueOf(taskOLevel));
		task.setUID(BigInteger.valueOf(task_uid));
		task.setID(BigInteger.valueOf(task_uid));
		task.setType(BigInteger.valueOf(0));

		GregorianCalendar gcDate = new GregorianCalendar();
		// gcDate.add(GregorianCalendar.DATE, 80);
		Date startDate = gcDate.getTime();
		task.setStart(startDate);

		// task.setDuration("PT20H0M0S");

		String notes = getBriefDescription(element);
		if (notes != null || notes.trim().length() > 0) {
			task.setNotes(notes);
		}

		if (element instanceof Milestone) {
			task.setMilestone(true);
			task.setDurationFormat(BigInteger.valueOf(7));
		}

		// Assign the task to all the associated roles.
		List rolesList = null;
		if (element instanceof TaskDescriptor) {
			rolesList = getRolesForTaskD((TaskDescriptor) element);
		} else if (element instanceof org.eclipse.epf.uma.Task) {
			rolesList = getRolesForTask((org.eclipse.epf.uma.Task) element);
		}
		if (rolesList != null) {
			for (Iterator iter = rolesList.iterator(); iter.hasNext();) {
				String roleName = (String) iter.next();
				addAssignment(roleName, task_uid, project);
			}
		}

		// Add the generated URL link to the task.
		if (publishContentSite) {
			String linkURL = getElementURL(element);
			if (element instanceof TaskDescriptor) {
				TaskDescriptor taskDescriptor = (TaskDescriptor) element;
				org.eclipse.epf.uma.Task ref_edTask = taskDescriptor.getTask();
				referencedTasks.add(ref_edTask);
			}
			task.setHyperlinkAddress(linkURL);
		}

		// aTask.setType(new BigInteger("1"));
		// aTask.setStart(new Date());
		// aTask.setSummary(false);
		// aTask.setConstraintType(new BigInteger("2"));

		// Add the task to the Microsoft Project object.
		project.getTasks().getTask().add(task);

		if (debug) {
			System.out.println("$$$ theCurrent element: taskUid=" + task_uid
					+ ", " + currentElement);
			System.out.println("                  path: " + currentElementPath);
		}

		// Store the task's local predecessors.
		storeTaskPredecessors(element);

		taskUidToWbsWapperPathMap.put(BigInteger.valueOf(task_uid),
				currentElementPath);
		wbsGuidToTaskUidMap
				.put(element.getGuid(), BigInteger.valueOf(task_uid));

		// get predecessors of a work breakdown element
		IBSItemProvider adapter = (IBSItemProvider) wbsAdapterFactory.adapt(
				elementOrWrapper, ITreeItemContentProvider.class);
		PredecessorList currentPredList = adapter.getPredecessors();
		List guidPredList = new ArrayList();
		for (Iterator iter = currentPredList.iterator(); iter.hasNext();) {
			Object e = (Object) iter.next();
			if (debug)
				System.out.println("    wrapperPredListMember: " + e);
			Object unwrappedE = TngUtil.unwrap(e);
			if (unwrappedE instanceof WorkBreakdownElement) {
				guidPredList.add(((WorkBreakdownElement) unwrappedE).getGuid());
				if (debug)
					System.out.println("    unwrappedPredListMember: "
							+ unwrappedE);
			}
			if (e instanceof ItemProviderAdapter) {
				unwrappedE = ((ItemProviderAdapter) e).getTarget();
				guidPredList.add(((BreakdownElement) unwrappedE).getGuid());
				if (debug)
					System.out.println("    unwrappedPredListMember: "
							+ unwrappedE);
			}
		}
		wbsWrapperPathToPredListMap.put(currentElementPath, guidPredList);
		if (debug)
			System.out.println("    __wrapperPredList: " + guidPredList);

		task_uid++;

		return task;
	}

	private String getBriefDescription(WorkBreakdownElement element) {
		if (element == null)
			return null;

		String briefDesc = element.getBriefDescription();
		if ((briefDesc == null || briefDesc.trim().length() <= 0)) {
			if (element instanceof TaskDescriptor) {
				TaskDescriptor taskDescriptor = (TaskDescriptor) element;
				org.eclipse.epf.uma.Task ref_edTask = taskDescriptor.getTask();
				if (ref_edTask != null)
					briefDesc = ref_edTask.getBriefDescription();
			}
		}

		return briefDesc;
	}

	private void addAssignment(String resName, int taskUid, Project proj) {
		Assignment assignment = projectFactory.createAssignment();

		assignment.setUID(BigInteger.valueOf(assign_uid));
		assignment.setTaskUID(BigInteger.valueOf(taskUid));
		BigInteger resID = (BigInteger) rolesToUidMap.get(resName);
		assignment.setResourceUID(resID);

		proj.getAssignments().getAssignment().add(assignment);

		assign_uid++;
	}

	private List getRolesForTaskD(TaskDescriptor taskDescriptor) {
		ArrayList rolesList = new ArrayList();

		// RoleDescriptor roleDescrp = taskDescriptor.getPerformedPrimarilyBy();
		RoleDescriptor roleDescrp = (RoleDescriptor) ConfigurationHelper
				.getCalculatedElement(taskDescriptor.getPerformedPrimarilyBy(),
						breakdownElementFilter.getMethodConfiguration());

		if (roleDescrp != null) {
			rolesList.add(getDisplayName(roleDescrp));
		}
		// List roleDescrpList = taskDescriptor.getAdditionallyPerformedBy();
		List roleDescrpList = ConfigurationHelper.getCalculatedElements(
				taskDescriptor.getAdditionallyPerformedBy(),
				breakdownElementFilter.getMethodConfiguration());

		for (Iterator iter = roleDescrpList.iterator(); iter.hasNext();) {
			roleDescrp = (RoleDescriptor) iter.next();
			rolesList.add(getDisplayName(roleDescrp));
		}

		return rolesList;
	}

	private List getRolesForTask(org.eclipse.epf.uma.Task umaTask) {
		ArrayList rolesList = new ArrayList();

		Role role = umaTask.getPerformedBy();
		if (role != null) {
			rolesList.add(getDisplayName(role));
		}
		List list = umaTask.getAdditionallyPerformedBy();
		for (Iterator iter = list.iterator(); iter.hasNext();) {
			role = (Role) iter.next();
			rolesList.add(getDisplayName(role));
		}

		return rolesList;
	}

	private boolean calculateRollupRoles(
			IStructuredContentProvider contentProvider,
			BreakdownElement breakdownElement, List rollupRoles) {

		boolean isAnySubTaskPlanned = false;

		Object[] elements = contentProvider.getElements(breakdownElement);
		for (int i = 0; i < elements.length; i++) {
			Object element = elements[i];
			if (element instanceof Activity) {
				if (!exportOnlyPlannedElements
						|| ((Activity) element).getIsPlanned().booleanValue()) {
					isAnySubTaskPlanned = true;
				} else {
					isAnySubTaskPlanned = calculateRollupRoles(contentProvider,
							(BreakdownElement) element, rollupRoles);
				}
			} else if (element instanceof ActivityWrapperItemProvider) {
				Object wrappedElement = TngUtil.unwrap(element);
				if (wrappedElement instanceof Activity) {
					if (!exportOnlyPlannedElements
							|| ((Activity) wrappedElement).getIsPlanned()
									.booleanValue()) {
						isAnySubTaskPlanned = true;
					} else {
						isAnySubTaskPlanned = calculateRollupRoles(
								contentProvider,
								(BreakdownElement) wrappedElement, rollupRoles);
					}
				}
			} else if (element instanceof TaskDescriptor) {
				TaskDescriptor descriptor = (TaskDescriptor) element;
				if (!exportOnlyPlannedElements
						|| descriptor.getIsPlanned().booleanValue()) {
					isAnySubTaskPlanned = true;
				} else {
					rollupRoles
							.addAll(getRolesForTaskD((TaskDescriptor) element));
				}
			} else if (element instanceof TaskDescriptorWrapperItemProvider) {
				Object wrappedElement = TngUtil.unwrap(element);
				if (wrappedElement instanceof TaskDescriptor) {
					TaskDescriptor descriptor = (TaskDescriptor) wrappedElement;
					if (!exportOnlyPlannedElements
							|| descriptor.getIsPlanned().booleanValue()) {
						isAnySubTaskPlanned = true;
					} else {
						rollupRoles
								.addAll(getRolesForTaskD((TaskDescriptor) wrappedElement));
					}
				}
			}
		}

		return isAnySubTaskPlanned;
	}

	/**
	 * Retrieves a work breakdown element's predecessors, stores them in an
	 * <ocde>ArrayList</code>, and put it into a map.
	 * 
	 * @param element
	 *            a work breakdown element
	 */
	private void storeTaskPredecessors(WorkBreakdownElement element) {
		if (element == null) {
			return;
		}

		List predecessors = element.getLinkToPredecessor();
		List predList = new ArrayList();
		if (predecessors != null && predecessors.size() > 0) {
			for (Iterator i = predecessors.iterator(); i.hasNext();) {
				WorkOrder workOrder = (WorkOrder) i.next();
				BreakdownElement predecessor = workOrder.getPred();
				if (debug) {
					System.out.println("    localPredListMember: "
							+ predecessor);
				}
				if (predecessor != null) {
					String predGuid = predecessor.getGuid();
					if (predGuid != null)
						predList.add(predGuid);
				}
			}
		}
		if (debug) {
			System.out.println("   local predlist for " + element.getName()
					+ " = " + predList.toString());
		}

		wbsWapperPathToLocalPredListMap.put(currentElementPath, predList);
	}

	protected void generateLinks(Process process, Project project)
			throws Exception {
		EList tasks = project.getTasks().getTask();
		for (Iterator iter = tasks.iterator(); iter.hasNext();) {
			Task task = (Task) iter.next();
			BigInteger taskUid = task.getUID();
			// skip the MS project hidden task with uid = 0
			if (taskUid.intValue() == 0)
				continue;

			String wbsPathStr = (String) taskUidToWbsWapperPathMap.get(taskUid);

			// List predList = (ArrayList)
			// wbsWapperPathToLocalPredListMap.get(wbsPathStr);
			List predList = (ArrayList) wbsWrapperPathToPredListMap
					.get(wbsPathStr);
			if (predList != null) {
				List removeList = new ArrayList();
				for (Iterator iterator = predList.iterator(); iterator
						.hasNext();) {
					String predGuid = (String) iterator.next();
					BigInteger predTaskUid = (BigInteger) wbsGuidToTaskUidMap
							.get(predGuid);

					if (predTaskUid == null
							|| predTaskUid.intValue() == taskUid.intValue()) {
						continue;
					}

					if (debug) {
						System.out.println("$$$ taskUid = " + taskUid
								+ ", wbsPathStr = " + wbsPathStr);
						System.out.println("    localPredList: " + predList);
						System.out.println("    found pred guid: " + predGuid);
					}

					removeList.add(predGuid);

					PredecessorLink preLink = projectFactory
							.createPredecessorLink();
					task.getPredecessorLink().add(preLink);
					preLink.setPredecessorUID(predTaskUid);
					preLink.setType(new BigInteger("1")); //$NON-NLS-1$
					preLink.setCrossProject(false);
					preLink.setLinkLag(new BigInteger("0")); //$NON-NLS-1$
					preLink.setLagFormat(new BigInteger("7")); //$NON-NLS-1$
				}
				predList.removeAll(removeList);
			}
		}
	}

	/**
	 * Returns the generated HTML content file URL for a method element.
	 * 
	 * @param element
	 *            a method element
	 * @return the URL of the generated HTML content file
	 */
	protected String getElementURL(MethodElement element) {
		if (element == null)
			return null;

		String elementPath = null;
		String elementFileName = null;
		try {
			elementPath = ResourceHelper.getElementPath(element);
			elementFileName = ResourceHelper.getFileName(element,
					ResourceHelper.FILE_EXT_HTML);
		} catch (Exception e) {
			e.printStackTrace();
			return ""; //$NON-NLS-1$
		}
		if (elementPath != null && elementFileName != null) {
			elementPath = elementPath.replace('\\', '/');
			elementFileName = elementFileName.replace('\\', '/');
			String url = contentFolderName
					+ "/" + elementPath + elementFileName; //$NON-NLS-1$
			return abTargetDir + File.separator + url;
		} else {
			return ""; //$NON-NLS-1$
		}
	}

	/**
	 * Returns the display name of a method element.
	 * 
	 * @param element
	 *            a method element
	 * @return the display name of the given element
	 */
	protected String getDisplayName(MethodElement element) {
		String name = null;
		if (element instanceof BreakdownElement) {
			name = ProcessUtil.getPresentationName((BreakdownElement) element);
		} else if (element instanceof DescribableElement) {
			name = ((DescribableElement) element).getPresentationName();
		}
		if (name == null || name.length() == 0) {
			name = element.getName();
		}
		return XMLUtil.escapeAttr(name);
	}

	/**
	 * Publishes the selected configuration associated with the exported
	 * process.
	 * 
	 * @param dir
	 *            the output directory
	 * @param config
	 *            the configuration to publish
	 * @param publishConfigOptions
	 *            the publishing options
	 * @return <code>true</code> if the configuration was published
	 *         successfully, <code>false</code> otherwise
	 * @throws Exception
	 *             if an error occurs while publishing the configuration
	 */
	protected boolean publishConfiguration(String dir,
			MethodConfiguration config, PublishOptions publishConfigOptions)
			throws Exception {
		PublishManager publishMgr = null;
		try {
			publishMgr = new PublishManager();
			publishMgr.init(dir, config, publishConfigOptions);

			ExportMSPXMLOperation operation = new ExportMSPXMLOperation(
					publishMgr);
			PublishProgressMonitorDialog dlg = new PublishProgressMonitorDialog(
					Display.getCurrent().getActiveShell(), publishMgr
							.getViewBuilder());
			boolean success = UserInteractionHelper.runWithProgress(operation,
					dlg, true, ExportMSPResources.exportMSPWizard_title);
			if (operation.getException() != null) {
				throw operation.getException();
			}
			return success && !dlg.getProgressMonitor().isCanceled();
		} catch (Exception e) {
			throw e;
		} finally {
			if (publishMgr != null) {
				publishMgr.dispose();
				publishMgr = null;
			}
		}
	}

	/**
	 * Prints the trace information for the Microsoft Project.
	 */
	private static void printMSProject(Project project) {
		System.out.println("\n$$$ read-in project = " + project); //$NON-NLS-1$

		EList tasks = project.getTasks().getTask();
		for (Iterator iter = tasks.iterator(); iter.hasNext();) {
			Task element = (Task) iter.next();
			System.out.println("$$$ a task = " + element); //$NON-NLS-1$
		}

		EList resources = project.getResources().getResource();
		for (Iterator iter = resources.iterator(); iter.hasNext();) {
			org.eclipse.epf.msproject.Resource element = (org.eclipse.epf.msproject.Resource) iter
					.next();
			System.out.println("$$$ a resource = " + element); //$NON-NLS-1$
		}

		EList assignments = project.getAssignments().getAssignment();
		for (Iterator iter = assignments.iterator(); iter.hasNext();) {
			Assignment element = (Assignment) iter.next();
			System.out.println("$$$ an assignment = " + element); //$NON-NLS-1$
		}

		System.out.println("$$$===\n"); //$NON-NLS-1$
	}

}
