//------------------------------------------------------------------------------
// 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.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.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, 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); //$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));
		}

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

		// 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: " //$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.");
			}
			return null;
		}
		WorkOrderType woType = wo.getLinkType();
		if (woType == WorkOrderType.FINISH_TO_START_LITERAL) {
			return new BigInteger("1"); //$NON-NLS-1$
		} 
		if (woType == WorkOrderType.START_TO_START_LITERAL) {
			return new BigInteger("3"); //$NON-NLS-1$
		} 
		if (woType == WorkOrderType.FINISH_TO_FINISH_LITERAL) {
			return new BigInteger("0"); //$NON-NLS-1$
		}
		if (woType == WorkOrderType.START_TO_FINISH_LITERAL) {
			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 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 = 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$
	}
	
	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) {
	}	

}
