/*******************************************************************************
 * Copyright (c) 2017, 2018 seanmuir.
 * 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:
 *     seanmuir - initial API and implementation
 *     seanmuir - add filtering by sections
 *
 *******************************************************************************/
package org.eclipse.mdht.cda.xml.ui.handlers;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import javax.swing.text.html.HTMLEditorKit;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFileState;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IPathVariableManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.mdht.cda.xml.ui.Activator;
import org.eclipse.mdht.cda.xml.ui.handlers.AnalyzeCDAHandler.CDAAnalaysisInput.CDAMetrics;
import org.eclipse.mdht.cda.xml.ui.handlers.CDAValueUtil.DocumentMetadata;
import org.eclipse.mdht.uml.cda.AssignedAuthor;
import org.eclipse.mdht.uml.cda.Author;
import org.eclipse.mdht.uml.cda.ClinicalDocument;
import org.eclipse.mdht.uml.cda.DocumentRoot;
import org.eclipse.mdht.uml.cda.Encounter;
import org.eclipse.mdht.uml.cda.InFulfillmentOf;
import org.eclipse.mdht.uml.cda.InformationRecipient;
import org.eclipse.mdht.uml.cda.PatientRole;
import org.eclipse.mdht.uml.cda.Section;
import org.eclipse.mdht.uml.cda.ServiceEvent;
import org.eclipse.mdht.uml.cda.ui.editors.MDHTPreferences;
import org.eclipse.mdht.uml.cda.util.CDAUtil;
import org.eclipse.mdht.uml.cda.util.CDAUtil.Query;
import org.eclipse.mdht.uml.cda.util.ValidationResult;
import org.eclipse.mdht.uml.hl7.datatypes.II;
import org.eclipse.mdht.uml.hl7.datatypes.ON;
import org.eclipse.mdht.uml.hl7.datatypes.PN;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.handlers.HandlerUtil;
import org.openhealthtools.mdht.uml.cda.consol.ConsolPackage;
import org.openhealthtools.mdht.uml.cda.consol.EncountersSectionEntriesOptional;
import org.openhealthtools.mdht.uml.cda.consol.GeneralHeaderConstraints;
import org.openhealthtools.mdht.uml.cda.hitsp.HITSPPackage;

import com.google.common.base.Stopwatch;
import com.google.common.io.ByteStreams;

public class GenerateCDADataHandler extends GenerateCDABaseHandler {

	protected static class ExtractText extends HTMLEditorKit.ParserCallback {

		StringBuffer txt;

		public ExtractText() {
			super();
			txt = new StringBuffer();
		}

		String getText() {
			String result = txt.toString();
			if (StringUtils.isEmpty(result)) {
				return "";
			}
			if (result.length() < 50) {
				return result;
			}
			return result.substring(0, 49);
		}

		@Override
		public void handleText(char[] text, int pos) {
			txt.append(text);
		}
	}

	protected enum PorO {
		ORGANIZATION, PERSON

	}

	public class ResultsDialog extends TitleAreaDialog {

		org.eclipse.swt.widgets.Table table;

		public ResultsDialog(Shell shell) {
			super(shell);

		}

		@Override
		public void create() {
			super.create();
			setTitle("CDA Processing Results");
		}

		@Override
		protected void createButtonsForButtonBar(Composite parent) {

			Button okButton = createButton(parent, OK, "Ok", false);

			okButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					setReturnCode(OK);
					close();
				}
			});
		}

		@Override
		protected Control createDialogArea(Composite parent) {

			Label label = new Label(parent, SWT.BORDER);

			label.setText("Total Files " + files.size());

			final ScrolledComposite composite = new ScrolledComposite(parent, SWT.V_SCROLL);
			composite.setLayout(new GridLayout());
			composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

			table = new org.eclipse.swt.widgets.Table(composite, SWT.BORDER | SWT.MULTI);
			table.setHeaderVisible(true);

			table.setSize(100, 100);

			composite.setContent(table);
			composite.setExpandHorizontal(true);
			composite.setExpandVertical(true);
			composite.setAlwaysShowScrollBars(true);
			composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));

			table.setLinesVisible(true);

			final GridData gridData = new GridData();
			gridData.widthHint = 500;
			table.setLayoutData(gridData);

			table.setHeaderVisible(true);
			final TableColumn column1 = new TableColumn(table, SWT.LEFT);

			final TableColumn column2 = new TableColumn(table, SWT.LEFT);

			column1.setText("File Name");
			column2.setText("Total Sections");

			column1.setWidth(250);
			column2.setWidth(250);

			for (IFile file : files) {
				final TableItem valueSetsUpdatedItem = new TableItem(table, SWT.NONE);
				if (errors.containsKey(file)) {
					valueSetsUpdatedItem.setText(new String[] { file.getName(), errors.get(file).getMessage() });
				} else {
					int sectionCount = getSectionCount(file);

					valueSetsUpdatedItem.setText(new String[] { file.getName(), String.valueOf(sectionCount) });
				}
			}

			return composite;
		}

	}

	static HashMap<String, String> authors = new HashMap<String, String>();

	private static final String CONSOLIDATED = "CONSOLIDATED";

	/**
	 * We'll use this pattern as divider to split the string into an array.
	 * Usage: myString.split(DIVIDER_PATTERN);
	 */
	private static final String DIVIDER_PATTERN = "(?<=[^\\p{Lu}])(?=\\p{Lu})" + "|(?<=[\\p{Ll}])(?=\\d)";

	static HashMap<Sheet, CellStyle> documentDateStyles = new HashMap<Sheet, CellStyle>();

	static ExtractText extractText = new ExtractText();

	private static final String FILTER = "org.eclipse.mdht.cda.xml.ui.filter";

	private static final String MDHTCONSOLE = "MDHTCONSOLE";

	static HashSet<String> names = new HashSet<String>();

	static boolean omitDOB = false;

	static boolean omitUnits = false;

	static boolean omitValidation = false;

	static HashMap<String, String> organizations = new HashMap<String, String>();

	static String preferenceFilters;

	static String fileNameFilters;

	static SigSwitch sigSwitch = new SigSwitch();

	static SigLocationSwitch sigLocationSwitch = new SigLocationSwitch();

	private static final String SPLITBYDOCUMENT = "org.eclipse.mdht.cda.xml.ui.splitbydocument";

	/**
	 * @param file
	 * @return
	 */

	public static String sheetName(EClass sectionEClass) {
		String name = sectionEClass.getName();
		String[] prettyName = name.split(DIVIDER_PATTERN); // "(?=\\p{Upper})");
		StringBuilder sb = new StringBuilder();
		for (String str : prettyName) {
			if (StringUtils.isNumeric(str)) {
				sb.append("(V").append(str).append(")");
			} else {
				sb.append(str).append(" ");
			}
		}
		if ("CONSOL".equalsIgnoreCase(sectionEClass.getEPackage().getNsPrefix())) {
			return sb.toString();
		} else {
			return sectionEClass.getEPackage().getNsPrefix().toUpperCase() + " " + sb.toString();
		}

	}

	static boolean shouldHandle(Diagnostic diagnostic) {
		// filter out diagnostics with no message or with root diagnostic message
		if (diagnostic.getMessage() == null || diagnostic.getMessage().startsWith("Diagnosis of")) {
			return false;
		}
		return true;
	}

	HashMap<Integer, EClass> documents = new HashMap<Integer, EClass>();

	HashMap<Integer, HashMap<IFile, DocumentMetadata>> documentsbyfile = new HashMap<Integer, HashMap<IFile, DocumentMetadata>>();

	protected HashMap<Integer, HashMap<String, ArrayList<IFile>>> documentsbysectionbyfile = new HashMap<Integer, HashMap<String, ArrayList<IFile>>>();

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.mdht.cda.xml.ui.handlers.GenerateCDABaseHandler#getSectionCount(org.eclipse.core.resources.IFile)
	 */

	protected HashMap<IFile, Exception> errors = new HashMap<IFile, Exception>();

	int fileCount = 0;

	protected ArrayList<IFile> files = new ArrayList<IFile>();

	long previousHeap = 0;

	protected HashMap<Integer, HashMap<String, ArrayList<IFile>>> sectionbyfileByDocumentxxx = new HashMap<Integer, HashMap<String, ArrayList<IFile>>>();

	HashMap<Integer, HashMap<String, String>> sheets = new HashMap<Integer, HashMap<String, String>>();

	HashMap<Integer, SXSSFWorkbook> workbooks = new HashMap<Integer, SXSSFWorkbook>();

	class ProcessSelection implements IRunnableWithProgress {

		Object object;

		String splitOption;

		String filterOption;

		HashSet<EClass> theSections;

		HashMap<EClass, HashSet<EClass>> theSectionCache;

		SXSSFWorkbook rollupStats;

		/**
		 * @param iss
		 * @param splitOption
		 * @param filterOption
		 * @param theSections
		 * @param theSectionCache
		 * @param rollupStats
		 */
		public ProcessSelection(Object object, String splitOption, String filterOption, HashSet<EClass> theSections,
				HashMap<EClass, HashSet<EClass>> theSectionCache) {
			super();
			this.object = object;
			this.splitOption = splitOption;
			this.filterOption = filterOption;
			this.theSections = theSections;
			this.theSectionCache = theSectionCache;
			// this.rollupStats = rollupStats;
		}

		public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
			try {
				// @SuppressWarnings("unchecked")
				// Iterator<Object> iter = iss.iterator();
				// while (iter.hasNext() && !monitor.isCanceled()) {
				// Object o = iter.next();
				if (object instanceof IFolder) {
					IFolder folder = (IFolder) object;
					codeMetricsFile = folder.getFile("codemetrics.cfg");
					monitor.beginTask("Generate Spreadsheet", folder.members().length);

					final SXSSFWorkbook rollupStats = new SXSSFWorkbook(10);
					processSelection(folder, null, monitor, splitOption, theSections, theSectionCache, rollupStats);

					final StringBuffer fileLocation = new StringBuffer();
					fileLocation.append(
						folder.getParent().getLocation().toOSString() + System.getProperty("file.separator") +
								CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" + folder.getName() + "_" +
								"RollupStatistics.xlsx");

					try (OutputStream fileOut = Files.newOutputStream(Paths.get(fileLocation.toString()))) {
						rollupStats.write(fileOut);
						fileOut.close();
						rollupStats.close();
						rollupStats.dispose();
					}
				}

				if (object instanceof IFile) {
					IFile zipFile = (IFile) object;

					final SXSSFWorkbook rollupStats = new SXSSFWorkbook(10);
					processSelection(null, zipFile, monitor, splitOption, theSections, theSectionCache, rollupStats);

					final StringBuffer fileLocation = new StringBuffer();
					fileLocation.append(
						zipFile.getParent().getLocation().toOSString() + System.getProperty("file.separator") +
								CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" +
								FilenameUtils.getBaseName(zipFile.getName()).toUpperCase() + "_" +
								"RollupStatistics.xlsx");

					try (OutputStream fileOut = Files.newOutputStream(Paths.get(fileLocation.toString()))) {
						rollupStats.write(fileOut);
						fileOut.close();
						rollupStats.close();
						rollupStats.dispose();
					}

				}
			} catch (Exception e) {
				ILog log = Activator.getDefault().getLog();
				log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error generating report", e));
			}
		}
	}

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {

		final String splitOption = event.getParameter(SPLITBYDOCUMENT);
		final String filterOption = event.getParameter(FILTER);

		// Omit DOB from generated Spreadsheets
		omitDOB = org.eclipse.mdht.uml.cda.ui.internal.Activator.getDefault().getPreferenceStore().getBoolean(
			MDHTPreferences.OMIT_DOB_STORE_VALUE);

		omitUnits = org.eclipse.mdht.uml.cda.ui.internal.Activator.getDefault().getPreferenceStore().getBoolean(
			MDHTPreferences.OMIT_UNITS_STORE_VALUE);

		preferenceFilters = org.eclipse.mdht.uml.cda.ui.internal.Activator.getDefault().getPreferenceStore().getString(
			MDHTPreferences.CDA_REPORT_DEFAULT_FILTER);

		fileNameFilters = org.eclipse.mdht.uml.cda.ui.internal.Activator.getDefault().getPreferenceStore().getString(
			MDHTPreferences.CDA_REPORT_FILE_NAME_FILTERS);

		omitValidation = org.eclipse.mdht.uml.cda.ui.internal.Activator.getDefault().getPreferenceStore().getBoolean(
			MDHTPreferences.OMIT_VALIDATION_STORE_VALUE);

		final HashSet<EClass> theSections = new HashSet<EClass>();

		final HashMap<EClass, HashSet<EClass>> theSectionCache = new HashMap<EClass, HashSet<EClass>>();

		// final SXSSFWorkbook rollupStats = new SXSSFWorkbook(10);

		if (filterOption != null) {

			IWorkbenchWindow window2 = HandlerUtil.getActiveWorkbenchWindowChecked(event);

			ILabelProvider lp = new ILabelProvider() {

				@Override
				public void addListener(ILabelProviderListener listener) {

				}

				@Override
				public void dispose() {

				}

				@Override
				public Image getImage(Object element) {

					return null;
				}

				@Override
				public String getText(Object element) {
					EClass ec = (EClass) element;
					String theElementName = ec.getName();

					if (Character.isDigit(theElementName.charAt(theElementName.length() - 1))) {
						theElementName = theElementName.substring(0, theElementName.length() - 1);
					}

					String[] nameArray = theElementName.split("(?=\\p{Upper})");
					StringBuffer sb = new StringBuffer();
					for (String seg : nameArray) {
						sb.append(seg).append(" ");
					}
					sb.append("(s)");

					return sb.toString();
				}

				@Override
				public boolean isLabelProperty(Object element, String property) {

					return false;
				}

				@Override
				public void removeListener(ILabelProviderListener listener) {

				}
			};

			ElementListSelectionDialog filterSelectionDialog = new ElementListSelectionDialog(window2.getShell(), lp);

			filterSelectionDialog.setTitle("Select Section");

			filterSelectionDialog.setMessage("Select a section(s):");

			filterSelectionDialog.setMultipleSelection(true);

			getFilterHash(theSectionCache);

			filterSelectionDialog.setElements(theSectionCache.keySet().toArray());

			;

			if (filterSelectionDialog.open() != Window.OK) {
				return null;
			}
			// return the selection

			for (Object object : filterSelectionDialog.getResult()) {
				theSections.add((EClass) object);
			}

		} else if (filterOption == null && !StringUtils.isEmpty(preferenceFilters)) {
			getFilterHash(theSectionCache);
			List<String> result = Arrays.asList(preferenceFilters.split("\\s*,\\s*"));
			for (String r : result) {
				if (theSectionCache.containsKey(ConsolPackage.eINSTANCE.getEClassifier(r))) {
					theSections.add((EClass) ConsolPackage.eINSTANCE.getEClassifier(r));
				}
			}
		}

		try {

			boolean completed = true;

			final StringBuffer fileLocation = new StringBuffer();

			ProgressMonitorDialog pd = new ProgressMonitorDialog(
				PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());

			ISelection selection = HandlerUtil.getCurrentSelectionChecked(event);

			if (selection instanceof ITreeSelection) {

				ITreeSelection treeSelection = (ITreeSelection) selection;

				for (Object element : treeSelection.toList()) {
					try {

						if (fileLocation.length() == 0) {
							IResource resource = (IResource) element;
							fileLocation.append(
								resource.getParent().getLocation().toOSString() + System.getProperty("file.separator") +
										CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" +
										resource.getParent().getName() + "_" + "RollupStatistics.xlsx");
						}
						pd.run(
							true, true,
							new ProcessSelection(element, splitOption, filterOption, theSections, theSectionCache));
					} catch (Throwable e) {
						ILog log = Activator.getDefault().getLog();
						log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error generating report", e));
					}
				}

				if (completed) {
					for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
						project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
					}
					PlatformUI.getWorkbench().getActiveWorkbenchWindow();
				}

			} else if (selection instanceof IStructuredSelection) {

				final IStructuredSelection iss = (IStructuredSelection) selection;

				final SXSSFWorkbook rollupStats = new SXSSFWorkbook(10);

				try {
					pd.run(true, true, new IRunnableWithProgress() {

						public void run(IProgressMonitor monitor)
								throws InvocationTargetException, InterruptedException {
							try {
								@SuppressWarnings("unchecked")
								Iterator<Object> iter = iss.iterator();
								while (iter.hasNext() && !monitor.isCanceled()) {
									Object o = iter.next();
									if (o instanceof IFolder) {
										IFolder folder = (IFolder) o;
										codeMetricsFile = folder.getFile("codemetrics.cfg");
										monitor.beginTask("Generate Spreadsheet", folder.members().length);

										if (fileLocation.length() == 0) {
											fileLocation.append(
												folder.getParent().getLocation().toOSString() +
														System.getProperty("file.separator") +
														CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" +
														"RollupStatistics.xlsx");
										}

										processSelection(
											folder, null, monitor, splitOption, theSections, theSectionCache,
											rollupStats);
									}

									if (o instanceof IFile) {
										IFile zipFile = (IFile) o;

										if (fileLocation.length() == 0) {
											fileLocation.append(
												zipFile.getParent().getLocation().toOSString() +
														System.getProperty("file.separator") +
														CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" +
														zipFile.getName() + "RollupStatistics.xlsx");
										}

										processSelection(
											null, zipFile, monitor, splitOption, theSections, theSectionCache,
											rollupStats);

									}

									try (OutputStream fileOut = Files.newOutputStream(
										Paths.get(fileLocation.toString()))) {
										rollupStats.write(fileOut);
										fileOut.close();
										rollupStats.close();
										rollupStats.dispose();
									}
								}
							} catch (Throwable e) {
								ILog log = Activator.getDefault().getLog();
								log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error generating report", e));
							}

						}
					});
				} catch (InvocationTargetException e) {
					ILog log = Activator.getDefault().getLog();
					log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error generating report", e));
					IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
					MessageBox dialog = new MessageBox(window.getShell(), SWT.ICON_ERROR | SWT.OK);
					dialog.setText("Error processing CDA");
					dialog.setMessage("Make sure Excel file is closed!" + e.getMessage());
					dialog.open();
					completed = false;
				} catch (InterruptedException e) {
					ILog log = Activator.getDefault().getLog();
					log.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Error generating report", e));
				}

				if (completed) {
					for (IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
						project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
					}
					PlatformUI.getWorkbench().getActiveWorkbenchWindow();
				}

				// if (selectedFile != null) {
				// fileLocation = selectedFile.getParent().getLocation().toOSString() +
				// System.getProperty("file.separator") + CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" +
				// selectedFile.getName().toUpperCase().replace(".ZIP", "") +
				// getFileName(eClass, splitOption) + "_SA.xlsx";
				// } else {
				// fileLocation = folder.getParent().getLocation().toOSString() +
				// System.getProperty("file.separator") + CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" +
				// folder.getName().toUpperCase() + getFileName(eClass, splitOption) + "_SA.xlsx";
				// }

			}
			if (completed) {

				File theFile = new File(fileLocation.toString());

				// If the file exists, check to see if we can open it
				// this is the excel
				if (theFile.exists()) {
					org.apache.commons.io.FileUtils.touch(theFile);
				}

				// monitor.subTask(
				// "Serializing " + CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" + folder.getName().toUpperCase() +
				// "_SA.xlsx");
				//
				// console.println("Start Saving " + currentProcessingTime);

				// try (OutputStream fileOut = Files.newOutputStream(Paths.get(fileLocation.toString()))) {
				// rollupStats.write(fileOut);
				// fileOut.close();
				// rollupStats.close();
				// rollupStats.dispose();
				// }

				for (

				IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
					project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
				}
				PlatformUI.getWorkbench().getActiveWorkbenchWindow();
			}

		} catch (

		Exception e) {
			ILog log = org.eclipse.mdht.cda.xml.ui.Activator.getDefault().getLog();
			log.log(
				new Status(
					IStatus.ERROR, org.eclipse.mdht.cda.xml.ui.Activator.PLUGIN_ID, "Error generating report", e));
		}

		return null;
	}

	private MessageConsole findConsole(String name) {
		ConsolePlugin plugin = ConsolePlugin.getDefault();
		IConsoleManager conMan = plugin.getConsoleManager();
		org.eclipse.ui.console.IConsole[] existing = conMan.getConsoles();
		for (int i = 0; i < existing.length; i++) {
			if (name.equals(existing[i].getName())) {
				return (MessageConsole) existing[i];
			}
		}
		// no console found, so create a new one
		MessageConsole myConsole = new MessageConsole(name, null);
		conMan.addConsoles(new org.eclipse.ui.console.IConsole[] { myConsole });
		return myConsole;
	}

	public IFile codeMetricsFile;

	private LinkedHashMap<String, String> getCodedMetrics() {

		LinkedHashMap<String, String> codedMetrics = new LinkedHashMap<String, String>();
		BufferedReader br = null;
		String line = "";
		String cvsSplitBy = ",";

		try {

			if (codeMetricsFile != null) {
				br = new BufferedReader(new FileReader(codeMetricsFile.getLocation().toOSString()));
				while ((line = br.readLine()) != null) {

					// use comma as separator
					String[] s = line.split(cvsSplitBy);
					if (s.length == 2) {
						codedMetrics.put(s[0], s[1]);
					}

				}
			}

		} catch (FileNotFoundException e) {

		} catch (IOException e) {

		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					// e.printStackTrace();
				}
			}
		}

		return codedMetrics;
	}

	public CDAMetrics applyMetrics(ClinicalDocument cd) {
		CDAMetrics cdaMetrics = new CDAMetrics();

		try {
			HashMap<String, String> codedMetrics = getCodedMetrics();

			cdaMetrics.codedMetricsCount = codedMetrics.size();
			for (String key : codedMetrics.keySet()) {
				String ocl = codedMetrics.get(key);
				Object o = CDAUtil.query(cd, ocl);
				if (o instanceof Collection && !((Collection) o).isEmpty()) {
					cdaMetrics.totalCodedMetrics++;
					cdaMetrics.codedMetrics.put(key, Boolean.TRUE);
				} else {
					cdaMetrics.codedMetrics.put(key, Boolean.FALSE);
				}
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return cdaMetrics;
	}

	void format(String fileLocation, IProgressMonitor monitor) throws IOException {

		// FileInputStream fis = new FileInputStream(fileLocation);

		try (InputStream fis = Files.newInputStream(Paths.get(fileLocation))) {

			monitor.subTask(
				"ReOpening  " + CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" + fileLocation.toUpperCase() +
						"_SA.xlsx");
			XSSFWorkbook wb = new XSSFWorkbook(fis);
			monitor.subTask(
				"Opened  " + CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" + fileLocation.toUpperCase() +
						"_SA.xlsx");
			CellStyle boldstyle = wb.createCellStyle();
			Font boldFont = wb.createFont();
			boldFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
			boldstyle.setFont(boldFont);

			for (int sheetCtr = 0; sheetCtr < wb.getNumberOfSheets(); sheetCtr++) {

				Sheet aSheet = wb.getSheetAt(sheetCtr);
				Row topRow = aSheet.getRow(0);
				if (topRow != null) {
					monitor.subTask("Formating Sheet  " + aSheet.getSheetName());
					int lastcell = topRow.getLastCellNum();
					for (int columnCtr = 0; columnCtr < lastcell; columnCtr++) {
						aSheet.autoSizeColumn(columnCtr);
						if (aSheet.getColumnWidth(columnCtr) > 9999) {
							aSheet.setColumnWidth(columnCtr, 9999);
						}
						// skip section sheet - different formatting
						if (sheetCtr != 1 && topRow.getCell(columnCtr) != null) {
							topRow.getCell(columnCtr).setCellStyle(boldstyle);
						}

					}

				}

			}

			try (OutputStream fileOut = Files.newOutputStream(Paths.get(fileLocation))) {
				wb.write(fileOut);
				fileOut.close();
				wb.close();
			}
		}
	}

	HashMap<IFile, DocumentMetadata> getDMHash(int document, String splitOption) {
		int documentIndex;

		if (CONSOLIDATED.equals(splitOption)) {
			documentIndex = 9909;
		} else {
			documentIndex = document; // .getClassifierID();
		}

		if (!documentsbyfile.containsKey(documentIndex)) {
			documentsbyfile.put(documentIndex, new HashMap<IFile, DocumentMetadata>());
		}
		return documentsbyfile.get(documentIndex);

	}

	String getFileName(Integer eclass, String splitOption) {

		if (CONSOLIDATED.equals(splitOption)) {
			return CONSOLIDATED;
		} else {
			return documents.get(eclass).getName();
		}

	}

	void getFilterHash(HashMap<EClass, HashSet<EClass>> theSections) {

		TreeIterator<EObject> packageContents = ConsolPackage.eINSTANCE.eAllContents();

		ArrayList<EClass> packageSections = new ArrayList<EClass>();

		ArrayList<EClass> rootSections = new ArrayList<EClass>();

		while (packageContents.hasNext()) {

			EObject packageObject = packageContents.next();

			if (packageObject instanceof EClass) {
				EClass eClass = (EClass) packageObject;
				boolean isSection = false;
				for (EClass eClass2 : eClass.getEAllSuperTypes()) {
					if ("Section".equals(eClass2.getName())) {
						isSection = true;
						break;
					}
				}

				if (isSection) {
					packageSections.add(eClass);
				}

			}

		}

		Set<EClass> sectionBaseClasses = new HashSet<EClass>();

		for (EClass section : packageSections) {
			for (EClass parentSection : section.getESuperTypes()) {
				sectionBaseClasses.add(parentSection);
			}
		}

		Comparator<? super EClass> compare = new Comparator<EClass>() {

			@Override
			public int compare(EClass o1, EClass o2) {
				return o1.getName().compareTo(o2.getName());
			}
		};
		Collections.sort(packageSections, compare);

		for (EClass section : packageSections) {
			if (!sectionBaseClasses.contains(section)) {

				boolean isRealRoot = true;
				for (EClass sectionAgain : packageSections) {
					if (sectionAgain.getName().startsWith(section.getName()) &&
							!sectionAgain.getName().equals(section.getName())) {
						isRealRoot = false;
					}
				}
				if (isRealRoot) {
					rootSections.add(section);
				}
			}
		}

		for (EClass ec3 : rootSections) {
			theSections.put(ec3, new HashSet<EClass>());
			theSections.get(ec3).addAll(ec3.getEAllSuperTypes());
			theSections.get(ec3).add(ec3);

			for (EClass sectionAgain : packageSections) {
				if (ec3.getName().startsWith(sectionAgain.getName()) && !ec3.getName().equals(sectionAgain.getName())) {
					theSections.get(ec3).add(sectionAgain);
				}
			}
		}
	}

	String getMemoryUssage() {
		// Map<String, String> memoryMap = new HashMap<>();
		StringBuffer sb = new StringBuffer();

		for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
			sb.append("gc count");
			sb.append(String.valueOf(gc.getCollectionCount()));
			sb.append(System.lineSeparator());
			sb.append("gc time");
			sb.append(String.valueOf(gc.getCollectionTime()));
			sb.append(System.lineSeparator());
		}
		MemoryMXBean memBean = ManagementFactory.getMemoryMXBean();
		MemoryUsage memHeapUsage = memBean.getHeapMemoryUsage();
		MemoryUsage nonHeapUsage = memBean.getNonHeapMemoryUsage();
		sb.append("heapInit = ");
		sb.append(String.valueOf(memHeapUsage.getInit()));
		sb.append(System.lineSeparator());
		sb.append("heapMax = ");
		sb.append(String.valueOf(memHeapUsage.getMax()));
		sb.append(System.lineSeparator());
		sb.append("heapCommit = ");
		sb.append(String.valueOf(memHeapUsage.getCommitted()));
		sb.append(System.lineSeparator());
		sb.append("heapUsed = ");
		sb.append(String.valueOf(memHeapUsage.getUsed()));
		sb.append(System.lineSeparator());
		sb.append("heapDelta = ");
		sb.append(String.valueOf(memHeapUsage.getUsed() - previousHeap));
		previousHeap = memHeapUsage.getUsed();
		sb.append(System.lineSeparator());
		sb.append("nonHeapInit = ");
		sb.append(String.valueOf(nonHeapUsage.getInit()));
		sb.append(System.lineSeparator());
		sb.append("nonHeapMax = ");
		sb.append(String.valueOf(nonHeapUsage.getMax()));
		sb.append(System.lineSeparator());
		sb.append("nonHeapCommit = ");
		sb.append(String.valueOf(nonHeapUsage.getCommitted()));
		sb.append(System.lineSeparator());
		sb.append("nonHeapUsed ");
		sb.append(String.valueOf(nonHeapUsage.getUsed()));
		sb.append(System.lineSeparator());

		return sb.toString();
	}

	public int getSectionCount(IFile file) {
		int count = 0;
		for (Integer i : documentsbysectionbyfile.keySet()) {
			for (String s : documentsbysectionbyfile.get(i).keySet()) {
				if (documentsbysectionbyfile.get(i).get(s).contains(file)) {
					count++;
				}
			}
		}
		return count;
	}

	ArrayList<IFile> getSectionHash(int document, String sheetIndex, String splitOption) {
		int documentIndex;

		if (CONSOLIDATED.equals(splitOption)) {
			documentIndex = 9909;
		} else {
			documentIndex = document; // .getClassifierID();
		}

		if (!documentsbysectionbyfile.containsKey(documentIndex)) {
			documentsbysectionbyfile.put(documentIndex, new HashMap<String, ArrayList<IFile>>(100));
		}
		if (!documentsbysectionbyfile.get(documentIndex).containsKey(sheetIndex)) {
			documentsbysectionbyfile.get(documentIndex).put(sheetIndex, new ArrayList<IFile>(fileCount));
		}
		ArrayList<IFile> result = documentsbysectionbyfile.get(documentIndex).get(sheetIndex);

		return result;

	}

	protected String getSheet(EClass document, String sectionIndex, String sheetName, String splitOption) {
		int documentIndex;
		// String sectionIndex = String.valueOf(sectionEClass.getClassifierID());

		if (CONSOLIDATED.equals(splitOption)) {
			documentIndex = 9909;
		} else {
			documentIndex = document.getClassifierID();
		}

		if (!sheets.containsKey(documentIndex)) {
			sheets.put(documentIndex, new HashMap<String, String>());
		}
		if (!sheets.get(documentIndex).containsKey(sectionIndex)) {

			// String sheetName = sheetName(sectionEClass);
			/*
			 * get and create appears to not use the same length of string
			 * So walk the collection and see if we have the previous version of section created first
			 *
			 *
			 */
			for (String akey : sheets.get(documentIndex).keySet()) {
				if (sheetName.startsWith(sheets.get(documentIndex).get(akey))) {
					sheets.get(documentIndex).put(sectionIndex, sheets.get(documentIndex).get(akey));
					return sheets.get(documentIndex).get(akey);
				}
			}

			SXSSFWorkbook wb = getWorkbook(document, splitOption);

			SXSSFSheet newSheet = wb.createSheet(sheetName);
			newSheet.setRandomAccessWindowSize(10);
			sheets.get(documentIndex).put(sectionIndex, newSheet.getSheetName());

		}
		return sheets.get(documentIndex).get(sectionIndex);

	}

	SXSSFWorkbook getWorkbook(EClass document, String splitOption) {

		int documentIndex;

		if (CONSOLIDATED.equals(splitOption)) {
			documentIndex = 9909;
		} else {
			documentIndex = document.getClassifierID();
		}

		if (!workbooks.containsKey(documentIndex)) {
			int offset = 0;

			SXSSFWorkbook wb = new SXSSFWorkbook(10);

			SXSSFSheet documentsSheet = wb.createSheet("Documents");
			documentsSheet.setRandomAccessWindowSize(10);

			SXSSFSheet sectionsSheet = wb.createSheet("Sections");
			sectionsSheet.setRandomAccessWindowSize(10);

			SXSSFSheet encountersSheet = wb.createSheet("Encounters");
			encountersSheet.setRandomAccessWindowSize(10);

			SXSSFSheet demographicsSheet = wb.createSheet("Demographics");
			demographicsSheet.setRandomAccessWindowSize(10);

			SXSSFSheet metricsSheet = wb.createSheet("Metrics");
			metricsSheet.setRandomAccessWindowSize(10);

			// sectionbyfileByDocument.put(documentIndex, new HashMap<String, ArrayList<IFile>>());

			SXSSFRow row1 = null;
			SXSSFRow row2 = documentsSheet.createRow(0);
			offset = SheetHeaderUtil.createPatientHeader(row1, row2, 0);
			SheetHeaderUtil.createPatientHeader2(row1, row2, offset);

			row1 = null;
			row2 = encountersSheet.createRow(0);

			offset = SheetHeaderUtil.createPatientHeader(row1, row2, 0);
			SheetHeaderUtil.createEncounterHeader(row1, row2, offset);

			row1 = null;
			row2 = demographicsSheet.createRow(0);

			offset = SheetHeaderUtil.createPatientHeader(row1, row2, 0);
			offset = SheetHeaderUtil.createDemographicsHeader(row1, row2, offset);

			row1 = null;
			row2 = metricsSheet.createRow(0);

			offset = SheetHeaderUtil.createPatientHeader(row1, row2, 0);
			offset = SheetHeaderUtil.createDemographicsHeader(row1, row2, offset);

			HashMap<String, String> codedMetrics = getCodedMetrics();

			for (String key : codedMetrics.keySet()) {
				row2.createCell(offset++).setCellValue(key);
			}

			workbooks.put(documentIndex, wb);
			documents.put(documentIndex, document);
		}

		return workbooks.get(documentIndex);

	}

	void initAuthorReferences(List<Author> authors, PorO poro) {

		String result = "";
		String authorId = "";

		for (Author a : authors) {

			if (a.getAssignedAuthor() != null) {
				AssignedAuthor aa = a.getAssignedAuthor();

				if (PorO.ORGANIZATION.equals(poro)) {
					if (aa.getRepresentedOrganization() != null) {
						for (ON on : aa.getRepresentedOrganization().getNames()) {
							result = CDAValueUtil.getValues(on);
						}
					}
				}

				if (PorO.PERSON.equals(poro)) {
					if (aa.getAssignedPerson() != null) {
						for (PN pn : aa.getAssignedPerson().getNames()) {
							result = CDAValueUtil.getValues(pn);
						}
					}
				}
			}

			for (II ii : a.getAssignedAuthor().getIds()) {
				authorId = CDAValueUtil.getKey3(ii);
				if (!StringUtils.isEmpty(authorId) && !StringUtils.isEmpty(result)) {
					if (PorO.ORGANIZATION.equals(poro)) {
						organizations.put(authorId, result);
					} else {
						GenerateCDADataHandler.authors.put(authorId, result);
					}

				}
			}

		}
	}

	public static String formatSize(long v) {
		if (v < 1024)
			return v + " B";
		int z = (63 - Long.numberOfLeadingZeros(v)) / 10;
		return String.format("%.1f %sB", (double) v / (1L << (z * 10)), " KMGTPE".charAt(z));
	}

	private static String getPath(EObject eObject) {
		String path = "";
		while (eObject != null && !(eObject instanceof DocumentRoot)) {
			EStructuralFeature feature = eObject.eContainingFeature();
			EObject container = eObject.eContainer();
			Object value = container.eGet(feature);
			if (feature.isMany()) {
				List<?> list = (List<?>) value;
				int index = list.indexOf(eObject) + 1;
				path = "/" + feature.getName() + "[" + index + "]" + path;
			} else {
				path = "/" + feature.getName() + "[1]" + path;
			}
			eObject = eObject.eContainer();
		}
		return path;
	}

	/**
	 * ZIPIterator will return WrapperForZipEnty one at a time
	 * this was done as to not load the complete zip file before starting processing
	 * this became problematic for larger files
	 *
	 * @author seanmuir
	 *
	 */
	public static class ZIPIterator implements Iterator<IFile> {

		Stack<ZipInputStream> zipInputStreams = new Stack<ZipInputStream>();

		WrapperForZipEnty wrapper = null;

		String filesFilter;

		String fileName;

		/**
		 * @param fileName
		 * @param zipInputStream
		 */
		public ZIPIterator(String fileName, ZipInputStream zipInputStream, String filesFilter) {
			this.fileName = fileName;
			zipInputStreams.push(zipInputStream);

			if (!StringUtils.isEmpty(filesFilter)) {
				this.filesFilter = filesFilter;
			} else {
				/**
				 * @TODO
				 * 		Add to preferences versus default here
				 */
				this.filesFilter = "C62TXT";
			}
		}

		boolean walkZipFile(String prefix) {

			while (!zipInputStreams.isEmpty()) {

				ZipInputStream zipInputStream = zipInputStreams.peek();

				ZipEntry entry = null;
				wrapper = null;
				try {
					/*
					 * What is not obvious from the documentation on ZipInputStream
					 * is the getNextEntry() modifies the zipInputStream state such that the input stream itself is now the entry
					 *
					 */
					entry = zipInputStream.getNextEntry();
					if (entry != null) {
						if (!entry.isDirectory()) {
							if ("XML".equalsIgnoreCase(FilenameUtils.getExtension(entry.getName())) &&
									!entry.getName().contains(filesFilter)) {
								// zipInputStream is now the input stream for the xml document
								byte[] buffer = ByteStreams.toByteArray(zipInputStream);
								ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer);
								wrapper = new WrapperForZipEnty(prefix, entry, byteArrayInputStream);
								return true;
							}
							if ("ZIP".equalsIgnoreCase(FilenameUtils.getExtension(entry.getName()))) {
								ZipInputStream embeddedZipInputStream = new ZipInputStream(zipInputStream);
								zipInputStreams.push(embeddedZipInputStream);
								if (walkZipFile(prefix + "/" + FilenameUtils.getBaseName(entry.getName()))) {
									return true;
								}
							}
						}
					} else {
						zipInputStreams.pop();
					}

				} catch (IOException e) {
					e.printStackTrace();
				}

			}

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see java.util.Iterator#hasNext()
		 */
		@Override
		public boolean hasNext() {
			return walkZipFile(FilenameUtils.getBaseName(fileName));
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see java.util.Iterator#next()
		 */
		@Override
		public IFile next() {
			return wrapper;
		}

	}

	void processSelection(IFolder selectedFolder, IFile selectedFile, IProgressMonitor monitor, String splitOption,
			HashSet<EClass> sectionFilter, HashMap<EClass, HashSet<EClass>> theSectionCache, SXSSFWorkbook rollupStats)
			throws Exception {

		MessageConsole mdhtConsole = findConsole(MDHTCONSOLE);
		mdhtConsole.setWaterMarks(1000, 8000);
		MessageConsoleStream console = mdhtConsole.newMessageStream();

		/*
		 * Set Ratio low as to prevent Zip Bomb Detection
		 */
		ZipSecureFile.setMinInflateRatio(0.000001);

		ConsolPackage.eINSTANCE.getContinuityOfCareDocument();
		HITSPPackage.eINSTANCE.getPatientSummary();

		/*
		 * There is a limitation on the number of cell styles you can create
		 * We create a global instance of the documentDateStyle for use in the getDocumentDateStyle()
		 * Set it to null on start up because it is bound to a particular workbook
		 *
		 * Not optimal but did not want to send the documentDateStyle as an argument to all the serialization methods
		 */
		// documentDateStyle = null;

		documentDateStyles.clear();
		sheets.clear();

		// sectionbyfileByDocument.clear();
		documentsbysectionbyfile.clear();
		documentsbyfile.clear();

		workbooks.clear();

		files.clear();

		errors.clear();

		documents.clear();

		int offset = 0;

		int filectr = 1;
		long currentProcessingTime = 1;
		Stopwatch stopwatch = Stopwatch.createUnstarted();

		Comparator<? super Object> c = new Comparator<Object>() {
			@Override
			public int compare(Object object1, Object object2) {
				try {

					if (object1 instanceof IFile) {
						IFile file1 = (IFile) object1;
						IFile file2 = (IFile) object2;
						IFileStore fs1 = org.eclipse.core.filesystem.EFS.getStore(file1.getLocationURI());
						IFileStore fs2 = org.eclipse.core.filesystem.EFS.getStore(file2.getLocationURI());
						if (fs1.fetchInfo().getLength() < fs2.fetchInfo().getLength()) {
							return 1;
						} else {
							return -1;
						}
					}

				} catch (CoreException e) {
				}
				return 0;
			}
		};

		ArrayList<IFile> documents = new ArrayList<IFile>();

		IFolder folder = null;
		Iterator<IFile> documentsIterator = null;
		if (selectedFolder != null) {
			folder = selectedFolder;
			for (IResource resource : folder.members()) {
				if (resource instanceof IFile) {
					documents.add((IFile) resource);
				}
			}
			Collections.sort(documents, c);
			documentsIterator = documents.iterator();
		}

		if (selectedFile != null) {
			folder = (IFolder) selectedFile.getParent();
			documentsIterator = new ZIPIterator(
				selectedFile.getName(), new ZipInputStream(selectedFile.getContents()), fileNameFilters);
		}

		fileCount = documents.size() + 50;

		String fileLocation2 = folder.getParent().getLocation().toOSString() + System.getProperty("file.separator") +
				CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" + folder.getName().toUpperCase() + "performance.log";

		String fileLocation3 = folder.getParent().getLocation().toOSString() + System.getProperty("file.separator") +
				CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" + folder.getName().toUpperCase() +
				"validatation.csv";

		BufferedWriter performance = Files.newBufferedWriter(Paths.get(fileLocation2));

		BufferedWriter validation = Files.newBufferedWriter(Paths.get(fileLocation3));

		validation.write("File,Rule,XPath");
		validation.newLine();

		final int STATSFILENAME = 0;
		final int STATSTOTAL = 1;
		final int STATSCONSOLIDATED = 2;
		final int STATSCONTINUITYOFCARE = 3;
		final int STATSPROGRESSNOTE = 4;
		final int STATSDISCHARGESUMMARY = 5;
		final int STATSOTHER = 6;
		final int STATSC32 = 7;
		final int STATSNONXML = 8;
		final int STATSERRORS = 9;

		SXSSFSheet statsheet = rollupStats.getSheet("File Statistics");
		if (statsheet == null) {
			statsheet = rollupStats.createSheet("File Statistics");
			Row hrow = statsheet.createRow(statsheet.getPhysicalNumberOfRows());
			hrow.createCell(STATSFILENAME).setCellValue("File Name");
			hrow.createCell(STATSTOTAL).setCellValue("Totals");
			hrow.createCell(STATSCONSOLIDATED).setCellValue("Consolidated");
			hrow.createCell(STATSCONTINUITYOFCARE).setCellValue("Summarization of episode note");
			hrow.createCell(STATSPROGRESSNOTE).setCellValue("Outpatient Progress note");
			hrow.createCell(STATSDISCHARGESUMMARY).setCellValue("Discharge Summary");
			hrow.createCell(STATSOTHER).setCellValue("Other");
			hrow.createCell(STATSC32).setCellValue("C32");
			hrow.createCell(STATSNONXML).setCellValue("NonXML");
			hrow.createCell(STATSERRORS).setCellValue("Errors");
			;

		}

		// statsheet.set

		Row statrow = statsheet.createRow(statsheet.getPhysicalNumberOfRows());

		if (selectedFile != null) {
			statrow.createCell(0).setCellValue(selectedFile.getName());
		}

		if (selectedFolder != null) {
			statrow.createCell(0).setCellValue(selectedFolder.getName());
		}

		int statfilectr = 0;
		int consoldocumentsprocessed = 0;
		int outpatientprogressnoteprocessed = 0;
		int dischargesummaryprocessed = 0;
		int continuityofcareprocessed = 0;
		int otherdocumentprocessed = 0;
		int c32documentsprocessed = 0;

		int nonxmldocuments = 0;
		int documenterrors = 0;
		int totalFiles = folder.members().length;
		while (documentsIterator.hasNext()) {
			statfilectr++;
			IFile file = documentsIterator.next();
			stopwatch.reset();
			stopwatch.start();
			if (monitor.isCanceled()) {
				monitor.done();
				break;
			}

			long fileSize = 100;
			if (file.getLocationURI() != null) {
				IFileStore fs1 = org.eclipse.core.filesystem.EFS.getStore(file.getLocationURI());
				fileSize = fs1.fetchInfo().getLength();
			}

			if ("XML".equalsIgnoreCase(file.getFileExtension())) {
				files.add(file);
				monitor.worked(1);
				double estimatedTimeLeft = ((folder.members().length - filectr) * (currentProcessingTime / filectr)) /
						1000.0;

				if (estimatedTimeLeft > 60) {
					monitor.setTaskName(
						"Processing " + file.getName() + ", " + StringUtils.leftPad(String.valueOf(filectr++), 5) +
								" of " + StringUtils.leftPad(String.valueOf(totalFiles), 5) +
								", Estimated Time to finish : " + ((int) estimatedTimeLeft / 60) + " Minutes ");
				} else {
					monitor.setTaskName(
						"Processing " + file.getName() + ", " + StringUtils.leftPad(String.valueOf(filectr++), 5) +
								" of " + StringUtils.leftPad(String.valueOf(totalFiles), 5) +
								", Estimated Time to finish : " + ((int) estimatedTimeLeft) + " Seconds ");
				}

				try {

					console.println(getMemoryUssage());
					console.println("file : " + file.getName() + "  size : " + fileSize);

					ClinicalDocument clinicalDocument = null;

					try (InputStream is = file.getContents()) {

						ValidationResult vr = null;
						if (!omitValidation) {
							vr = new ValidationResult();
						}

						try {
							clinicalDocument = CDAUtil.load(is, vr);
						} catch (Throwable e) {
							ILog log = Activator.getDefault().getLog();
							if (!omitValidation) {
								try {
									// attempt to load document with out validation
									clinicalDocument = CDAUtil.load(file.getContents());
									// if we get here - we can load without validation. log initial error
									log.log(
										new Status(
											IStatus.ERROR, Activator.PLUGIN_ID,
											"Validation Error loading " + file.getName(), e));
								} catch (Throwable e2) {
									// issue with XML skip
									log.log(
										new Status(
											IStatus.ERROR, Activator.PLUGIN_ID, "XML Error loading " + file.getName(),
											e));
									continue;
								}
							} else {
								// issue with XML skip
								log.log(
									new Status(
										IStatus.ERROR, Activator.PLUGIN_ID, "XML Error loading " + file.getName(), e));
								continue;
							}
						}

						console.println("End Load " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
						is.close();
						if (vr != null) {
							if (!vr.getErrorDiagnostics().isEmpty()) {
								for (Diagnostic diagnostic : vr.getErrorDiagnostics()) {
									validation.write(
										file.getName() + "," + StringEscapeUtils.escapeCsv(diagnostic.getMessage()));

									if (diagnostic.getData().size() > 0 &&
											diagnostic.getData().get(0) instanceof EObject) {
										validation.write("," + getPath((EObject) diagnostic.getData().get(0)));
									}

									validation.newLine();
								}
								validation.flush();

							}
						}
					}

					SXSSFWorkbook wb = this.getWorkbook(clinicalDocument.eClass(), splitOption);

					SXSSFSheet documentsSheet = wb.getSheet("Documents");
					SXSSFSheet demographicsSheet = wb.getSheet("Demographics");
					SXSSFSheet encountersSheet = wb.getSheet("Encounters");
					SXSSFSheet metricsSheet = wb.getSheet("Metrics");

					List<Encounter> encounters = new ArrayList<Encounter>();

					Query query = new Query(clinicalDocument);

					// Need to initialize author references because the order of the sections being return is not necessarily the physical order
					List<Author> authors = query.getEObjects(Author.class);
					initAuthorReferences(authors, PorO.ORGANIZATION);
					initAuthorReferences(authors, PorO.PERSON);

					PatientRole patientRole = query.getEObject(PatientRole.class);
					ServiceEvent serviceEvent = query.getEObject(ServiceEvent.class);
					InformationRecipient ir = query.getEObject(InformationRecipient.class);
					InFulfillmentOf iffo = query.getEObject(InFulfillmentOf.class);
					String fileName = file.getName();

					// if (file instanceof WrapperForZipEnty) {
					// fileName = fileName.substring(fileName.indexOf(" ") + 1);
					// }

					DocumentMetadata documentMetadata = SpreadsheetSerializer.appendToPatientSheet(
						query, documentsSheet, patientRole, ir, iffo, file);

					SpreadsheetSerializer.appendToDemographicsSheet(
						query, demographicsSheet, documentMetadata, patientRole);

					getDMHash(clinicalDocument.eClass().getClassifierID(), splitOption).put(file, documentMetadata);

					/*
					 * Outpatient Progress note
					 * Summary of episode note
					 */

					if (clinicalDocument instanceof GeneralHeaderConstraints) {
						console.println("Start Processing ");

						consoldocumentsprocessed++;

						switch (clinicalDocument.eClass().getClassifierID()) {
							case ConsolPackage.PROGRESS_NOTE:
							case ConsolPackage.PROGRESS_NOTE2:
								outpatientprogressnoteprocessed++;
								break;
							case ConsolPackage.DISCHARGE_SUMMARY:
							case ConsolPackage.DISCHARGE_SUMMARY2:
								dischargesummaryprocessed++;
								break;
							case ConsolPackage.CONTINUITY_OF_CARE_DOCUMENT:
							case ConsolPackage.CONTINUITY_OF_CARE_DOCUMENT2:
								continuityofcareprocessed++;
								break;

							default:
								otherdocumentprocessed++;
								break;
						}

						CDAMetrics metrics = applyMetrics(clinicalDocument);

						SpreadsheetSerializer.appendToMetricsSheet(
							query, metricsSheet, documentMetadata, patientRole, metrics, file.getName());

						EncountersSectionEntriesOptional es = query.getEObject(EncountersSectionEntriesOptional.class);

						if (es != null) {
							encounters.addAll(es.getEncounterActivitiess());
						}

						SpreadsheetSerializer.appendToEncounterSheet(
							query, encountersSheet, documentMetadata, patientRole, encounters, file.getName());

						ProcessSectionSwitch pss = new ProcessSectionSwitch(
							splitOption, query, wb, documentMetadata, patientRole, serviceEvent, encounters, file,
							this);

						for (Section section : clinicalDocument.getSections()) {

							if (!sectionFilter.isEmpty() && !sectionFilter.contains(section.eClass())) {

								boolean found = false;
								for (EClass sectionClass : sectionFilter) {
									if (theSectionCache.get(sectionClass).contains(section.eClass())) {
										// theSectionEClass = sectionClass;
										found = true;
										break;
									}
								}
								if (!found) {
									continue;

								}
							}

							console.println("Start Section " + section.eClass().getName());
							pss.doSwitch(section);
							console.println("End Section " + stopwatch.elapsed(TimeUnit.MILLISECONDS));

						}

						long t = stopwatch.elapsed(TimeUnit.MILLISECONDS);
						String s = file.getName() + " : " + formatSize(fileSize) + " took " + t / 1000.0 +
								" Second(s) at " +
								String.format("%.2f MB/S", (fileSize / (1024 * 1024)) / (t / 1000.0));
						monitor.subTask(s);

						performance.write(s);
						performance.newLine();
						performance.flush();

						console.println("End Processing " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
					} else {

						c32documentsprocessed++;

						org.openhealthtools.mdht.uml.cda.ccd.EncountersSection es = query.getEObject(
							org.openhealthtools.mdht.uml.cda.ccd.EncountersSection.class);

						if (es != null) {
							encounters.addAll(es.getEncounters());
						}

						SpreadsheetSerializer.appendToEncounterSheet(
							query, encountersSheet, documentMetadata, patientRole, encounters, file.getName());

						for (Section section : clinicalDocument.getSections()) {

							String sheetIndex = getSheet(
								clinicalDocument.eClass(), String.valueOf(section.eClass().getClassifierID()),
								sheetName(section.eClass()), splitOption);
							// if (!(section instanceof org.openhealthtools.mdht.uml.cda.ccd.EncountersSection)) {
							C32SectionSwitch sectionSwitch = new C32SectionSwitch(
								query, wb.getSheet(sheetIndex), documentMetadata, patientRole, serviceEvent, encounters,
								file.getName());
							Boolean result = sectionSwitch.doSwitch(section);
							if (!result) {
								IHESectionSwitch iheSectionSwitch = new IHESectionSwitch(
									query, wb.getSheet(sheetIndex), documentMetadata, patientRole, serviceEvent,
									encounters, file.getName());
								result = iheSectionSwitch.doSwitch(section);
							}
							if (!result) {
								CCDSectionSwitch ccdSectionSwitch = new CCDSectionSwitch(
									query, wb.getSheet(sheetIndex), documentMetadata, patientRole, serviceEvent,
									encounters, file.getName());
								result = ccdSectionSwitch.doSwitch(section);
							}
							wb.getSheet(sheetIndex).flushRows();
							// }
							if (shouldCountSection(section)) {
								getSectionHash(
									clinicalDocument.eClass().getClassifierID(), sheetIndex, splitOption).add(file);
							}
						}

					}
					EncounterUtil.encounterCache.clear();
					clinicalDocument.eResource().unload();
					currentProcessingTime += stopwatch.elapsed(TimeUnit.MILLISECONDS);
					/*
					 * Setting to null to encourage GC
					 */
					clinicalDocument = null;
				} catch (Exception exception) {
					documenterrors++;
					ILog log = Activator.getDefault().getLog();
					log.log(
						new Status(
							IStatus.ERROR, Activator.PLUGIN_ID, "Error processing file " + file.getName(), exception));
					errors.put(file, exception);
				}

			} else {
				nonxmldocuments++;
			}

			// final int STATSFILENAME = 0;
			// final int STATSTOTAL = 1;
			// final int STATSCONSOLIDATED = 2;
			// final int STATSCONTINUITYOFCARE = 3;
			// final int STATSPROGRESSNOTE = 4;
			// final int STATSEPISODENOTE = 5;
			// final int STATSDISCHARGESUMMARY = 6;
			// final int STATSOTHER = 7;
			// final int STATSC32 = 8;
			// final int STATSNONXML = 9;
			// final int STATSERRORS = 10;

			statrow.createCell(STATSTOTAL).setCellValue(statfilectr);
			statrow.createCell(STATSCONSOLIDATED).setCellValue(consoldocumentsprocessed);
			statrow.createCell(STATSCONTINUITYOFCARE).setCellValue(continuityofcareprocessed);
			statrow.createCell(STATSPROGRESSNOTE).setCellValue(outpatientprogressnoteprocessed);
			statrow.createCell(STATSDISCHARGESUMMARY).setCellValue(dischargesummaryprocessed);
			statrow.createCell(STATSOTHER).setCellValue(otherdocumentprocessed);
			statrow.createCell(STATSC32).setCellValue(c32documentsprocessed);
			statrow.createCell(STATSNONXML).setCellValue(nonxmldocuments);
			statrow.createCell(STATSERRORS).setCellValue(documenterrors);

			stopwatch.stop();
		}

		monitor.beginTask("Generate Spreadsheet", folder.members().length);

		for (

		Integer eClass : workbooks.keySet()) {

			HashMap<String, ArrayList<IFile>> sectionbyfile = documentsbysectionbyfile.get(eClass);

			if (sectionbyfile == null) {
				sectionbyfile = new HashMap<String, ArrayList<IFile>>();
			}

			SXSSFWorkbook wb = workbooks.get(eClass);
			SXSSFSheet sectionsSheet = wb.getSheet("Sections");

			List<String> sortedKeys = new ArrayList<String>(sectionbyfile.keySet());
			Collections.sort(sortedKeys);

			Font boldFont = wb.createFont();
			boldFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
			CellStyle sectionstyle = null;
			if (sectionsSheet.getWorkbook().getNumCellStyles() < 100) {
				sectionstyle = sectionsSheet.getWorkbook().createCellStyle();
				sectionstyle.setFillForegroundColor(IndexedColors.BLUE.getIndex());
				sectionstyle.setRotation((short) -90);
				sectionstyle.setFont(boldFont);
			}

			SXSSFRow row1 = sectionsSheet.createRow(sectionsSheet.getPhysicalNumberOfRows());

			offset = 0;
			// row1.createCell(offset++).setCellValue("File Name");
			// row1.createCell(offset++).setCellValue("Document");
			offset = SheetHeaderUtil.createDocumentMedadataHeadder(row1, offset++);
			int metadataoffset = offset;

			// undo to go back to two rows for headers row1.createCell(offset++).setCellValue("Document Type");
			for (String sectionclass : sortedKeys) {
				Cell cell = row1.createCell(offset++);
				cell.setCellValue(sectionclass);
				if (sectionstyle != null) {
					cell.setCellStyle(sectionstyle);
				}
			}

			row1 = sectionsSheet.createRow(sectionsSheet.getPhysicalNumberOfRows());
			// offset = 2;
			for (@SuppressWarnings("unused")
			String sectionclass : sortedKeys) {
				Cell cell = row1.createCell(metadataoffset++);
				String columnLetter = CellReference.convertNumToColString(cell.getColumnIndex());
				String strFormula = "COUNTIF(" + columnLetter + "3:" + columnLetter + (files.size() + 2) + ",\"X\")";
				cell.setCellType(Cell.CELL_TYPE_FORMULA);
				cell.setCellFormula(strFormula);
			}

			CellStyle style = null;
			if (sectionsSheet.getWorkbook().getNumCellStyles() < 100) {
				style = sectionsSheet.getWorkbook().createCellStyle();
				style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
				style.setFillPattern(CellStyle.SOLID_FOREGROUND);
				style.setAlignment(CellStyle.ALIGN_CENTER);
			}

			// style.setFont(font);

			// CellStyle boldstyle = wb.createCellStyle();

			for (IFile file : files) {
				if (getDMHash(eClass, splitOption).containsKey(file)) {
					offset = 0;
					row1 = sectionsSheet.createRow(sectionsSheet.getPhysicalNumberOfRows());
					// row1.createCell(offset++).setCellValue(file.getName());
					DocumentMetadata documentMetadata = getDMHash(eClass, splitOption).get(file);
					offset = SpreadsheetSerializer.serializeDocumentMetadata(row1, offset, documentMetadata);
					row1.getRowNum();
					for (String sectionclass : sortedKeys) {
						if (sectionbyfile.get(sectionclass).contains(file)) {
							Cell cell = row1.createCell(offset++);
							cell.setCellValue("X");
							if (style != null) {
								cell.setCellStyle(style);
							}
						} else {
							row1.createCell(offset++).setCellValue("");
						}
					}
				}
			}

			// row1 = sectionsSheet.createRow(sectionsSheet.getPhysicalNumberOfRows());
			// // offset = 2;
			// for (@SuppressWarnings("unused")
			// String sectionclass : sortedKeys) {
			// Cell cell = row1.createCell(metadataoffset++);
			// String columnLetter = CellReference.convertNumToColString(cell.getColumnIndex());
			// String strFormula = "COUNTIF(" + columnLetter + "2:" + columnLetter + (lastRow + 1) + ",\"X\")";
			// cell.setCellType(Cell.CELL_TYPE_FORMULA);
			// cell.setCellFormula(strFormula);
			// }

			String fileLocation = "";
			if (selectedFile != null) {
				fileLocation = selectedFile.getParent().getLocation().toOSString() +
						System.getProperty("file.separator") + CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" +
						selectedFile.getName().toUpperCase().replace(".ZIP", "") + getFileName(eClass, splitOption) +
						"_SA.xlsx";
			} else {
				fileLocation = folder.getParent().getLocation().toOSString() + System.getProperty("file.separator") +
						CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" + folder.getName().toUpperCase() +
						getFileName(eClass, splitOption) + "_SA.xlsx";
			}

			File theFile = new File(fileLocation);

			// If the file exists, check to see if we can open it
			// this is the excel
			if (theFile.exists()) {
				org.apache.commons.io.FileUtils.touch(theFile);
			}

			monitor.subTask(
				"Serializing  " + CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" + folder.getName().toUpperCase() +
						"_SA.xlsx");

			console.println("Start Saving " + currentProcessingTime);

			try (OutputStream fileOut = Files.newOutputStream(Paths.get(fileLocation))) {
				wb.write(fileOut);
				fileOut.close();
				wb.close();
				wb.dispose();
			}

			// FileOutputStream = new FileOutputStream();

			console.println("End Saving " + currentProcessingTime);

			monitor.subTask(
				"Flushing Memory  " + CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" +
						folder.getName().toUpperCase() + "_SA.xlsx");

			monitor.subTask(
				"Reloading  " + CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" + folder.getName().toUpperCase() +
						"_SA.xlsx");

			/**
			 * @TODO Add preference for formatting
			 */
			if (false && folder.members().length < 50) {
				format(fileLocation, monitor);
			}
			monitor.subTask(
				"Completed Saving  " + CDAValueUtil.DATE_FORMAT3.format(new Date()) + "_" +
						folder.getName().toUpperCase() + "_SA.xlsx");

		}

		if (performance != null) {
			performance.close();
		}

		if (validation != null) {
			validation.close();
		}

	}

	//

	/**
	 * If there is no null flavor and there is a entries or large narrative return true
	 * else
	 * return
	 * false
	 *
	 * @param section
	 * @return boolean
	 */
	boolean shouldCountSection(Section section) {
		if (section.isNullFlavorUndefined()) {
			if (!section.getEntries().isEmpty()) {
				return true;
			}
			if (section.getText() != null && section.getText().getText() != null) {
				if (section.getText().getText().length() > 50) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 *
	 * WrapperForZipEnty implements just enough of IFILE as to not have to rewrite zip file processing
	 *
	 *
	 * @author seanmuir
	 *
	 */
	public static class WrapperForZipEnty implements IFile {

		ZipFile zipFile;

		ZipEntry zipEntry;

		InputStream inputStream;

		String prefix = "";

		/**
		 * @param zipEntry
		 */
		public WrapperForZipEnty(ZipFile zipFile, ZipEntry zipEntry) {
			this.zipFile = zipFile;
			this.zipEntry = zipEntry;
		}

		public WrapperForZipEnty(String prefix, ZipEntry zipEntry, InputStream inputStream) {
			this.prefix = prefix;
			this.zipEntry = zipEntry;
			this.inputStream = inputStream;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.internal.resources.Resource#getType()
		 */
		@Override
		public int getType() {

			return 0;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#appendContents(java.io.InputStream, boolean, boolean, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void appendContents(InputStream source, boolean force, boolean keepHistory, IProgressMonitor monitor)
				throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#appendContents(java.io.InputStream, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void appendContents(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#create(java.io.InputStream, boolean, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void create(InputStream source, boolean force, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#create(java.io.InputStream, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void create(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#getCharset()
		 */
		@Override
		public String getCharset() throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#getCharset(boolean)
		 */
		@Override
		public String getCharset(boolean checkImplicit) throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#getCharsetFor(java.io.Reader)
		 */
		@Override
		public String getCharsetFor(Reader reader) throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#getContentDescription()
		 */
		@Override
		public IContentDescription getContentDescription() throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#getContents()
		 */
		@Override
		public InputStream getContents() throws CoreException {
			try {
				if (this.inputStream != null) {
					return this.inputStream;
				} else {
					return zipFile.getInputStream(this.zipEntry);
				}
			} catch (IOException e) {
				throw new CoreException(null);
			}
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#getContents(boolean)
		 */
		@Override
		public InputStream getContents(boolean force) throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#getEncoding()
		 */
		@Override
		public int getEncoding() throws CoreException {

			return 0;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#getHistory(org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public IFileState[] getHistory(IProgressMonitor monitor) throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#setCharset(java.lang.String)
		 */
		@Override
		public void setCharset(String newCharset) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#setCharset(java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void setCharset(String newCharset, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#setContents(java.io.InputStream, boolean, boolean, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void setContents(InputStream source, boolean force, boolean keepHistory, IProgressMonitor monitor)
				throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#setContents(org.eclipse.core.resources.IFileState, boolean, boolean,
		 * org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void setContents(IFileState source, boolean force, boolean keepHistory, IProgressMonitor monitor)
				throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#setContents(java.io.InputStream, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void setContents(InputStream source, int updateFlags, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#setContents(org.eclipse.core.resources.IFileState, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void setContents(IFileState source, int updateFlags, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#accept(org.eclipse.core.resources.IResourceProxyVisitor, int)
		 */
		@Override
		public void accept(IResourceProxyVisitor visitor, int memberFlags) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#accept(org.eclipse.core.resources.IResourceProxyVisitor, int, int)
		 */
		@Override
		public void accept(IResourceProxyVisitor visitor, int depth, int memberFlags) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#accept(org.eclipse.core.resources.IResourceVisitor)
		 */
		@Override
		public void accept(IResourceVisitor visitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#accept(org.eclipse.core.resources.IResourceVisitor, int, boolean)
		 */
		@Override
		public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#accept(org.eclipse.core.resources.IResourceVisitor, int, int)
		 */
		@Override
		public void accept(IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#clearHistory(org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void clearHistory(IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#copy(org.eclipse.core.runtime.IPath, boolean, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void copy(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#copy(org.eclipse.core.runtime.IPath, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void copy(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#copy(org.eclipse.core.resources.IProjectDescription, boolean, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void copy(IProjectDescription description, boolean force, IProgressMonitor monitor)
				throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#copy(org.eclipse.core.resources.IProjectDescription, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void copy(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
				throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#createMarker(java.lang.String)
		 */
		@Override
		public IMarker createMarker(String type) throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#createProxy()
		 */
		@Override
		public IResourceProxy createProxy() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#delete(boolean, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void delete(boolean force, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#delete(int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#deleteMarkers(java.lang.String, boolean, int)
		 */
		@Override
		public void deleteMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#exists()
		 */
		@Override
		public boolean exists() {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#findMarker(long)
		 */
		@Override
		public IMarker findMarker(long id) throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#findMarkers(java.lang.String, boolean, int)
		 */
		@Override
		public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#findMaxProblemSeverity(java.lang.String, boolean, int)
		 */
		@Override
		public int findMaxProblemSeverity(String type, boolean includeSubtypes, int depth) throws CoreException {

			return 0;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getFileExtension()
		 */
		@Override
		public String getFileExtension() {
			// String fn = ;

			return FilenameUtils.getExtension(this.zipEntry.getName());

			// return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getLocalTimeStamp()
		 */
		@Override
		public long getLocalTimeStamp() {

			return 0;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getLocation()
		 */
		@Override
		public IPath getLocation() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getLocationURI()
		 */
		@Override
		public java.net.URI getLocationURI() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getMarker(long)
		 */
		@Override
		public IMarker getMarker(long id) {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getModificationStamp()
		 */
		@Override
		public long getModificationStamp() {

			return 0;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getPathVariableManager()
		 */
		@Override
		public IPathVariableManager getPathVariableManager() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getParent()
		 */
		@Override
		public IContainer getParent() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getPersistentProperties()
		 */
		@Override
		public Map<QualifiedName, String> getPersistentProperties() throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getPersistentProperty(org.eclipse.core.runtime.QualifiedName)
		 */
		@Override
		public String getPersistentProperty(QualifiedName key) throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getProject()
		 */
		@Override
		public IProject getProject() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getProjectRelativePath()
		 */
		@Override
		public IPath getProjectRelativePath() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getRawLocation()
		 */
		@Override
		public IPath getRawLocation() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getRawLocationURI()
		 */
		@Override
		public java.net.URI getRawLocationURI() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getResourceAttributes()
		 */
		@Override
		public ResourceAttributes getResourceAttributes() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getSessionProperties()
		 */
		@Override
		public Map<QualifiedName, Object> getSessionProperties() throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getSessionProperty(org.eclipse.core.runtime.QualifiedName)
		 */
		@Override
		public Object getSessionProperty(QualifiedName key) throws CoreException {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#getWorkspace()
		 */
		@Override
		public IWorkspace getWorkspace() {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isAccessible()
		 */
		@Override
		public boolean isAccessible() {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isDerived()
		 */
		@Override
		public boolean isDerived() {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isDerived(int)
		 */
		@Override
		public boolean isDerived(int options) {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isHidden()
		 */
		@Override
		public boolean isHidden() {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isHidden(int)
		 */
		@Override
		public boolean isHidden(int options) {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isLinked()
		 */
		@Override
		public boolean isLinked() {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isVirtual()
		 */
		@Override
		public boolean isVirtual() {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isLinked(int)
		 */
		@Override
		public boolean isLinked(int options) {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isLocal(int)
		 */
		@Override
		public boolean isLocal(int depth) {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isPhantom()
		 */
		@Override
		public boolean isPhantom() {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isSynchronized(int)
		 */
		@Override
		public boolean isSynchronized(int depth) {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isTeamPrivateMember()
		 */
		@Override
		public boolean isTeamPrivateMember() {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#isTeamPrivateMember(int)
		 */
		@Override
		public boolean isTeamPrivateMember(int options) {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#move(org.eclipse.core.runtime.IPath, boolean, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void move(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#move(org.eclipse.core.runtime.IPath, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void move(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#move(org.eclipse.core.resources.IProjectDescription, boolean, boolean,
		 * org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void move(IProjectDescription description, boolean force, boolean keepHistory, IProgressMonitor monitor)
				throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#move(org.eclipse.core.resources.IProjectDescription, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
				throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#refreshLocal(int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#revertModificationStamp(long)
		 */
		@Override
		public void revertModificationStamp(long value) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#setDerived(boolean)
		 */
		@Override
		public void setDerived(boolean isDerived) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#setDerived(boolean, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void setDerived(boolean isDerived, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#setHidden(boolean)
		 */
		@Override
		public void setHidden(boolean isHidden) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#setLocal(boolean, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#setLocalTimeStamp(long)
		 */
		@Override
		public long setLocalTimeStamp(long value) throws CoreException {

			return 0;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#setPersistentProperty(org.eclipse.core.runtime.QualifiedName, java.lang.String)
		 */
		@Override
		public void setPersistentProperty(QualifiedName key, String value) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#setReadOnly(boolean)
		 */
		@Override
		public void setReadOnly(boolean readOnly) {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#setResourceAttributes(org.eclipse.core.resources.ResourceAttributes)
		 */
		@Override
		public void setResourceAttributes(ResourceAttributes attributes) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#setSessionProperty(org.eclipse.core.runtime.QualifiedName, java.lang.Object)
		 */
		@Override
		public void setSessionProperty(QualifiedName key, Object value) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#setTeamPrivateMember(boolean)
		 */
		@Override
		public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IResource#touch(org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void touch(IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
		 */
		@Override
		public <T> T getAdapter(Class<T> adapter) {

			return null;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.runtime.jobs.ISchedulingRule#contains(org.eclipse.core.runtime.jobs.ISchedulingRule)
		 */
		@Override
		public boolean contains(ISchedulingRule rule) {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse.core.runtime.jobs.ISchedulingRule)
		 */
		@Override
		public boolean isConflicting(ISchedulingRule rule) {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#createLink(org.eclipse.core.runtime.IPath, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void createLink(IPath localLocation, int updateFlags, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#createLink(java.net.URI, int, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void createLink(java.net.URI location, int updateFlags, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#delete(boolean, boolean, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void delete(boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException {

		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#getFullPath()
		 */
		@Override
		public IPath getFullPath() {
			IPath path = new Path(prefix);
			return path;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#getName()
		 */
		@Override
		public String getName() {
			return FilenameUtils.getName(zipEntry.getName());
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#isReadOnly()
		 */
		@Override
		public boolean isReadOnly() {

			return false;
		}

		/*
		 * (non-Javadoc)
		 *
		 * @see org.eclipse.core.resources.IFile#move(org.eclipse.core.runtime.IPath, boolean, boolean, org.eclipse.core.runtime.IProgressMonitor)
		 */
		@Override
		public void move(IPath destination, boolean force, boolean keepHistory, IProgressMonitor monitor)
				throws CoreException {

		}

	}
}
