//------------------------------------------------------------------------------
// 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.lang.reflect.InvocationTargetException;
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.IProgressMonitor;
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.EAttribute;
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.UIHelper;
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.PublishHTMLOptions;
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.UmaPackage;
import org.eclipse.epf.uma.WorkBreakdownElement;
import org.eclipse.epf.uma.WorkOrder;
import org.eclipse.epf.uma.WorkOrderType;
import org.eclipse.epf.uma.WorkProductDescriptor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
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
 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=177428
 */
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.
	protected boolean exportOnlyPlannedElements;

	private boolean publishContentSite = false;

	private int task_uid = 1;

	private int res_uid = 1;

	private int assign_uid = 1;

	protected MsprojectFactory projectFactory = MsprojectFactory.eINSTANCE;

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

	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;
	
	private HashMap<Task, WorkBreakdownElement> taskToWbeMap;

	/**
	 * 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();
		processConfig = exportOptions.getMethodConfiguration();
		if (debug) {
			System.out.println("$$$ exporting to Microsoft Project!"); //$NON-NLS-1$
			System.out.println("$$$ process          = " + process); //$NON-NLS-1$
			System.out.println("$$$ configuration    = " + processConfig); //$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();

			taskToWbeMap = new HashMap<Task, WorkBreakdownElement>();
			if (! generateMSProject(process, project, exportOptions)) {
				return false;
			}

			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());
			
			setProjectExtendedAttributes(project);

			generateOperatonRun(process, project, config);
			
			return true;
		} catch (Exception e) {
			throw e;
		}
	}

	private void generateOperatonRun(Process process, Project project,
			MethodConfiguration config) throws InvocationTargetException,
			InterruptedException {
		final Process fprocess = process;
		final Project fproject = project;
		final MethodConfiguration fconfig = config;
		
		IRunnableWithProgress op = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
					throws InvocationTargetException {
				try {
					monitor.beginTask(ExportMSPResources.exportMSPWizard_title,
							IProgressMonitor.UNKNOWN);

					generate(fprocess, fproject, fconfig);
				} catch (Exception e) {
					throw new InvocationTargetException(e);
				} finally {
					monitor.done();
				}
			}
		};
		ProgressMonitorDialog pmDialog = new ProgressMonitorDialog(Display.getCurrent().getActiveShell());
		pmDialog.run(true, false, op);
	}

	private void generate(Process process, Project project,
			MethodConfiguration config) throws Exception {
		generateProjectResources(process, config, project);
		generateProjectTasks(process, config, project);
		generateLinks(process, project);
		generateWPDs(config);
	}

	/**
	 * 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));
			}
			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);
			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); //$NON-NLS-1$
			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); //$NON-NLS-1$
				if (e instanceof ItemProviderAdapter) {
					System.out.println("    unwrappedPredList: " //$NON-NLS-1$
							+ ((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] + "."); //$NON-NLS-1$
					}
					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 = " //$NON-NLS-1$
							+ ((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 {
		Task task = addTask_(elementOrWrapper, taskOLevel, project);
		if (task != null) {
			WorkBreakdownElement element = (WorkBreakdownElement) TngUtil
				.unwrap(elementOrWrapper);
			taskToWbeMap.put(task, element);
		}
		return task;
	}
	
	private 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));
			task.setDuration("PT0H0M0S");
		} else {
			task.setMilestone(false);
		}

		// 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 //$NON-NLS-1$
					+ ", " + currentElement); //$NON-NLS-1$
			System.out.println("                  path: " + currentElementPath); //$NON-NLS-1$
		}

		// 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<MethodElement> guidPredList = new ArrayList<MethodElement>();
		for (Iterator iter = currentPredList.iterator(); iter.hasNext();) {
			Object e = (Object) iter.next();
			if (debug)
				System.out.println("    wrapperPredListMember: " + e); //$NON-NLS-1$
			Object unwrappedE = TngUtil.unwrap(e);
			if (unwrappedE instanceof WorkBreakdownElement) {
				//guidPredList.add(((WorkBreakdownElement) unwrappedE).getGuid());
				guidPredList.add((WorkBreakdownElement) unwrappedE);
				if (debug)
					System.out.println("    unwrappedPredListMember: " //$NON-NLS-1$
							+ unwrappedE);
			}
			if (e instanceof ItemProviderAdapter) {
				unwrappedE = ((ItemProviderAdapter) e).getTarget();
				//guidPredList.add(((BreakdownElement) unwrappedE).getGuid());
				guidPredList.add((BreakdownElement) unwrappedE);
				if (debug)
					System.out.println("    unwrappedPredListMember: " //$NON-NLS-1$
							+ unwrappedE);
			}
		}
		wbsWrapperPathToPredListMap.put(currentElementPath, guidPredList);
		if (debug)
			System.out.println("    __wrapperPredList: " + guidPredList); //$NON-NLS-1$

		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) {
					MethodElement realizedElement = ConfigurationHelper.getCalculatedElement(ref_edTask, processConfig);
					if (debug) System.out.println("$$$ realizedElement = " + realizedElement); //$NON-NLS-1$
					if (realizedElement != null) {
						EAttribute attribute = UmaPackage.eINSTANCE.getMethodElement_BriefDescription();
						Object briefDescObj = ConfigurationHelper.calcAttributeFeatureValue(realizedElement, attribute, processConfig);
						briefDesc = briefDescObj.toString();
						if (debug) System.out.println("$$$ realized brief desc = " + briefDesc);	 //$NON-NLS-1$
					}
				}
			}
		}

		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();

		for (RoleDescriptor rd : taskDescriptor.getPerformedPrimarilyBy()) {

			// RoleDescriptor roleDescrp =
			// taskDescriptor.getPerformedPrimarilyBy();
			RoleDescriptor roleDescrp = (RoleDescriptor) ConfigurationHelper
					.getCalculatedElement(rd, 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();) {
			RoleDescriptor roleDescrp = (RoleDescriptor) iter.next();
			rolesList.add(getDisplayName(roleDescrp));
		}

		return rolesList;
	}

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

		for (Role role: umaTask.getPerformedBy()) {
			if (role != null) {
				rolesList.add(getDisplayName(role));
			}
		}

		List list = umaTask.getAdditionallyPerformedBy();
		for (Iterator iter = list.iterator(); iter.hasNext();) {
			Role 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: " //$NON-NLS-1$
							+ predecessor);
				}
				if (predecessor != null) {
					String predGuid = predecessor.getGuid();
					if (predGuid != null)
						predList.add(predGuid);
				}
			}
		}
		if (debug) {
			System.out.println("   local predlist for " + element.getName() //$NON-NLS-1$
					+ " = " + predList.toString()); //$NON-NLS-1$
		}

		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);

			HashMap<String, WorkOrder> predGuidToWOMap = getPredGuidToWOMap(taskToWbeMap.get(task));
			
			// 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();
					MethodElement predElem = (MethodElement) iterator.next();
					String predGuid = predElem.getGuid();
					
					BigInteger predTaskUid = (BigInteger) wbsGuidToTaskUidMap
							.get(predGuid);

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

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

					//removeList.add(predGuid);
					removeList.add(predElem);

					PredecessorLink preLink = projectFactory
							.createPredecessorLink();
					task.getPredecessorLink().add(preLink);
					preLink.setPredecessorUID(predTaskUid);
					
					//preLink.setType(new BigInteger("1")); //$NON-NLS-1$
					BigInteger bigInt = getLinkTypeInt(predGuidToWOMap.get(predGuid));
					if (bigInt != null) {
						preLink.setType(bigInt);
					}
					
					preLink.setCrossProject(false);
					preLink.setLinkLag(new BigInteger("0")); //$NON-NLS-1$
					preLink.setLagFormat(new BigInteger("7")); //$NON-NLS-1$
				}
				predList.removeAll(removeList);
			}
		}
	}

	private BigInteger getLinkTypeInt(WorkOrder wo) {
		if (wo == null) {
			if (debug) {
				System.out.println("Warning> getLinkTypeInt, wo == null.");//$NON-NLS-1$
			}
			return null;
		}
		WorkOrderType woType = wo.getLinkType();
		if (woType == WorkOrderType.FINISH_TO_START) {
			return new BigInteger("1"); //$NON-NLS-1$
		} 
		if (woType == WorkOrderType.START_TO_START) {
			return new BigInteger("3"); //$NON-NLS-1$
		} 
		if (woType == WorkOrderType.FINISH_TO_FINISH) {
			return new BigInteger("0"); //$NON-NLS-1$
		}
		if (woType == WorkOrderType.START_TO_FINISH) {
			return new BigInteger("2"); //$NON-NLS-1$
		}
		return null;
	}

	private HashMap<String, WorkOrder> getPredGuidToWOMap(WorkBreakdownElement wbe) {
		HashMap<String, WorkOrder> predGuidToWOMap = new HashMap<String, WorkOrder>();
		if (wbe != null) {
			List<WorkOrder> woList = wbe.getLinkToPredecessor();
			int sz = woList == null ? 0 : woList.size();
			for (int i = 0; i < sz; i++) {
				WorkOrder wo = woList.get(i);
				if (wo == null || wo.getPred() == null) {
					continue;
				}
				predGuidToWOMap.put(wo.getPred().getGuid(), wo);
			}
		}
		return predGuidToWOMap;
	}

	/**
	 * 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 name;
		
		//This is not needed since EMF would take care of encoding
		//suring save
		//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, new PublishHTMLOptions(
					publishConfigOptions));

			ExportMSPXMLOperation operation = new ExportMSPXMLOperation(
					publishMgr);
			PublishProgressMonitorDialog dlg = new PublishProgressMonitorDialog(
					Display.getCurrent().getActiveShell(), publishMgr
							.getViewBuilder());
			boolean success = UIHelper.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$
	}
	
	protected HashMap<Task, WorkBreakdownElement> getTaskToWbeMap() {
		return taskToWbeMap;
	}
	
	//To be overriden by subclasses
	protected void setProjectExtendedAttributes(Project project) {
	}

	//To be overriden by subclasses
	protected void generateWPDs(MethodConfiguration config) {
	}	

}
