/*******************************************************************************
 * 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.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.CDAPackage;
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 Map<String, List<String>> preferenceFilters = new HashMap<String, List<String>>();

	static String activeFilter;

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

		MDHTPreferences.filtersFromString(
			org.eclipse.mdht.uml.cda.ui.internal.Activator.getDefault().getPreferenceStore().getString(
				MDHTPreferences.CDA_REPORT_FILTERS),
			preferenceFilters);

		activeFilter = org.eclipse.mdht.uml.cda.ui.internal.Activator.getDefault().getPreferenceStore().getString(
			MDHTPreferences.CDA_REPORT_ACTIVE_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;
			}

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

		} else if (filterOption == null && preferenceFilters.containsKey(activeFilter)) {
			getFilterHash(theSectionCache);
			for (String r : preferenceFilters.get(activeFilter)) {
				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(1000);
			wb.setCompressTempFiles(true);

			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, 18000);
		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>() {
			HashMap<IFile, Long> sizes = new HashMap<IFile, Long>();

			private Long getSize(IFile aFile) throws CoreException {
				if (!sizes.containsKey(aFile)) {
					sizes.put(
						aFile,
						org.eclipse.core.filesystem.EFS.getStore(aFile.getLocationURI()).fetchInfo().getLength());

				}

				return sizes.get(aFile);

			}

			@Override
			public int compare(Object object1, Object object2) {
				try {
					if (getSize((IFile) object1) < getSize((IFile) object2)) {
						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());
		}

		boolean skipProcessing = false;

		if (System.getProperty("org.eclipse.mdht.cda.xls.skip") != null) {
			skipProcessing = true;
		}

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

						boolean loaded = false;
						try {
							clinicalDocument = CDAUtil.load(is, vr);
							loaded = true;
						} catch (Throwable e) {
							ILog log = Activator.getDefault().getLog();
							if (!omitValidation) {
								try {
									// attempt to load document with out validation
									clinicalDocument = CDAUtil.load(is);
									// 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;
							}
						} finally {

						}

						console.println("End Load " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
						is.close();

						if (!loaded) {
							continue;
						}

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

							}
						}
					}

					if (skipProcessing) {

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

						continue;
					}

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

							// This is when a section template is not found
							if (!sectionFilter.isEmpty()) {

								if (CDAPackage.eINSTANCE.getSection().isInstance(section)) {

									String code = section.getCode().getCode();

									if (ProcessSectionSwitch.getCodeToSection().containsKey(code)) {
										EClass targetSectionEclass = ProcessSectionSwitch.getCodeToSection().get(code);

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

										}

									} else {
										continue;
									}

								}

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

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

									}
								}
							}

							console.println("Start Section " + section.eClass().getName());
							if (!pss.doSwitch(section)) {

								console.println("Error processing section Unknown Template ID ");

								for (II templateId : section.getTemplateIds()) {
									console.println(
										"Error processing section Unknown Template ID root :  " + templateId.getRoot() +
												" extension : " + templateId.getExtension());
								}

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

					int sheetNumber = wb.getNumberOfSheets();
					for (int i = 0; i < sheetNumber; i++) {
						try {
							wb.getSheetAt(i).flushRows();
						} catch (java.lang.IllegalArgumentException iae) {
							System.err.println(i);

						}
					}
					/*
					 * 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");

			if (!sectionFilter.isEmpty()) {
				/*
				 * To limit size - do not serialize these tabs when using section filter option
				 * It was simpler to remove after tracking then modifying logic to process
				 *
				 */

				wb.removeSheetAt(wb.getSheetIndex("Demographics"));
				wb.removeSheetAt(wb.getSheetIndex("Metrics"));
				wb.removeSheetAt(wb.getSheetIndex("Sections"));
				wb.removeSheetAt(wb.getSheetIndex("Documents"));
				wb.removeSheetAt(wb.getSheetIndex("Encounters"));

			}
			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 countSections = false;

	boolean shouldCountSection(Section section) {
		if (countSections && 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 {

		}

	}
}
