Updated spreadsheet generation for care plans
diff --git a/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/GenerateCDABaseHandler.java b/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/GenerateCDABaseHandler.java
index a558100..296359d 100644
--- a/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/GenerateCDABaseHandler.java
+++ b/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/GenerateCDABaseHandler.java
@@ -92,7 +92,6 @@
 import org.openhealthtools.mdht.uml.cda.consol.MedicationFreeTextSig;
 import org.openhealthtools.mdht.uml.cda.consol.MedicationsAdministeredSection;
 import org.openhealthtools.mdht.uml.cda.consol.MedicationsSectionEntriesOptional;
-import org.openhealthtools.mdht.uml.cda.consol.PlanOfCareSection;
 import org.openhealthtools.mdht.uml.cda.consol.ProblemConcernAct;
 import org.openhealthtools.mdht.uml.cda.consol.ProblemObservation;
 import org.openhealthtools.mdht.uml.cda.consol.ProblemSectionEntriesOptional;
@@ -993,42 +992,6 @@
 		/*
 		 * (non-Javadoc)
 		 *
-		 * @see
-		 * org.openhealthtools.mdht.uml.cda.consol.util.ConsolSwitch#casePlanOfCareSection(org.openhealthtools.mdht.uml.cda.consol.PlanOfCareSection)
-		 */
-		@Override
-		public Boolean casePlanOfCareSection(PlanOfCareSection section) {
-
-			// if (!section.getPlanOfCareActivityActs().isEmpty()) {
-			//
-			//
-			// section.getPlanOfCareActivityEncounters();
-			// section.getPlanOfCareActivityObservations();
-			// section.getPlanOfCareActivityProcedures();
-			// section.getPlanOfCareActivitySubstanceAdministrations();
-			// section.getPlanOfCareActivitySupplies();
-			//
-			// if (sheet.getPhysicalNumberOfRows() == 0) {
-			// Row row1 = null;
-			// Row row2 = sheet.createRow(0);
-			//
-			// int offset = createPatientHeader(row1, row2, 0);
-			// offset = createEncounterIDHeader(row1, row2, offset);
-			// offset = createVitalSignsHeader(row1, row2, offset);
-			// emptySectionOffset.put(sheet, offset);
-			// }
-			//
-			// appendToCarePlanSheet(
-			// query, sheet, documentMetadata, patientRole, serviceEvent, section.getOrganizers(), encounters,
-			// fileName);
-			// return Boolean.TRUE;
-
-			return super.casePlanOfCareSection(section);
-		}
-
-		/*
-		 * (non-Javadoc)
-		 *
 		 * @see org.openhealthtools.mdht.uml.cda.consol.util.ConsolSwitch#defaultCase(org.eclipse.emf.ecore.EObject)
 		 */
 		@Override
diff --git a/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/GenerateCDADataHandler.java b/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/GenerateCDADataHandler.java
index 9e87958..08cac1e 100644
--- a/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/GenerateCDADataHandler.java
+++ b/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/GenerateCDADataHandler.java
@@ -77,6 +77,7 @@
 import org.eclipse.mdht.uml.cda.Author;
 import org.eclipse.mdht.uml.cda.ClinicalDocument;
 import org.eclipse.mdht.uml.cda.Encounter;
+import org.eclipse.mdht.uml.cda.Entry;
 import org.eclipse.mdht.uml.cda.InFulfillmentOf;
 import org.eclipse.mdht.uml.cda.InformationRecipient;
 import org.eclipse.mdht.uml.cda.PatientRole;
@@ -101,6 +102,11 @@
 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.consol.HandoffCommunicationParticipants;
+import org.openhealthtools.mdht.uml.cda.consol.HealthConcernAct;
+import org.openhealthtools.mdht.uml.cda.consol.HealthConcernsSection;
+import org.openhealthtools.mdht.uml.cda.consol.HealthStatusObservation2;
+import org.openhealthtools.mdht.uml.cda.consol.InterventionsSection2;
 import org.openhealthtools.mdht.uml.cda.consol.NutritionRecommendation;
 import org.openhealthtools.mdht.uml.cda.consol.PlanOfCareActivityAct;
 import org.openhealthtools.mdht.uml.cda.consol.PlanOfCareActivityEncounter;
@@ -110,6 +116,7 @@
 import org.openhealthtools.mdht.uml.cda.consol.PlanOfCareActivitySupply;
 import org.openhealthtools.mdht.uml.cda.consol.PlanOfCareSection;
 import org.openhealthtools.mdht.uml.cda.consol.PlanOfTreatmentSection2;
+import org.openhealthtools.mdht.uml.cda.consol.PlannedInterventionAct;
 import org.openhealthtools.mdht.uml.cda.consol.util.ConsolSwitch;
 import org.openhealthtools.mdht.uml.cda.hitsp.HITSPPackage;
 
@@ -581,6 +588,182 @@
 			this.serviceEvent = serviceEvent;
 			this.encounters = encounters;
 			this.file = file;
+
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see
+		 * org.openhealthtools.mdht.uml.cda.consol.util.ConsolSwitch#caseInterventionsSection(org.openhealthtools.mdht.uml.cda.consol.InterventionsSection)
+		 */
+		@Override
+		public Boolean caseInterventionsSection2(InterventionsSection2 section) {
+
+			processClinicalStatements(section);
+
+			for (PlannedInterventionAct act : section.getPlannedInterventionActs()) {
+
+				String sheetIndex = getSheet(
+					section.getClinicalDocument().eClass(),
+					String.valueOf(
+						section.eClass().getClassifierID() + "." +
+								String.valueOf(ConsolPackage.eINSTANCE.getPlannedInterventionAct().getClassifierID())),
+					sheetName(ConsolPackage.eINSTANCE.getPlannedInterventionAct()), splitOption);
+				Sheet sheet = wb.getSheet(sheetIndex);
+				if (sheet.getPhysicalNumberOfRows() == 0) {
+					Row row1 = null;
+					Row row2 = sheet.createRow(0);
+					int offset = SpreadsheetSerializer.createPatientHeader(row1, row2, 0);
+					offset = SpreadsheetSerializer.createEncounterIDHeader(row1, row2, offset);
+					offset = SpreadsheetSerializer.createProcedureHeader(row1, row2, offset);
+				}
+				Row row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+				int offset = SpreadsheetSerializer.serializePatient(row, 0, this.documentMetadata, patientRole);
+				offset = SpreadsheetSerializer.serializeProcedureActivityAct(row, offset, act);
+				SpreadsheetSerializer.serializeSectionAndFileName(row, offset, act.getSection(), file.getName());
+
+			}
+
+			for (HandoffCommunicationParticipants act : section.getHandoffCommunications()) {
+
+				String sheetIndex = getSheet(
+					section.getClinicalDocument().eClass(),
+					String.valueOf(
+						section.eClass().getClassifierID() + "." +
+								String.valueOf(
+									ConsolPackage.eINSTANCE.getHandoffCommunicationParticipants().getClassifierID())),
+					sheetName(ConsolPackage.eINSTANCE.getHandoffCommunicationParticipants()), splitOption);
+				Sheet sheet = wb.getSheet(sheetIndex);
+				if (sheet.getPhysicalNumberOfRows() == 0) {
+					Row row1 = null;
+					Row row2 = sheet.createRow(0);
+					int offset = SpreadsheetSerializer.createPatientHeader(row1, row2, 0);
+					offset = SpreadsheetSerializer.createEncounterIDHeader(row1, row2, offset);
+					offset = SpreadsheetSerializer.createProcedureHeader(row1, row2, offset);
+				}
+				Row row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+				int offset = SpreadsheetSerializer.serializePatient(row, 0, this.documentMetadata, patientRole);
+				offset = SpreadsheetSerializer.serializeProcedureActivityAct(row, offset, act);
+				SpreadsheetSerializer.serializeSectionAndFileName(row, offset, act.getSection(), file.getName());
+
+			}
+
+			return Boolean.TRUE;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see
+		 * org.openhealthtools.mdht.uml.cda.consol.util.ConsolSwitch#caseHealthConcernsSection(org.openhealthtools.mdht.uml.cda.consol.HealthConcernsSection)
+		 */
+		@Override
+		public Boolean caseHealthConcernsSection(HealthConcernsSection section) {
+
+			processClinicalStatements(section);
+
+			for (HealthConcernAct act : section.getHealthConcernActs()) {
+
+				String sheetIndex = getSheet(
+					section.getClinicalDocument().eClass(),
+					String.valueOf(
+						section.eClass().getClassifierID() + "." +
+								String.valueOf(ConsolPackage.eINSTANCE.getHealthConcernAct().getClassifierID())),
+					sheetName(ConsolPackage.eINSTANCE.getHealthConcernAct()), splitOption);
+				Sheet sheet = wb.getSheet(sheetIndex);
+				if (sheet.getPhysicalNumberOfRows() == 0) {
+					Row row1 = null;
+					Row row2 = sheet.createRow(0);
+					int offset = SpreadsheetSerializer.createPatientHeader(row1, row2, 0);
+					offset = SpreadsheetSerializer.createEncounterIDHeader(row1, row2, offset);
+					offset = SpreadsheetSerializer.createProcedureHeader(row1, row2, offset);
+				}
+				Row row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+				int offset = SpreadsheetSerializer.serializePatient(row, 0, this.documentMetadata, patientRole);
+				offset = SpreadsheetSerializer.serializeProcedureActivityAct(row, offset, act);
+				SpreadsheetSerializer.serializeSectionAndFileName(row, offset, act.getSection(), file.getName());
+
+			}
+
+			for (HealthStatusObservation2 observation : section.getHealthStatusObservation2s()) {
+				String sheetIndex = getSheet(
+					section.getClinicalDocument().eClass(),
+					String.valueOf(
+						section.eClass().getClassifierID() + "." +
+								String.valueOf(
+									ConsolPackage.eINSTANCE.getHealthStatusObservation2().getClassifierID())),
+					sheetName(ConsolPackage.eINSTANCE.getPlanOfCareActivityObservation()), splitOption);
+				Sheet sheet = wb.getSheet(sheetIndex);
+				if (sheet.getPhysicalNumberOfRows() == 0) {
+					Row row1 = null;
+					Row row2 = sheet.createRow(0);
+					int offset = SpreadsheetSerializer.createPatientHeader(row1, row2, 0);
+					offset = SpreadsheetSerializer.createEncounterIDHeader(row1, row2, offset);
+					offset = SpreadsheetSerializer.createSocialHistoryHeader(row1, row2, offset);
+				}
+				Row row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+				int offset = SpreadsheetSerializer.serializePatient(row, 0, this.documentMetadata, patientRole);
+				offset = SpreadsheetSerializer.serializeObservation(row, offset, observation);
+				SpreadsheetSerializer.serializeSectionAndFileName(
+					row, offset, observation.getSection(), file.getName());
+			}
+
+			return Boolean.TRUE;
+		}
+
+		private void processClinicalStatements(Section section) {
+			for (Entry entry : section.getEntries()) {
+
+				String sheetIndex = getSheet(
+					section.getClinicalDocument().eClass(), String.valueOf(section.eClass().getClassifierID()),
+					sheetName(section.eClass()), splitOption);
+
+				Sheet sheet = wb.getSheet(sheetIndex);
+
+				if (sheet.getPhysicalNumberOfRows() == 0) {
+					Row row1 = null; // sheet.createRow(0);
+					Row row2 = sheet.createRow(0);
+
+					int offset = SpreadsheetSerializer.createPatientHeader(row1, row2, 0);
+					offset = SpreadsheetSerializer.createEncounterIDHeader(row1, row2, offset);
+					offset = SpreadsheetSerializer.createClinicalStatmentHeader(row1, row2, offset);
+				}
+
+				if (entry.getAct() != null) {
+					Row row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+					int offset = SpreadsheetSerializer.serializePatient(row, 0, this.documentMetadata, patientRole);
+					offset = SpreadsheetSerializer.serializeClinicalStatement(row, offset, entry.getAct());
+					SpreadsheetSerializer.serializeSectionAndFileName(
+						row, offset, entry.getAct().getSection(), file.getName());
+				}
+
+				if (entry.getObservation() != null) {
+					Row row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+					int offset = SpreadsheetSerializer.serializePatient(row, 0, this.documentMetadata, patientRole);
+					offset = SpreadsheetSerializer.serializeClinicalStatement(row, offset, entry.getObservation());
+					SpreadsheetSerializer.serializeSectionAndFileName(
+						row, offset, entry.getObservation().getSection(), file.getName());
+				}
+
+				if (entry.getProcedure() != null) {
+					Row row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+					int offset = SpreadsheetSerializer.serializePatient(row, 0, this.documentMetadata, patientRole);
+					offset = SpreadsheetSerializer.serializeClinicalStatement(row, offset, entry.getProcedure());
+					SpreadsheetSerializer.serializeSectionAndFileName(
+						row, offset, entry.getObservation().getSection(), file.getName());
+				}
+
+				if (entry.getOrganizer() != null) {
+					Row row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+					int offset = SpreadsheetSerializer.serializePatient(row, 0, this.documentMetadata, patientRole);
+					offset = SpreadsheetSerializer.serializeClinicalStatement(row, offset, entry.getOrganizer());
+					SpreadsheetSerializer.serializeSectionAndFileName(
+						row, offset, entry.getObservation().getSection(), file.getName());
+				}
+
+			}
+
 		}
 
 		/*
@@ -592,7 +775,8 @@
 		@Override
 		public Boolean casePlanOfCareSection(PlanOfCareSection section) {
 
-			section.getInstructionss();
+			processClinicalStatements(section);
+
 			for (PlanOfCareActivityAct act : section.getPlanOfCareActivityActs()) {
 
 				String sheetIndex = getSheet(
@@ -608,7 +792,7 @@
 					int offset = SpreadsheetSerializer.createPatientHeader(row1, row2, 0);
 					offset = SpreadsheetSerializer.createEncounterIDHeader(row1, row2, offset);
 					offset = SpreadsheetSerializer.createProcedureHeader(row1, row2, offset);
-					// emptySectionOffset.put(sheet, offset);
+
 				}
 				Row row = sheet.createRow(sheet.getPhysicalNumberOfRows());
 				int offset = SpreadsheetSerializer.serializePatient(row, 0, this.documentMetadata, patientRole);
@@ -661,7 +845,6 @@
 				SpreadsheetSerializer.serializeSectionAndFileName(
 					row, offset, observation.getSection(), file.getName());
 			}
-			// section.getPlanOfCareActivityProcedures();
 
 			for (PlanOfCareActivityProcedure act : section.getPlanOfCareActivityProcedures()) {
 
diff --git a/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/SpreadsheetSerializer.java b/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/SpreadsheetSerializer.java
index f07e99d..1459083 100644
--- a/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/SpreadsheetSerializer.java
+++ b/cda/plugins/org.eclipse.mdht.cda.xml.ui/src/org/eclipse/mdht/cda/xml/ui/handlers/SpreadsheetSerializer.java
@@ -103,9 +103,10 @@
 		}
 		cell.setCellValue(sb.toString());
 		if (!GenerateCDABaseHandler.omitDOB) {
-			offset = SpreadsheetSerializer.serializePatientDOB(row, offset, patientRole, (patientRole != null
-					? patientRole.getPatient()
-					: null));
+			offset = SpreadsheetSerializer.serializePatientDOB(
+				row, offset, patientRole, (patientRole != null
+						? patientRole.getPatient()
+						: null));
 		}
 		;
 
@@ -1972,4 +1973,302 @@
 		return documentMetadata;
 	}
 
+	/**
+	 * @param row
+	 * @param offset
+	 * @param act
+	 * @return
+	 */
+	public static int serializeClinicalStatement(Row row, int offset, Act act) {
+		StringBuffer sb = new StringBuffer();
+
+		for (II ii : act.getIds()) {
+			sb.append(CDAValueUtil.getKey2(ii));
+		}
+
+		row.createCell(offset++).setCellValue(sb.toString());
+
+		sb = new StringBuffer();
+
+		Date d = CDAValueUtil.getDate(CDAValueUtil.getValueAsString(act.getEffectiveTime()));
+		if (d != null) {
+			row.createCell(offset++).setCellValue(CDAValueUtil.DATE_PRETTY.format(d));
+		} else {
+			row.createCell(offset++).setCellValue("");
+		}
+
+		offset = SpreadsheetSerializer.appendCode(row, offset, act.getSection(), act.getCode(), act.getText());
+
+		String organizationValue = "";
+		String personValue = "";
+		for (Performer2 performer : act.getPerformers()) {
+
+			if (performer.getAssignedEntity() != null) {
+				for (Organization organization : performer.getAssignedEntity().getRepresentedOrganizations()) {
+					for (ON on : organization.getNames()) {
+						organizationValue = organizationValue + CDAValueUtil.getValues(on);
+					}
+				}
+				if (performer.getAssignedEntity().getAssignedPerson() != null) {
+					for (PN pn : performer.getAssignedEntity().getAssignedPerson().getNames()) {
+						personValue = CDAValueUtil.getValues(pn);
+					}
+				}
+			}
+
+		}
+
+		row.createCell(offset++).setCellValue(personValue);
+
+		row.createCell(offset++).setCellValue(organizationValue);
+
+		return offset;
+	}
+
+	/**
+	 * @param row
+	 * @param offset
+	 * @param act
+	 * @return
+	 */
+	public static int serializeClinicalStatement(Row row, int offset, Observation observation) {
+		StringBuffer sb = new StringBuffer();
+
+		for (II ii : observation.getIds()) {
+			sb.append(CDAValueUtil.getKey2(ii));
+		}
+
+		row.createCell(offset++).setCellValue(sb.toString());
+
+		sb = new StringBuffer();
+
+		Date d = CDAValueUtil.getDate(CDAValueUtil.getValueAsString(observation.getEffectiveTime()));
+		if (d != null) {
+			row.createCell(offset++).setCellValue(CDAValueUtil.DATE_PRETTY.format(d));
+		} else {
+			row.createCell(offset++).setCellValue("");
+		}
+
+		offset = SpreadsheetSerializer.appendCode(
+			row, offset, observation.getSection(), observation.getCode(), observation.getText());
+
+		String organizationValue = "";
+		String personValue = "";
+		for (Performer2 performer : observation.getPerformers()) {
+
+			if (performer.getAssignedEntity() != null) {
+				for (Organization organization : performer.getAssignedEntity().getRepresentedOrganizations()) {
+					for (ON on : organization.getNames()) {
+						organizationValue = organizationValue + CDAValueUtil.getValues(on);
+					}
+				}
+				if (performer.getAssignedEntity().getAssignedPerson() != null) {
+					for (PN pn : performer.getAssignedEntity().getAssignedPerson().getNames()) {
+						personValue = CDAValueUtil.getValues(pn);
+					}
+				}
+			}
+
+		}
+
+		row.createCell(offset++).setCellValue(personValue);
+
+		row.createCell(offset++).setCellValue(organizationValue);
+
+		return offset;
+	}
+
+	public static int serializeClinicalStatement(Row row, int offset, SubstanceAdministration substanceAdministration) {
+		StringBuffer sb = new StringBuffer();
+
+		for (II ii : substanceAdministration.getIds()) {
+			sb.append(CDAValueUtil.getKey2(ii));
+		}
+
+		row.createCell(offset++).setCellValue(sb.toString());
+
+		sb = new StringBuffer();
+
+		String time = "";
+		for (SXCM_TS t : substanceAdministration.getEffectiveTimes()) {
+
+			if (!StringUtils.isEmpty(t.getValue())) {
+				time = t.getValue();
+			}
+
+			if (t instanceof IVL_TS) {
+
+				time = CDAValueUtil.getValueAsString((IVL_TS) t);
+
+			}
+
+		}
+
+		Date d = CDAValueUtil.getDate(time);
+
+		if (d != null) {
+			row.createCell(offset++).setCellValue(CDAValueUtil.DATE_PRETTY.format(d));
+		} else {
+			row.createCell(offset++).setCellValue(time);
+		}
+
+		// Date d = CDAValueUtil.getDate(CDAValueUtil.getValueAsString(substanceAdministration.getEffectiveTimes().get(0)));
+		// if (d != null) {
+		// row.createCell(offset++).setCellValue(CDAValueUtil.DATE_PRETTY.format(d));
+		// } else {
+		// row.createCell(offset++).setCellValue("");
+		// }
+
+		offset = SpreadsheetSerializer.appendCode(
+			row, offset, substanceAdministration.getSection(), substanceAdministration.getCode(),
+			substanceAdministration.getText());
+
+		String organizationValue = "";
+		String personValue = "";
+		for (Performer2 performer : substanceAdministration.getPerformers()) {
+
+			if (performer.getAssignedEntity() != null) {
+				for (Organization organization : performer.getAssignedEntity().getRepresentedOrganizations()) {
+					for (ON on : organization.getNames()) {
+						organizationValue = organizationValue + CDAValueUtil.getValues(on);
+					}
+				}
+				if (performer.getAssignedEntity().getAssignedPerson() != null) {
+					for (PN pn : performer.getAssignedEntity().getAssignedPerson().getNames()) {
+						personValue = CDAValueUtil.getValues(pn);
+					}
+				}
+			}
+
+		}
+
+		row.createCell(offset++).setCellValue(personValue);
+
+		row.createCell(offset++).setCellValue(organizationValue);
+
+		return offset;
+	}
+
+	/**
+	 * @param row
+	 * @param offset
+	 * @param procedure
+	 * @return
+	 */
+	public static int serializeClinicalStatement(Row row, int offset, Procedure procedure) {
+		StringBuffer sb = new StringBuffer();
+
+		for (II ii : procedure.getIds()) {
+			sb.append(CDAValueUtil.getKey2(ii));
+		}
+
+		row.createCell(offset++).setCellValue(sb.toString());
+
+		sb = new StringBuffer();
+
+		Date d = CDAValueUtil.getDate(CDAValueUtil.getValueAsString(procedure.getEffectiveTime()));
+		if (d != null) {
+			row.createCell(offset++).setCellValue(CDAValueUtil.DATE_PRETTY.format(d));
+		} else {
+			row.createCell(offset++).setCellValue("");
+		}
+
+		offset = SpreadsheetSerializer.appendCode(
+			row, offset, procedure.getSection(), procedure.getCode(), procedure.getText());
+
+		String organizationValue = "";
+		String personValue = "";
+		for (Performer2 performer : procedure.getPerformers()) {
+
+			if (performer.getAssignedEntity() != null) {
+				for (Organization organization : performer.getAssignedEntity().getRepresentedOrganizations()) {
+					for (ON on : organization.getNames()) {
+						organizationValue = organizationValue + CDAValueUtil.getValues(on);
+					}
+				}
+				if (performer.getAssignedEntity().getAssignedPerson() != null) {
+					for (PN pn : performer.getAssignedEntity().getAssignedPerson().getNames()) {
+						personValue = CDAValueUtil.getValues(pn);
+					}
+				}
+			}
+
+		}
+
+		row.createCell(offset++).setCellValue(personValue);
+
+		row.createCell(offset++).setCellValue(organizationValue);
+
+		return offset;
+	}
+
+	/**
+	 * @param row
+	 * @param offset
+	 * @param organizer
+	 * @return
+	 */
+	public static int serializeClinicalStatement(Row row, int offset, Organizer organizer) {
+		StringBuffer sb = new StringBuffer();
+
+		for (II ii : organizer.getIds()) {
+			sb.append(CDAValueUtil.getKey2(ii));
+		}
+
+		row.createCell(offset++).setCellValue(sb.toString());
+
+		sb = new StringBuffer();
+
+		Date d = CDAValueUtil.getDate(CDAValueUtil.getValueAsString(organizer.getEffectiveTime()));
+		if (d != null) {
+			row.createCell(offset++).setCellValue(CDAValueUtil.DATE_PRETTY.format(d));
+		} else {
+			row.createCell(offset++).setCellValue("");
+		}
+
+		offset = SpreadsheetSerializer.appendCode(row, offset, organizer.getSection(), organizer.getCode(), null);
+
+		String organizationValue = "";
+		String personValue = "";
+		for (Performer2 performer : organizer.getPerformers()) {
+
+			if (performer.getAssignedEntity() != null) {
+				for (Organization organization : performer.getAssignedEntity().getRepresentedOrganizations()) {
+					for (ON on : organization.getNames()) {
+						organizationValue = organizationValue + CDAValueUtil.getValues(on);
+					}
+				}
+				if (performer.getAssignedEntity().getAssignedPerson() != null) {
+					for (PN pn : performer.getAssignedEntity().getAssignedPerson().getNames()) {
+						personValue = CDAValueUtil.getValues(pn);
+					}
+				}
+			}
+
+		}
+
+		row.createCell(offset++).setCellValue(personValue);
+
+		row.createCell(offset++).setCellValue(organizationValue);
+
+		return offset;
+	}
+
+	/**
+	 * @param row1
+	 * @param row2
+	 * @param offset
+	 * @return
+	 */
+	public static int createClinicalStatmentHeader(Row row1, Row row2, int offset) {
+		row2.createCell(offset++).setCellValue("ID");
+		row2.createCell(offset++).setCellValue("Date");
+		offset = SpreadsheetSerializer.addCodeHeader(row2, offset, "Code");
+		row2.createCell(offset++).setCellValue("Performer");
+		row2.createCell(offset++).setCellValue("Organization");
+		row2.createCell(offset++).setCellValue("Section Title");
+		row2.createCell(offset++).setCellValue("File Name");
+		return offset;
+	}
+
 }
diff --git a/cda/plugins/org.eclipse.mdht.report/src/org/eclipse/mdht/report/common/Generate.java b/cda/plugins/org.eclipse.mdht.report/src/org/eclipse/mdht/report/common/Generate.java
new file mode 100644
index 0000000..95c3db0
--- /dev/null
+++ b/cda/plugins/org.eclipse.mdht.report/src/org/eclipse/mdht/report/common/Generate.java
@@ -0,0 +1,409 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2012 Obeo.
+ * 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:
+ *     Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.mdht.report.common;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.acceleo.engine.event.IAcceleoTextGenerationListener;
+import org.eclipse.acceleo.engine.generation.strategy.IAcceleoGenerationStrategy;
+import org.eclipse.acceleo.engine.service.AbstractAcceleoGenerator;
+import org.eclipse.emf.common.util.BasicMonitor;
+import org.eclipse.emf.common.util.Monitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+/**
+ * Entry point of the 'Generate' generation module.
+ *
+ * @generated
+ */
+public class Generate extends AbstractAcceleoGenerator {
+    /**
+     * The name of the module.
+     *
+     * @generated
+     */
+    public static final String MODULE_FILE_NAME = "/org/eclipse/mdht/report/common/generate";
+    
+    /**
+     * The name of the templates that are to be generated.
+     *
+     * @generated
+     */
+    public static final String[] TEMPLATE_NAMES = { "generateElement" };
+    
+    /**
+     * The list of properties files from the launch parameters (Launch configuration).
+     *
+     * @generated
+     */
+    private List<String> propertiesFiles = new ArrayList<String>();
+
+    /**
+     * Allows the public constructor to be used. Note that a generator created
+     * this way cannot be used to launch generations before one of
+     * {@link #initialize(EObject, File, List)} or
+     * {@link #initialize(URI, File, List)} is called.
+     * <p>
+     * The main reason for this constructor is to allow clients of this
+     * generation to call it from another Java file, as it allows for the
+     * retrieval of {@link #getProperties()} and
+     * {@link #getGenerationListeners()}.
+     * </p>
+     *
+     * @generated
+     */
+    public Generate() {
+        // Empty implementation
+    }
+
+    /**
+     * This allows clients to instantiates a generator with all required information.
+     * 
+     * @param modelURI
+     *            URI where the model on which this generator will be used is located.
+     * @param targetFolder
+     *            This will be used as the output folder for this generation : it will be the base path
+     *            against which all file block URLs will be resolved.
+     * @param arguments
+     *            If the template which will be called requires more than one argument taken from the model,
+     *            pass them here.
+     * @throws IOException
+     *             This can be thrown in three scenarios : the module cannot be found, it cannot be loaded, or
+     *             the model cannot be loaded.
+     * @generated
+     */
+    public Generate(URI modelURI, File targetFolder,
+            List<? extends Object> arguments) throws IOException {
+        initialize(modelURI, targetFolder, arguments);
+    }
+
+    /**
+     * This allows clients to instantiates a generator with all required information.
+     * 
+     * @param model
+     *            We'll iterate over the content of this element to find Objects matching the first parameter
+     *            of the template we need to call.
+     * @param targetFolder
+     *            This will be used as the output folder for this generation : it will be the base path
+     *            against which all file block URLs will be resolved.
+     * @param arguments
+     *            If the template which will be called requires more than one argument taken from the model,
+     *            pass them here.
+     * @throws IOException
+     *             This can be thrown in two scenarios : the module cannot be found, or it cannot be loaded.
+     * @generated
+     */
+    public Generate(EObject model, File targetFolder,
+            List<? extends Object> arguments) throws IOException {
+        initialize(model, targetFolder, arguments);
+    }
+    
+    /**
+     * This can be used to launch the generation from a standalone application.
+     * 
+     * @param args
+     *            Arguments of the generation.
+     * @generated
+     */
+    public static void main(String[] args) {
+        try {
+            if (args.length < 2) {
+                System.out.println("Arguments not valid : {model, folder}.");
+            } else {
+                URI modelURI = URI.createFileURI(args[0]);
+                File folder = new File(args[1]);
+                
+                List<String> arguments = new ArrayList<String>();
+                
+                /*
+                 * If you want to change the content of this method, do NOT forget to change the "@generated"
+                 * tag in the Javadoc of this method to "@generated NOT". Without this new tag, any compilation
+                 * of the Acceleo module with the main template that has caused the creation of this class will
+                 * revert your modifications.
+                 */
+
+                /*
+                 * Add in this list all the arguments used by the starting point of the generation
+                 * If your main template is called on an element of your model and a String, you can
+                 * add in "arguments" this "String" attribute.
+                 */
+                
+                Generate generator = new Generate(modelURI, folder, arguments);
+                
+                /*
+                 * Add the properties from the launch arguments.
+                 * If you want to programmatically add new properties, add them in "propertiesFiles"
+                 * You can add the absolute path of a properties files, or even a project relative path.
+                 * If you want to add another "protocol" for your properties files, please override 
+                 * "getPropertiesLoaderService(AcceleoService)" in order to return a new property loader.
+                 * The behavior of the properties loader service is explained in the Acceleo documentation
+                 * (Help -> Help Contents).
+                 */
+                 
+                for (int i = 2; i < args.length; i++) {
+                    generator.addPropertiesFile(args[i]);
+                }
+                
+                generator.doGenerate(new BasicMonitor());
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Launches the generation described by this instance.
+     * 
+     * @param monitor
+     *            This will be used to display progress information to the user.
+     * @throws IOException
+     *             This will be thrown if any of the output files cannot be saved to disk.
+     * @generated
+     */
+    @Override
+    public void doGenerate(Monitor monitor) throws IOException {
+        /*
+         * TODO if you wish to change the generation as a whole, override this. The default behavior should
+         * be sufficient in most cases. If you want to change the content of this method, do NOT forget to
+         * change the "@generated" tag in the Javadoc of this method to "@generated NOT". Without this new tag,
+         * any compilation of the Acceleo module with the main template that has caused the creation of this
+         * class will revert your modifications. If you encounter a problem with an unresolved proxy during the
+         * generation, you can remove the comments in the following instructions to check for problems. Please
+         * note that those instructions may have a significant impact on the performances.
+         */
+
+        //org.eclipse.emf.ecore.util.EcoreUtil.resolveAll(model);
+
+        /*
+         * If you want to check for potential errors in your models before the launch of the generation, you
+         * use the code below.
+         */
+
+        //if (model != null && model.eResource() != null) {
+        //    List<org.eclipse.emf.ecore.resource.Resource.Diagnostic> errors = model.eResource().getErrors();
+        //    for (org.eclipse.emf.ecore.resource.Resource.Diagnostic diagnostic : errors) {
+        //        System.err.println(diagnostic.toString());
+        //    }
+        //}
+
+        super.doGenerate(monitor);
+    }
+    
+    /**
+     * If this generator needs to listen to text generation events, listeners can be returned from here.
+     * 
+     * @return List of listeners that are to be notified when text is generated through this launch.
+     * @generated
+     */
+    @Override
+    public List<IAcceleoTextGenerationListener> getGenerationListeners() {
+        List<IAcceleoTextGenerationListener> listeners = super.getGenerationListeners();
+        /*
+         * TODO if you need to listen to generation event, add listeners to the list here. If you want to change
+         * the content of this method, do NOT forget to change the "@generated" tag in the Javadoc of this method
+         * to "@generated NOT". Without this new tag, any compilation of the Acceleo module with the main template
+         * that has caused the creation of this class will revert your modifications.
+         */
+        return listeners;
+    }
+    
+    /**
+     * If you need to change the way files are generated, this is your entry point.
+     * <p>
+     * The default is {@link org.eclipse.acceleo.engine.generation.strategy.DefaultStrategy}; it generates
+     * files on the fly. If you only need to preview the results, return a new
+     * {@link org.eclipse.acceleo.engine.generation.strategy.PreviewStrategy}. Both of these aren't aware of
+     * the running Eclipse and can be used standalone.
+     * </p>
+     * <p>
+     * If you need the file generation to be aware of the workspace (A typical example is when you wanna
+     * override files that are under clear case or any other VCS that could forbid the overriding), then
+     * return a new {@link org.eclipse.acceleo.engine.generation.strategy.WorkspaceAwareStrategy}.
+     * <b>Note</b>, however, that this <b>cannot</b> be used standalone.
+     * </p>
+     * <p>
+     * All three of these default strategies support merging through JMerge.
+     * </p>
+     * 
+     * @return The generation strategy that is to be used for generations launched through this launcher.
+     * @generated
+     */
+    @Override
+    public IAcceleoGenerationStrategy getGenerationStrategy() {
+        return super.getGenerationStrategy();
+    }
+    
+    /**
+     * This will be called in order to find and load the module that will be launched through this launcher.
+     * We expect this name not to contain file extension, and the module to be located beside the launcher.
+     * 
+     * @return The name of the module that is to be launched.
+     * @generated
+     */
+    @Override
+    public String getModuleName() {
+        return MODULE_FILE_NAME;
+    }
+    
+    /**
+     * If the module(s) called by this launcher require properties files, return their qualified path from
+     * here.Take note that the first added properties files will take precedence over subsequent ones if they
+     * contain conflicting keys.
+     * 
+     * @return The list of properties file we need to add to the generation context.
+     * @see java.util.ResourceBundle#getBundle(String)
+     * @generated
+     */
+    @Override
+    public List<String> getProperties() {
+        /*
+         * If you want to change the content of this method, do NOT forget to change the "@generated"
+         * tag in the Javadoc of this method to "@generated NOT". Without this new tag, any compilation
+         * of the Acceleo module with the main template that has caused the creation of this class will
+         * revert your modifications.
+         */
+
+        /*
+         * TODO if your generation module requires access to properties files, add their qualified path to the list here.
+         * 
+         * Properties files can be located in an Eclipse plug-in or in the file system (all Acceleo projects are Eclipse
+         * plug-in). In order to use properties files located in an Eclipse plugin, you need to add the path of the properties
+         * files to the "propertiesFiles" list:
+         * 
+         * final String prefix = "platform:/plugin/";
+         * final String pluginName = "org.eclipse.acceleo.module.sample";
+         * final String packagePath = "/org/eclipse/acceleo/module/sample/properties/";
+         * final String fileName = "default.properties";
+         * propertiesFiles.add(prefix + pluginName + packagePath + fileName);
+         * 
+         * With this mechanism, you can load properties files from your plugin or from another plugin.
+         * 
+         * You may want to load properties files from the file system, for that you need to add the absolute path of the file:
+         * 
+         * propertiesFiles.add("C:\Users\MyName\MyFile.properties");
+         * 
+         * If you want to let your users add properties files located in the same folder as the model:
+         *
+         * if (EMFPlugin.IS_ECLIPSE_RUNNING && model != null && model.eResource() != null) { 
+         *     propertiesFiles.addAll(AcceleoEngineUtils.getPropertiesFilesNearModel(model.eResource()));
+         * }
+         * 
+         * To learn more about Properties Files, have a look at the Acceleo documentation (Help -> Help Contents).
+         */
+        return propertiesFiles;
+    }
+    
+    /**
+     * Adds a properties file in the list of properties files.
+     * 
+     * @param propertiesFile
+     *            The properties file to add.
+     * @generated
+     * @since 3.1
+     */
+    @Override
+    public void addPropertiesFile(String propertiesFile) {
+        this.propertiesFiles.add(propertiesFile);
+    }
+    
+    /**
+     * This will be used to get the list of templates that are to be launched by this launcher.
+     * 
+     * @return The list of templates to call on the module {@link #getModuleName()}.
+     * @generated
+     */
+    @Override
+    public String[] getTemplateNames() {
+        return TEMPLATE_NAMES;
+    }
+    
+    /**
+     * This can be used to update the resource set's package registry with all needed EPackages.
+     * 
+     * @param resourceSet
+     *            The resource set which registry has to be updated.
+     * @generated
+     */
+    @Override
+    public void registerPackages(ResourceSet resourceSet) {
+        super.registerPackages(resourceSet);
+        if (!isInWorkspace(org.eclipse.emf.ecore.EcorePackage.class)) {
+            resourceSet.getPackageRegistry().put(org.eclipse.emf.ecore.EcorePackage.eINSTANCE.getNsURI(), org.eclipse.emf.ecore.EcorePackage.eINSTANCE);
+        }
+        
+        /*
+         * If you want to change the content of this method, do NOT forget to change the "@generated"
+         * tag in the Javadoc of this method to "@generated NOT". Without this new tag, any compilation
+         * of the Acceleo module with the main template that has caused the creation of this class will
+         * revert your modifications.
+         */
+        
+        /*
+         * If you need additional package registrations, you can register them here. The following line
+         * (in comment) is an example of the package registration for UML.
+         * 
+         * You can use the method  "isInWorkspace(Class c)" to check if the package that you are about to
+         * register is in the workspace.
+         * 
+         * To register a package properly, please follow the following conventions:
+         *
+         * If the package is located in another plug-in, already installed in Eclipse. The following content should
+         * have been generated at the beginning of this method. Do not register the package using this mechanism if
+         * the metamodel is located in the workspace.
+         *  
+         * if (!isInWorkspace(UMLPackage.class)) {
+         *     // The normal package registration if your metamodel is in a plugin.
+         *     resourceSet.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
+         * }
+         * 
+         * If the package is located in another project in your workspace, the plugin containing the package has not
+         * been register by EMF and Acceleo should register it automatically. If you want to use the generator in
+         * stand alone, the regular registration (seen a couple lines before) is needed.
+         * 
+         * To learn more about Package Registration, have a look at the Acceleo documentation (Help -> Help Contents).
+         */
+    }
+
+    /**
+     * This can be used to update the resource set's resource factory registry with all needed factories.
+     * 
+     * @param resourceSet
+     *            The resource set which registry has to be updated.
+     * @generated
+     */
+    @Override
+    public void registerResourceFactories(ResourceSet resourceSet) {
+        super.registerResourceFactories(resourceSet);
+        /*
+         * If you want to change the content of this method, do NOT forget to change the "@generated"
+         * tag in the Javadoc of this method to "@generated NOT". Without this new tag, any compilation
+         * of the Acceleo module with the main template that has caused the creation of this class will
+         * revert your modifications.
+         */
+        
+        /*
+         * TODO If you need additional resource factories registrations, you can register them here. the following line
+         * (in comment) is an example of the resource factory registration for UML.
+         *
+         * If you want to use the generator in stand alone, the resource factory registration will be required.
+         *  
+         * To learn more about the registration of Resource Factories, have a look at the Acceleo documentation (Help -> Help Contents). 
+         */ 
+        
+        // resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
+    }
+    
+}