/*
 *  
 *  $Id: ihl7parser.h $
 *  Ginkgo CADx Project
 *
 *  Copyright 2008-14 MetaEmotion S.L. All rights reserved.
 *  http://ginkgo-cadx.com
 *
 *  This file is licensed under LGPL v3 license.
 *  See License.txt for details
 *
 */
#pragma once
#include <api/api.h>
#include "imodelohl7.h"
#include <ostream>
#include <iomanip>
#include <sstream>
#include <ctime>

namespace GIL {
	namespace Hl7Parser {

	namespace Segmentos {

				class MSH : public GIL::HL7::Segment {

				protected:

				public:

					MSH(const std::string& messageType, const std::string& messageTriggerEvent, const std::string& messageHeader, const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : GIL::HL7::Segment("MSH",rs,fs,sfs)
					{
						GIL::HL7::Segment& msh = *this;

						msh <<= GIL::HL7::Field(1, "MSH.1") << GIL::HL7::Component(1, "", m_FS);
						msh <<= GIL::HL7::Field(2, "MSH.2") << GIL::HL7::Component(1, "", m_CS + "~\\&");

						msh <<= GIL::HL7::Field(3, "MSH.3") << GIL::HL7::Component(1, "HD.1"); // Sending Application
						msh <<= GIL::HL7::Field(4, "MSH.4") << GIL::HL7::Component(1, "HD.1"); // Sending Facility
						msh <<= GIL::HL7::Field(5, "MSH.5") << GIL::HL7::Component(1, "HD.1"); // Receiving Application
						msh <<= GIL::HL7::Field(6, "MSH.6") << GIL::HL7::Component(1, "HD.1"); // Receiving Facility

						msh <<= GIL::HL7:: Field(7, "MSH.7") << GIL::HL7::Component(1, "TS.1"); // TimeStamp: YYYYMMDDhhmmss

						msh <<= GIL::HL7::Field(9, "MSH.9") << GIL::HL7::Component(1, "MSG.1", messageType) << GIL::HL7::Component(2, "MSG.2", messageTriggerEvent) << GIL::HL7::Component(3, "MSG.3", messageHeader); // Message Type

						msh <<= GIL::HL7::Field(10, "MSH.10") << GIL::HL7::Component(1, ""); // Message Control ID
						msh <<= GIL::HL7::Field(11, "MSH.11") << GIL::HL7::Component(1, "PT.1", "P"); // Processing ID
						msh <<= GIL::HL7::Field(12, "MSH.12") << GIL::HL7::Component(1, "VID.1", "2.5"); // Version ID
						msh <<= GIL::HL7::Field(15, "MSH.15") << GIL::HL7::Component(1, "", "AL"); // Accept Acknowledgment type
						msh <<= GIL::HL7::Field(16, "MSH.16") << GIL::HL7::Component(1, "", "NE"); // Application Acknowledgement type
					}

					MSH(const GIL::HL7::Segment& segment)
					{
						*this = segment;
					}

					MSH& operator=(const GIL::HL7::Segment& segment)
					{
						GIL::HL7::Segment& msh = *this;
						msh = segment;
						return *this;
					}

					void SetSendingApplication(const std::string& sendingApplication)
					{
						GIL::HL7::Segment& msh = *this;
						msh[3][1] = sendingApplication;
					}

					const std::string& GetSendingApplication()
					{
						GIL::HL7::Segment& msh = *this;
						return msh[3][1];
					}

					void SetSendingFacility(const std::string& sendingFacility)
					{
						GIL::HL7::Segment& msh = *this;
						msh[4][1] = sendingFacility;
					}

					const std::string& GetSendingFacility()
					{
						GIL::HL7::Segment& msh = *this;
						return msh[4][1];
					}

					void SetReceivingApplication(const std::string& receivingApplication)
					{
						GIL::HL7::Segment& msh = *this;
						msh[5][1] = receivingApplication;
					}

					const std::string& GetReceivingApplication()
					{
						GIL::HL7::Segment& msh = *this;
						return msh[5][1];
					}

					void SetReceivingFacility(const std::string& receivingFacility)
					{
						GIL::HL7::Segment& msh = *this;
						msh[6][1] = receivingFacility;
					}

					const std::string& GetReceivingFacility()
					{
						GIL::HL7::Segment& msh = *this;
						return msh[6][1];
					}

					void SetTimeStamp(const std::string& messageTimeStamp)
					{
						GIL::HL7::Segment& msh = *this;
						msh[7][1] = messageTimeStamp;
					}

					const std::string& GetTimeStamp()
					{
						GIL::HL7::Segment& msh = *this;
						return msh[7][1];
					}

					void SetMessageType(const std::string& messageType)
					{
						GIL::HL7::Segment& msh = *this;
						msh[9][1] = messageType;
					}

					const std::string& GetMessageType()
					{
						GIL::HL7::Segment& msh = *this;
						return msh[9][1];
					}

					void SetMessageTriggerEvent(const std::string& triggerEvent)
					{
						GIL::HL7::Segment& msh = *this;
						msh[9][2] = triggerEvent;
					}

					const std::string& GetMessageTriggerEvent()
					{
						GIL::HL7::Segment& msh = *this;
						return msh[9][2];
					}

					void SetMessageHeader(const std::string& messageHeader)
					{
						GIL::HL7::Segment& msh = *this;
						msh[9][3] = messageHeader;
					}

					const std::string& GetMessageHeader()
					{
						GIL::HL7::Segment& msh = *this;
						return msh[9][3];
					}

					void SetMessageControlId(const std::string& messageControlId)
					{
						GIL::HL7::Segment& msh = *this;
						msh[10][1] = messageControlId;
					}

					const std::string& GetMessageControlId()
					{
						GIL::HL7::Segment& msh = *this;
						return msh[10][1];
					}
				};

				class MSA : public GIL::HL7::Segment {

				public:

					typedef enum ACK_Code {
						AC_Success,
						AC_Error,
						AC_Rejected,
						AC_Unknown
					} ACK_Code;

					MSA(const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : GIL::HL7::Segment("MSA", rs, fs, sfs)
					{
						GIL::HL7::Segment& msa = *this;

						msa <<= GIL::HL7::Field(1, "MSA.1") << GIL::HL7::Component(1, "");
						msa <<= GIL::HL7::Field(2, "MSA.2") << GIL::HL7::Component(1, "");
					}

					MSA& operator=(const GIL::HL7::Segment& segment)
					{
						GIL::HL7::Segment& msa = *this;
						msa = segment;
						return *this;
					}

					void SetReferralMessageControlId(const std::string& refMsgControlId)
					{
						GIL::HL7::Segment& msa = *this;
						msa[2][1] = refMsgControlId;
					}

					const std::string& GetReferralMessageControlId()
					{
						GIL::HL7::Segment& msa = *this;
						return msa[2][1];
					}

					void SetAckCode(ACK_Code code)
					{
						GIL::HL7::Segment& msa = *this;
						switch(code) {
							case AC_Success:
								msa[1][1] = "CA";
								break;
							case AC_Rejected:
								msa[1][1] = "CR";
								break;
							case AC_Error:
							case AC_Unknown:
							default:
								msa[1][1] = "CE";
								break;
						}

					}

					ACK_Code GetAckCode()
					{
						GIL::HL7::Segment& msa = *this;
						if (msa[1][1] == "CA" || msa[1][1] == "AA")
						{
							return AC_Success;
						}
						else if (msa[1][1] == "CR" || msa[1][1] == "AR")
						{
							return AC_Rejected;
						}
						else if (msa[1][1] == "CE" || msa[1][1] == "AE")
						{
							return AC_Error;
						}
						else {
							return AC_Unknown;
						}
					}

					void SetAckCodeString(const std::string& ackCodeString)
					{
						GIL::HL7::Segment& msa = *this;
						msa[1][1] = ackCodeString;
					}

					const std::string& GetAckCodeString()
					{
						GIL::HL7::Segment& msa = *this;
						return msa[1][1];
					}

					bool IsSuccess() {
						return GetAckCode() == AC_Success;
					}

					bool IsRejected() {
						return GetAckCode() == AC_Rejected;
					}

					bool IsErrored() {
						return GetAckCode() == AC_Error;
					}

					bool IsUnknown() {
						return GetAckCode() == AC_Unknown;
					}

				};

				class ERR : public GIL::HL7::Segment {

				public:
					ERR(const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : GIL::HL7::Segment("ERR", rs, fs, sfs)
					{
						//GIL::HL7::Segment& msh = *this;
					}

					ERR& operator=(const GIL::HL7::Segment& segment)
					{
						GIL::HL7::Segment& err = *this;
						err = segment;
						return *this;
					}

					void SetErrorCode(GIL::HL7::Message::ErrorCode errorCode)
					{
						GIL::HL7::Segment& err = *this;
						err[2][1] = GIL::HL7::Message::GetErrorCodeAsString(errorCode);
					}

					GIL::HL7::Message::ErrorCode GetErrorCode()
					{
						GIL::HL7::Segment& err = *this;
						return GIL::HL7::Message::GetErrorCodeFromErrorCodeAsString(err[2][1]);
					}

					const std::string GetErrorCodeDescription()
					{
						return GIL::HL7::Message::GetErrorCodeDescription(GetErrorCode());
					}

					const std::string GetErrorMessage()
					{
						GIL::HL7::Segment& err = *this;
						return err[6][1];
					}

					void SetErrorSeverity(GIL::HL7::Message::ErrorSeverity errorSeverity)
					{
						GIL::HL7::Segment& err = *this;
						err[3][1] = GIL::HL7::Message::GetErrorSeverityString(errorSeverity);
					}

					GIL::HL7::Message::ErrorSeverity GetErrorSeverity()
					{
						GIL::HL7::Segment& err = *this;
						return GIL::HL7::Message::GetErrorSeverityFromString(err[3][1]);
					}
				};

				class PID : public GIL::HL7::Segment {
				public:
					PID(const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : GIL::HL7::Segment("PID", rs, fs, sfs)
					{
						GIL::HL7::Segment& pid = *this;
						pid <<= GIL::HL7::Field(1, "PID.1") << GIL::HL7::Component(1, "SI.1");
						pid <<= GIL::HL7::Field(3, "PID.3");
						pid <<= GIL::HL7::Field(4, "PID.4");
						pid <<= GIL::HL7::Field(5, "PID.5");
						pid <<= GIL::HL7::Field(6, "PID.6");

					}

					PID& operator=(const GIL::HL7::Segment& segment)
					{
						GIL::HL7::Segment& pid = *this;
						pid = segment;
						return *this;
					}

					void SetSetId(const std::string& setId) {
						GIL::HL7::Segment& pid = *this;
						pid[1][1] = setId;
					}

					const std::string& GetSetId() {
						GIL::HL7::Segment& pid = *this;
						return pid[1][1];
					}

					void ClearPatientIdentification()
					{
						GIL::HL7::Segment& pid = *this;
						pid <<= GIL::HL7::Field(3, "PID.3");
					}

					/* Numero de Identificacion Fiscal */
					void SetPatientNIF( const std::string& nif)
					{
						ClearPatientIdentification();
						GIL::HL7::Segment& pid = *this;
						pid[3] << GIL::HL7::Component(1, "CX.1", nif);
						pid[3] << GIL::HL7::Component(4, "CX.4", "MI");
						pid[3] << GIL::HL7::Component(5, "CX.5", "NNESP");
						pid[3] << GIL::HL7::Component(9, "CX.9", "ESP&&ISO3166");
					}

					void AddPatientNIF( const std::string& nif) {
						GIL::HL7::Segment& pid = *this;
						GIL::HL7::Field pid_3(3, "PID.3");
						pid_3 << GIL::HL7::Component(1, "CX.1", nif);
						pid_3 << GIL::HL7::Component(4, "CX.4", "MI");
						pid_3 << GIL::HL7::Component(5, "CX.5", "NNESP");
						pid_3 << GIL::HL7::Component(9, "CX.9", "ESP&&ISO3166");
						pid << pid_3;
					}

					/* Numero de Seguridad Social */
					void SetPatientSS(const std::string& numss)
					{
						ClearPatientIdentification();
						GIL::HL7::Segment& pid = *this;
						pid[3] << GIL::HL7::Component(1, "CX.1", numss);
						pid[3] << GIL::HL7::Component(4, "CX.4", "SS");
						pid[3] << GIL::HL7::Component(5, "CX.5", "SS");
						pid[3] << GIL::HL7::Component(9, "CX.9", "ESP&&ISO3166");
					}

					/* Numero de Seguridad Social */
					void AddPatientSS(const std::string& numss)
					{
						GIL::HL7::Segment& pid = *this;
						GIL::HL7::Field pid_3(3, "PID.3");
						pid_3 << GIL::HL7::Component(1, "CX.1", numss);
						pid_3 << GIL::HL7::Component(4, "CX.4", "SS");
						pid_3 << GIL::HL7::Component(5, "CX.5", "SS");
						pid_3 << GIL::HL7::Component(9, "CX.9", "ESP&&ISO3166");
						pid << pid_3;
					}

					/* CIP del Servicio Nacional de Salud*/
					void SetPatientCIP(const std::string& cip)
					{
						ClearPatientIdentification();
						GIL::HL7::Segment& pid = *this;
						pid[3] << GIL::HL7::Component(1, "CX.1", cip);
						pid[3] << GIL::HL7::Component(4, "CX.4", "MS");
						pid[3] << GIL::HL7::Component(5, "CX.5", "HC");
						pid[3] << GIL::HL7::Component(9, "CX.9", "ESP&&ISO3166");
					}

					/* CIP del Servicio Nacional de Salud*/
					void AddPatientCIP(const std::string& cip)
					{
						GIL::HL7::Segment& pid = *this;
						GIL::HL7::Field pid_3(3, "PID.3");
						pid_3 << GIL::HL7::Component(1, "CX.1", cip);
						pid_3 << GIL::HL7::Component(4, "CX.4", "MS");
						pid_3 << GIL::HL7::Component(5, "CX.5", "HC");
						pid_3 << GIL::HL7::Component(9, "CX.9", "ESP&&ISO3166");
						pid << pid_3;
					}

					/* CIP Hl7Parser */
					void SetPatientHl7ParserCIP(const std::string& cip)
					{
						ClearPatientIdentification();
						GIL::HL7::Segment& pid = *this;
						pid[3] << GIL::HL7::Component(1, "CX.1", cip);
						pid[3] << GIL::HL7::Component(4, "CX.4", "CACL");
						pid[3] << GIL::HL7::Component(5, "CX.5", "JHN");
						pid[3] << GIL::HL7::Component(9, "CX.9", "CL&&ISO3166-2");
					}

					/* CIP Hl7Parser */
					void AddPatientHl7ParserCIP(const std::string& cip)
					{
						GIL::HL7::Segment& pid = *this;
						GIL::HL7::Field pid_3(3, "PID.3");
						pid_3 << GIL::HL7::Component(1, "CX.1", cip);
						pid_3 << GIL::HL7::Component(4, "CX.4", "CACL");
						pid_3 << GIL::HL7::Component(5, "CX.5", "JHN");
						pid_3 << GIL::HL7::Component(9, "CX.9", "CL&&ISO3166-2");
						pid << pid_3;
					}

					/* Numero de pasaporte */
					void SetPatientPassportNum(const std::string& num)
					{
						ClearPatientIdentification();
						GIL::HL7::Segment& pid = *this;
						pid[3] << GIL::HL7::Component(1, "CX.1", num);
						pid[3] << GIL::HL7::Component(4, "CX.4", "MI");
						pid[3] << GIL::HL7::Component(5, "CX.5", "PPN");
						pid[3] << GIL::HL7::Component(9, "CX.9", "ESP&&ISO3166");
					}

					/* Numero de pasaporte */
					void AddPatientPassportNum(const std::string& num)
					{
						GIL::HL7::Segment& pid = *this;
						GIL::HL7::Field pid_3(3, "PID.3");
						pid_3 << GIL::HL7::Component(1, "CX.1", num);
						pid_3 << GIL::HL7::Component(4, "CX.4", "MI");
						pid_3 << GIL::HL7::Component(5, "CX.5", "PPN");
						pid_3 << GIL::HL7::Component(9, "CX.9", "ESP&&ISO3166");
						pid << pid_3;
					}

					/* Numero de Historia Clinica (Dependiente del centro) */
					void SetPatientNHC(const std::string& nhc, const std::string& idCentro)
					{
						ClearPatientIdentification();
						GIL::HL7::Segment& pid = *this;
						pid[3] << GIL::HL7::Component(1, "CX.1", nhc);
						pid[3] << GIL::HL7::Component(4, "CX.4", "HIS");
						pid[3] << GIL::HL7::Component(5, "CX.5", "PI");
						pid[3] << GIL::HL7::Component(9, "CX.9", idCentro + std::string("&&99CENTROSACYL"));
					}

					/* Numero de Historia Clinica (Dependiente del centro) */
					void AddPatientNHC(const std::string& nhc, const std::string& idCentro)
					{
						GIL::HL7::Segment& pid = *this;
						GIL::HL7::Field pid_3(3, "PID.3");
						pid_3 << GIL::HL7::Component(1, "CX.1", nhc);
						pid_3 << GIL::HL7::Component(4, "CX.4", "HIS");
						pid_3 << GIL::HL7::Component(5, "CX.5", "PI");
						pid_3 << GIL::HL7::Component(9, "CX.9", idCentro + std::string("&&99CENTROSACYL"));
						pid << pid_3;
					}

					void SetPatientName(const std::string& nombre, const std::string& apellido1, const std::string& apellido2)
					{
						GIL::HL7::Segment& pid = *this;
						pid[5] << GIL::HL7::Component(1, "XPN.1", apellido1);
						pid[5] << GIL::HL7::Component(2, "XPN.2", nombre);
						pid[6] << GIL::HL7::Component(1, "XPN.1", apellido2);
					}
				};

				class PV1 : public GIL::HL7::Segment {
				public:
					PV1(const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : GIL::HL7::Segment("PV1", rs, fs, sfs)
					{
						GIL::HL7::Segment& pv1 = *this;
						pv1 <<= GIL::HL7::Field(1, "PV1.1") << GIL::HL7::Component(1, "SI.1");
						pv1 <<= GIL::HL7::Field(19, "PV1.19") << GIL::HL7::Component(1, "CX.1") << GIL::HL7::Component(4, "CX.4") << GIL::HL7::Component(5, "CX.5") << GIL::HL7::Component(9, "CX.9");
					}

					PV1& operator=(const GIL::HL7::Segment& segment)
					{
						GIL::HL7::Segment& pv1 = *this;
						pv1 = segment;
						return *this;
					}

					void SetSetId(const std::string& id)
					{
						GIL::HL7::Segment& pv1 = *this;
						pv1[1] << GIL::HL7::Component(1, "SI.1", id);
					}

					void SetPatientClass(const std::string& patientClass)
					{
						GIL::HL7::Segment& pv1 = *this;
						pv1[2] << GIL::HL7::Component(1, "IS.1", patientClass);
					}

					void SetEpisodeNumber(const std::string& episodeNumber, const std::string& ambitoPeticion, const std::string& idCentro)
					{
						GIL::HL7::Segment& pv1 = *this;
						if (!episodeNumber.empty()) {
							pv1[19] << GIL::HL7::Component(1, "CX.1", episodeNumber);
						}
						pv1[19] << GIL::HL7::Component(4, "CX.4", ambitoPeticion);
						pv1[19] << GIL::HL7::Component(5, "CX.5", "VN");
						pv1[19] << GIL::HL7::Component(9, "CX.9", idCentro + std::string("&&99CENTROHl7Parser"));
					}

				};

				class ORC : public GIL::HL7::Segment {
				public:
					ORC(const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : GIL::HL7::Segment("ORC", rs, fs, sfs)
					{
						GIL::HL7::Segment& orc = *this;
						orc <<= GIL::HL7::Field(1, "ORC.1") << GIL::HL7::Component(1, "ID.1");
						orc <<= GIL::HL7::Field(2, "ORC.2") << GIL::HL7::Component(1, "EI.1");
						orc <<= GIL::HL7::Field(2, "ORC.3") << GIL::HL7::Component(1, "EI.1");
						orc <<= GIL::HL7::Field(4, "ORC.4") << GIL::HL7::Component(1, "EI.1");
						orc <<= GIL::HL7::Field(5, "ORC.5") << GIL::HL7::Component(1, "ID.1");
						orc <<= GIL::HL7::Field(12, "ORC.12") << GIL::HL7::Component(1, "XCN.1") << GIL::HL7::Component(2, "XCN.2") << GIL::HL7::Component(3, "XCN.3") << GIL::HL7::Component(4, "XCN.4") << GIL::HL7::Component(9, "XCN.9") << GIL::HL7::Component(13, "XCN.13") << GIL::HL7::Component(22, "XCN.22");
						orc <<= GIL::HL7::Field(17, "ORC.17") << GIL::HL7::Component(1, "CE.1") << GIL::HL7::Component(2, "CE.2") << GIL::HL7::Component(3, "CE.3");
					}

					ORC& operator=(const GIL::HL7::Segment& segment)
					{
						GIL::HL7::Segment& orc = *this;
						orc = segment;
						return *this;
					}

					void SetControlOrder(const std::string& controlOrder)
					{
						GIL::HL7::Segment& orc = *this;
						orc[1][1] = controlOrder;
					}

					void SetPlacerOrderNumber(const std::string& placerOrder)
					{
						GIL::HL7::Segment& orc = *this;
						orc[2][1] = placerOrder;
						orc[4][1] = placerOrder;
					}

					void SetFillerOrderNumber(const std::string& fillerOrder)
					{
						GIL::HL7::Segment& orc = *this;
						orc[3][1] = fillerOrder;
					}

					void SetStatus(const std::string& status)
					{
						GIL::HL7::Segment& orc = *this;
						orc[5][1] = status;
					}

					void SetOrderingProviderName(const std::string& nombre, const std::string& apellido1, const std::string& apellido2)
					{
						GIL::HL7::Segment& orc = *this;
						orc[12][2] = apellido1;
						orc[12][3] = nombre;
						orc[12][4] = apellido2;
					}

					void SetOrderingProviderNIF(const std::string& nif)
					{
						GIL::HL7::Segment& orc = *this;
						orc[12][1] = nif;
						orc[12][9] = "MI";
						orc[12][13] = "NNESP";
						orc[12][22] ="ESP&&ISO3166";
					}

					void SetOrderingProviderCollegNumber(const std::string& num)
					{
						GIL::HL7::Segment& orc = *this;
						orc[12][1] = num;
						orc[12][9] = "MD";
						orc[12][13] = "COM";
						orc[12][22] ="ESP&&ISO3166";
					}

					void SetOrderingFacility(const std::string& id, const std::string& nombre)
					{
						GIL::HL7::Segment& orc = *this;
						orc[21][1] = nombre;
						orc[21][10] = id;
					}

				};

				class OBR : public GIL::HL7::Segment {
				public:
					typedef enum Laterality_Code {
						LAT_R,
						LAT_L
					} ACK_Code;

					OBR(const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : GIL::HL7::Segment("OBR", rs, fs, sfs)
					{
						GIL::HL7::Segment& obr = *this;
						obr <<= GIL::HL7::Field(1, "OBR.1") << GIL::HL7::Component(1, "SI.1");
						obr <<= GIL::HL7::Field(2, "OBR.2") << GIL::HL7::Component(1, "ST.1");
						obr <<= GIL::HL7::Field(2, "OBR.3") << GIL::HL7::Component(1, "ST.1");
						obr <<= GIL::HL7::Field(4, "OBR.4") << GIL::HL7::Component(1, "ST.1") << GIL::HL7::Component(2, "ST.1") << GIL::HL7::Component(3, "ID.1");
						obr <<= GIL::HL7::Field(26, "OBR.26") << GIL::HL7::Component(1, "ST.1");
						obr <<= GIL::HL7::Field(29, "OBR.26") << GIL::HL7::Component(1, "ST.1");
					}

					OBR& operator=(const GIL::HL7::Segment& segment)
					{
						GIL::HL7::Segment& obr = *this;
						obr = segment;
						return *this;
					}

					void SetSetId(const std::string& id)
					{
						GIL::HL7::Segment& obr = *this;
						obr[1][1] = id;
					}

					void SetPlacerOrderNumber(const std::string& placeOrderUID)
					{
						GIL::HL7::Segment& obr = *this;
						obr[2][1] = placeOrderUID;
					}

					void SetStudyUID(const std::string& StudyUID)
					{
						GIL::HL7::Segment& obr = *this;
						obr[2][1] = StudyUID;
					}

					void SetFillerOrderNumber(const std::string& fillerOrder)
					{
						GIL::HL7::Segment& obr = *this;
						obr[3][1] = fillerOrder;
					}

					void SetFillerOrderNumber(const std::string& fillerOrderId, const std::string& fillerOrderNamespaceId)
					{
						GIL::HL7::Segment& obr = *this;
						obr[3][1] = fillerOrderId;
						obr[3][2] = fillerOrderNamespaceId;
					}

					void SetIdentifier(const std::string& identifier)
					{
						GIL::HL7::Segment& obr = *this;
						obr.ParseField(4, identifier);
					}

					void SetIdentifier(const std::string& codPrueba, const std::string& tipoPrueba, const std::string& sistemaCodificacion)
					{
						GIL::HL7::Segment& obr = *this;
						obr[4][1] = codPrueba;
						obr[4][2] = tipoPrueba;
						obr[4][3] = sistemaCodificacion;
					}

					void SetPlacerField1(const std::string& value)
					{
						GIL::HL7::Segment& obr = *this;
						obr[18][1] = value;
					}

					void SetParentResultIdentifier(const std::string& parentObservationIdentifier, const std::string& parentObservationSubIdentifier, const std::string& parentObservationValueDescriptor)
					{
						GIL::HL7::Segment& obr = *this;
						obr[26][1] = parentObservationIdentifier;
						obr[26][2] = parentObservationSubIdentifier;
						obr[26][3] = parentObservationValueDescriptor;
					}

					void SetParentID(const std::string& placerOrderUId, const std::string& fillerOderUId)
					{
						GIL::HL7::Segment& obr = *this;
						obr[29][1] = placerOrderUId;
						obr[29][2] = fillerOderUId;
					}

					void SetLaterality(Laterality_Code laterality)
					{
						GIL::HL7::Segment& obr = *this;
						switch(laterality) {
							case LAT_L:
								{
									obr[46][1] = "L";
									obr[46][2] = "Izquierdo";
									obr[46][3] = "HL70495";
								}
								break;
							case LAT_R:
								{
									obr[46][1] = "R";
									obr[46][2] = "Derecho";
									obr[46][3] = "HL70495";
								}
								break;
						}
					}
				};

				class OBX : public GIL::HL7::Segment {
				public:
					OBX(const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : GIL::HL7::Segment("OBX", rs, fs, sfs)
					{
						GIL::HL7::Segment& obx = *this;
						obx <<= GIL::HL7::Field(1, "OBX.1")   << GIL::HL7::Component(1, "SI.1");
						obx <<= GIL::HL7::Field(2, "OBX.2")   << GIL::HL7::Component(1, "ID.1");
						obx <<= GIL::HL7::Field(3, "OBX.3")   << GIL::HL7::Component(1, "ST.1")  << GIL::HL7::Component(2, "ST.1")  << GIL::HL7::Component(3, "ID.1");
						obx <<= GIL::HL7::Field(5, "OBX.5")   << GIL::HL7::Component(1, "") << GIL::HL7::Component(2, "") << GIL::HL7::Component(3, "");
						obx <<= GIL::HL7::Field(11, "OBX.11") << GIL::HL7::Component(1, "ID.1");
						obx <<= GIL::HL7::Field(16, "OBX.16") << GIL::HL7::Component(1, "XCN.1") << GIL::HL7::Component(2, "XCN.2") << GIL::HL7::Component(3, "XCN.3") << GIL::HL7::Component(4, "XCN.4") << GIL::HL7::Component(9, "XCN.9") << GIL::HL7::Component(13, "XCN.13") << GIL::HL7::Component(22, "XCN.22");

					}

					OBX& operator=(const GIL::HL7::Segment& segment)
					{
						GIL::HL7::Segment& obx = *this;
						obx = segment;
						return *this;
					}

					void SetSetId(const std::string& id)
					{
						GIL::HL7::Segment& obx = *this;
						obx[1][1] = id;
					}

					void SetValueType(const std::string& valueType)
					{
						GIL::HL7::Segment& obx = *this;
						obx[2][1] = valueType;
					}

					void SetIdentifier(const std::string& codigoPrueba, const std::string& descPrueba, const std::string& sistemaCodificacion)
					{
						GIL::HL7::Segment& obx = *this;
						if (codigoPrueba != "") {
							obx[3][1] = codigoPrueba;
						} 
						obx[3][2] = descPrueba;
						if (sistemaCodificacion != "") {
							obx[3][3] = sistemaCodificacion;
						} 
					}

					void SetSubIdentifier(const std::string& value, bool unscape = true)
					{
						GIL::HL7::Segment& obx = *this;
						obx.ParseField(4, value, unscape);
					}

					void SetValue(const std::string& value, bool unscape = true)
					{
						GIL::HL7::Segment& obx = *this;
						obx.ParseField(5, value, unscape);
					}

					void SetWado(const std::string& value)
					{
						GIL::HL7::Segment& obx = *this;
						obx[5][1] = value;
						obx[5][3] = "image";
						obx[5][4] = "dicom";
					}

					void SetValueMetadata(const std::string& idAplicacion, const std::string& dataType, const std::string& dataSubType)
					{
						GIL::HL7::Segment& obx = *this;
						obx[5][2] = idAplicacion;
						obx[5][3] = dataType;
						obx[5][4] = dataSubType;
					}

					void SetObservationResultStatus(const std::string& status)
					{
						GIL::HL7::Segment& obx = *this;
						obx[11][1] = status;
					}

					void SetResponsiveObserverName(const std::string& nombre, const std::string& apellido1, const std::string& apellido2)
					{
						GIL::HL7::Segment& obx = *this;
						obx[16][2] = apellido1;
						obx[16][3] = nombre;
						obx[16][4] = apellido2;
					}

					void SetResponsiveObserverNIF(const std::string& nif)
					{
						GIL::HL7::Segment& obx = *this;
						obx[16][1]  = nif;
						obx[16][9]  = "MI";
						obx[16][13] = "NNESP";
						obx[16][22] ="ESP&&ISO3166";
					}

					void AddObservationMethod(const std::string& codigo, const std::string& desc, const std::string& namespaceid)
					{
						GIL::HL7::Segment& obx = *this;
						obx << GIL::HL7::Field(17, "OBX.17") << GIL::HL7::Component(1, "ST.1", codigo) << GIL::HL7::Component(2, "ST.2", desc) << GIL::HL7::Component(3, "ST.3", namespaceid);						
					}

					void SetObservationMethod(const std::string& codigo, const std::string& desc, const std::string& namespaceid)
					{
						GIL::HL7::Segment& obx = *this;
						obx[17][1] = codigo;
						obx[17][2] = desc;
						obx[17][3] = namespaceid;
					}
				};

				class TQ1 : public GIL::HL7::Segment {
				public:
					TQ1(const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : GIL::HL7::Segment("TQ1", rs, fs, sfs)
					{
						GIL::HL7::Segment& tq1 = *this;
						tq1 <<= GIL::HL7::Field(1, "TQ.1") << GIL::HL7::Component(1, "SI.1");
						tq1 <<= GIL::HL7::Field(9, "TQ.9") << GIL::HL7::Component(1, "ST.1");
					}

					TQ1& operator=(const GIL::HL7::Segment& segment)
					{
						GIL::HL7::Segment& tq1 = *this;
						tq1 = segment;
						return *this;
					}

					void SetSetId(const std::string& id)
					{
						GIL::HL7::Segment& tq1 = *this;
						tq1[1][1] = id;
					}

					void SetUrgency(const std::string& urgency)
					{
						GIL::HL7::Segment& tq1 = *this;
						tq1[9][1] = urgency;
					}
				};

			}

			namespace Messages {

				class MessageInterpreter {

				public:

					MessageInterpreter(const std::string& messageType, const std::string& messageTriggerEvent, const std::string& messageHeader, const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : MSH( messageType, messageTriggerEvent, messageHeader, rs, fs, sfs)
					{
					}

					MessageInterpreter(const GIL::HL7::Message& msg) : MSH(msg.GetSegment("MSH", 1))
					{
					}

					virtual ~MessageInterpreter()
					{
					}

					virtual void GenerateTimeStamp();

					void SetSendingApplication(const std::string& sendingApplication)
					{
						MSH.SetSendingApplication(sendingApplication);
					}

					const std::string& GetSendingApplication()
					{
						return MSH.GetSendingApplication();
					}

					void SetSendingFacility(const std::string& sendingFacility)
					{
						MSH.SetSendingFacility(sendingFacility);
					}

					const std::string& GetSendingFacility()
					{
						return MSH.GetSendingFacility();
					}

					void SetReceivingApplication(const std::string& receivingApplication)
					{
						MSH.SetReceivingApplication(receivingApplication);
					}

					const std::string& GetReceivingApplicacion()
					{
						return MSH.GetReceivingApplication();
					}

					void SetReceivingFacility(const std::string& receivingFacility)
					{
						MSH.SetReceivingFacility(receivingFacility);
					}

					const std::string& GetReceivingFacility()
					{
						return MSH.GetReceivingFacility();
					}

					void SetTimeStamp(const std::string& messageTimeStamp)
					{
						MSH.SetTimeStamp(messageTimeStamp);
					}

					const std::string& GetTimeStamp()
					{
						return MSH.GetTimeStamp();
					}

					void SetMessageType(const std::string& messageType)
					{
						MSH.SetMessageType(messageType);
					}

					const std::string& GetMessageType()
					{
						return MSH.GetMessageType();
					}

					void SetMessageTriggerEvent(const std::string& triggerEvent)
					{
						MSH.SetMessageTriggerEvent(triggerEvent);
					}

					const std::string& GetMessageTriggerEvent()
					{
						return MSH.GetMessageTriggerEvent();
					}

					void SetMessageHeader(const std::string& messageHeader)
					{
						MSH.SetMessageHeader(messageHeader);
					}

					const std::string& GetMessageHeader()
					{
						return MSH.GetMessageHeader();
					}

					void SetMessageControlId(const std::string& messageControlId)
					{
						MSH.SetMessageControlId(messageControlId);
					}

					const std::string& GetMessageControlId()
					{
						return MSH.GetMessageControlId();
					}

					void Build(GIL::HL7::Message& msg)
					{
						GenerateTimeStamp();
						msg.SetHeader(MSH.GetMessageHeader());
						msg["MSH"] = MSH;

						BuildSpecific(msg);
					}

				protected:

					virtual void BuildSpecific(GIL::HL7::Message& msg) = 0;

				public:

					GIL::Hl7Parser::Segmentos::MSH MSH;

				protected:
					std::string messageType;
					std::string messageTriggerEvent;

				};

				class ORU_R01Interpreter : public MessageInterpreter {

				public:

					class PatientResult {

					public:

						class Patient {

						public:

							class PatientIdentification {

							public:

								PatientIdentification()
								{
								}

								void SetSetId(unsigned int id)
								{
									std::stringstream ss;
									ss << id;
									PID.SetSetId(ss.str());
								}

								void SetPatientNIF( const std::string& nif)
								{
									PID.SetPatientNIF(nif);
								}

								void AddPatientNIF( const std::string& nif)
								{
									PID.AddPatientNIF(nif);
								}

								/* Numero de Seguridad Social */
								void SetPatientSS(const std::string& numss)
								{
									PID.SetPatientSS(numss);
								}

								/* Numero de Seguridad Social */
								void AddPatientSS(const std::string& numss)
								{
									PID.AddPatientSS(numss);
								}

								/* CIP del Servicio Nacional de Salud*/
								void SetPatientCIP(const std::string& cip)
								{
									PID.SetPatientCIP(cip);
								}

								/* CIP del Servicio Nacional de Salud*/
								void AddPatientCIP(const std::string& cip)
								{
									PID.AddPatientCIP(cip);
								}

								/* CIP Hl7Parser */
								void SetPatientHl7ParserCIP(const std::string& cip)
								{
									PID.SetPatientHl7ParserCIP(cip);
								}

								/* CIP Hl7Parser */
								void AddPatientHl7ParserCIP(const std::string& cip)
								{
									PID.AddPatientHl7ParserCIP(cip);
								}

								/* Numero de pasaporte */
								void AddPatientPassportNum(const std::string& num)
								{
									PID.AddPatientPassportNum(num);
								}

								/* Numero de pasaporte */
								void SetPatientPassportNum(const std::string& num)
								{
									PID.SetPatientPassportNum(num);
								}

								/* Numero de Historia Clinica (Dependiente del centro) */
								void SetPatientNHC(const std::string& nhc, const std::string& idCentro)
								{
									PID.SetPatientNHC(nhc, idCentro);
								}

								/* Numero de Historia Clinica (Dependiente del centro) */
								void AddPatientNHC(const std::string& nhc, const std::string& idCentro)
								{
									PID.AddPatientNHC(nhc, idCentro);
								}

								void SetPatientName(const std::string& nombre, const std::string& apellido1, const std::string& apellido2)
								{
									PID.SetPatientName(nombre, apellido1, apellido2);
								}

								GIL::Hl7Parser::Segmentos::PID PID;
							};

							class PatientVisit {

							public:

								PatientVisit()
								{
								}

								void SetEpisodeNumber(const std::string& nep, const std::string& ambitoPeticion, const std::string& idCentro)
								{
									PV1.SetEpisodeNumber(nep, ambitoPeticion, idCentro);
								}

								void SetSetId(unsigned int id)
								{
									std::stringstream ss;
									ss << id;
									PV1.SetSetId(ss.str());
								}

								void SetPatientTypeExternal()
								{
									PV1.SetPatientClass("O");
								}

								void SetPatientTypeAdmitted()
								{
									PV1.SetPatientClass("I");
								}

							public:
								GIL::Hl7Parser::Segmentos::PV1 PV1;

							};

							Patient()
							{
							}

						public:

							void BuildSpecific(GIL::HL7::Message& msg)
							{
								msg << patientIdentification.PID;
								msg << patientVisit.PV1;
							}

							PatientIdentification patientIdentification;
							PatientVisit patientVisit;
						};

						class Order {

						public:
							class OrderCommon {

							public:
								OrderCommon()
								{
								}

								void SetStatusCompleted()
								{
									ORC.SetStatus("CM");
									ORC.SetControlOrder("SC");
								}

								void SetOrderingUID(const std::string& uid)
								{
									ORC.SetPlacerOrderNumber(uid);
								}

								void SetProducerUID(const std::string& producerUID)
								{
									ORC.SetFillerOrderNumber(producerUID);
								}

								void SetProducerUID(const std::string& accessionNumber,const std::string& idPACS)
								{
									std::stringstream ostr;
									ostr << accessionNumber << '^' << idPACS;
									ORC.SetFillerOrderNumber(ostr.str());
								}

								void SetOrderingProviderName(const std::string& nombre, const std::string& apellido1, const std::string& apellido2)
								{
									ORC.SetOrderingProviderName(nombre, apellido1, apellido2);
								}

								void SetOrderingProviderNIF(const std::string& nif)
								{
									ORC.SetOrderingProviderNIF(nif);
								}

								void SetOrderingCenter(const std::string& id, const std::string& nombre)
								{
									ORC.SetOrderingFacility(id, nombre);
								}

								GIL::Hl7Parser::Segmentos::ORC ORC;
							};

							class TimingQuantity {
							public:
								TimingQuantity()
								{
								}

								void SetSetId(unsigned int id)
								{
									std::stringstream ss;
									ss << id;
									TQ1.SetSetId(ss.str());
								}

								void SetUrgencyNormal()
								{
									TQ1.SetUrgency("R");
								}

								void SetUrgencyUrgent()
								{
									TQ1.SetUrgency("S");
								}

								GIL::Hl7Parser::Segmentos::TQ1 TQ1;
							};

							class ObservationRequest {

							public:
								ObservationRequest()
								{
								}

								void SetSetId(unsigned int id)
								{
									std::stringstream ss;
									ss << id;
									OBR.SetSetId(ss.str());
								}

								void SetOrderingUID(const std::string& orderUId)
								{
									OBR.SetPlacerOrderNumber(orderUId);
								}

								void SetProducerUID(const std::string& producerUID)
								{
									OBR.SetFillerOrderNumber(producerUID);
								}

								void SetProducerUID(const std::string& accessionNumber,const std::string& idPACS)
								{
									std::stringstream ostr;
									ostr << accessionNumber << '^' << idPACS;
									OBR.SetFillerOrderNumber(ostr.str());
								}

								void SetIdentifier(const std::string& id)
								{
									OBR.SetIdentifier(id);
								}

								void SetIdentifier(const std::string& codPrueba, const std::string& tipoPrueba, const std::string& sistemaCodificacion)
								{
									OBR.SetIdentifier(codPrueba, tipoPrueba, sistemaCodificacion);
								}

								//  identificadordObservacionReferida = OBX.3, subIdentificadorObservacionReferida = OBX.4, valorEvidencia = OBX.4
								void SetParentResultIdentifier(const std::string& identificadordObservacionReferida, const std::string& subIdentificadorObservacionReferida, const std::string& valorEvidencia)
								{
									OBR.SetParentResultIdentifier(identificadordObservacionReferida, subIdentificadorObservacionReferida, valorEvidencia);
								}

								void SetParentID(const std::string& placerOrderUId, const std::string& fillerOderUId)
								{
									OBR.SetParentID(placerOrderUId, fillerOderUId);
								}

								void SetStudyUID(const std::string& StudyUID)
								{
									OBR.SetStudyUID(StudyUID);
								}

								void SetPlacerField1(const std::string& value)
								{
									OBR.SetPlacerField1(value);
								}

								void SetLateralityRight()
								{
									OBR.SetLaterality(GIL::Hl7Parser::Segmentos::OBR::LAT_R);
								}

								void SetLateralityLeft()
								{
									OBR.SetLaterality(GIL::Hl7Parser::Segmentos::OBR::LAT_L);
								}

								GIL::Hl7Parser::Segmentos::OBR OBR;
							};

							class ObservationGroup {

							public:

								class Observation {
								public:

									Observation()
									{
									}

									void Clear()
									{
										OBX = GIL::Hl7Parser::Segmentos::OBX();
									}

									void SetSetId(unsigned int id)
									{
										std::stringstream ss;
										ss << id;
										OBX.SetSetId(ss.str());
									}

									void SetDataType(const std::string& dataType)
									{
										OBX.SetValueType(dataType);
									}

									void SetSubIdentifier(unsigned int id)
									{
										std::stringstream ss;
										ss << id;
										OBX.SetSubIdentifier(ss.str());
									}

									void SetIdentifier(const std::string& codigoPrueba, const std::string& descPrueba, const std::string& sistemaCodificacion)
									{
										OBX.SetIdentifier(codigoPrueba, descPrueba, sistemaCodificacion);
									}

									void SetValue(const std::string& value, bool unscape = true)
									{
										OBX.SetValue(value, unscape);
									}

									void SetValueMetadata(const std::string& idAplicacion, const std::string& dataType, const std::string& dataSubType)
									{
										OBX.SetValueMetadata(idAplicacion, dataType, dataSubType);
									}

									void SetWado(const std::string& value)
									{
										OBX.SetWado(value);
									}

									void SetResponsiveObserverName(const std::string& nombre, const std::string& apellido1, const std::string& apellido2)
									{
										OBX.SetResponsiveObserverName(nombre, apellido1, apellido2);
									}

									void SetResponsiveObserverNIF(const std::string& nif)
									{
										OBX.SetResponsiveObserverNIF(nif);
									}

									void SetFinal()
									{
										OBX.SetObservationResultStatus("F");
									}

									void AddObservationMethod(const std::string& codigo, const std::string& desc, const std::string& namespaceid)
									{
										OBX.AddObservationMethod(codigo, desc, namespaceid);
									}

									GIL::Hl7Parser::Segmentos::OBX OBX;
								};

								ObservationGroup()
								{

								}

								void AddObservation(const Observation& ob)
								{
									Observations.push_back(ob);
								}

								std::list<Observation> Observations;
							};

							Order()
							{

							}

						public:
							void BuildSpecific(GIL::HL7::Message& msg)
							{
								msg << orderCommon.ORC;
								msg << observationRequest.OBR;
								msg << timingQuantity.TQ1;

								for (std::list<Order::ObservationGroup::Observation>::iterator it = observationGroup.Observations.begin(); it != observationGroup.Observations.end(); ++it)
								{
									msg << (*it).OBX;
								}

							}

							OrderCommon orderCommon;
							TimingQuantity timingQuantity;
							ObservationRequest observationRequest;
							ObservationGroup observationGroup;

						};

						PatientResult()
						{
						}

					public:

						void BuildSpecific(GIL::HL7::Message& msg)
						{
							patient.BuildSpecific(msg);

							for (std::list<Order>::iterator it = orders.begin(); it != orders.end(); ++it) {
								(*it).BuildSpecific(msg);
							}
						}

						void AddOrder(Order& order)
						{
							orders.push_back(order);
						}

						Patient patient;
						std::list<Order> orders;
					};

					ORU_R01Interpreter(const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : MessageInterpreter("ORU", "R01", "ORU_R01", rs, fs, sfs)
					{
					}

				protected:

					virtual void BuildSpecific(GIL::HL7::Message& msg)
					{
						for (std::list<PatientResult>::iterator it = results.begin(); it != results.end(); ++it) {
							(*it).BuildSpecific(msg);
						}

					}

				public:

					void AddPatientResult(PatientResult& result)
					{
						results.push_back(result);
					}

				protected:

						std::list<PatientResult> results;
				};

				class ACKInterpreter : public MessageInterpreter {

				public:

					ACKInterpreter(const std::string& rs = RECORD_SEPARATOR, const std::string& fs = "|", const std::string& sfs = "^") : MessageInterpreter("ACK", "", "ACK", rs, fs,sfs)
					{
						MSH <<= GIL::HL7::Field(15, "MSH.15") << GIL::HL7::Component(1, "", "NE");
						MSH <<= GIL::HL7::Field(16, "MSH.16") << GIL::HL7::Component(1, "", "NE");
					}

					ACKInterpreter(const GIL::HL7::Message& msg) : MessageInterpreter(msg), MSA(), ERR()
					{
						MSA = msg.GetSegment("MSA", 1);
						ERR = msg.GetSegment("ERR", 1);
					}

					// Obtiene el Control ID del mensaje al que se refiere este ACK
					void SetReferralMessageControlId (MessageInterpreter& msg)
					{
						MSA.SetReferralMessageControlId(msg.MSH.GetMessageControlId());
					}

					void SetReferralMessageControlId (GIL::HL7::Message& msg)
					{
						MSA.SetReferralMessageControlId(msg["MSH"][10][1]);
					}

					void SetReferralMessageControlId (const std::string& msgControlId)
					{
						MSA.SetReferralMessageControlId(msgControlId);
					}

					const std::string& GetReferralMessageControlId ()
					{
						return MSA.GetReferralMessageControlId();
					}

					void SetAckCode(GIL::Hl7Parser::Segmentos::MSA::ACK_Code code)
					{
						return MSA.SetAckCode(code);
					}

					GIL::Hl7Parser::Segmentos::MSA::ACK_Code GetAckCode()
					{
						return MSA.GetAckCode();
					}

					bool IsSuccess ()
					{
						return MSA.IsSuccess();
					}

					bool IsRejected ()
					{
						return MSA.IsRejected();
					}

					bool IsErrored ()
					{
						return MSA.IsErrored();
					}

					bool IsUnknown ()
					{
						return MSA.IsUnknown();
					}

					void SetErrorCode(GIL::HL7::Message::ErrorCode errorCode)
					{
						ERR.SetErrorCode(errorCode);
					}

					GIL::HL7::Message::ErrorCode GetErrorCode()
					{
						return ERR.GetErrorCode();
					}

					void SetErrorSeverity(GIL::HL7::Message::ErrorSeverity errorSeverity)
					{
						return ERR.SetErrorSeverity(errorSeverity);
					}

					GIL::HL7::Message::ErrorSeverity GetErrorSeverity()
					{
						return ERR.GetErrorSeverity();
					}

				protected:

					virtual void BuildSpecific(GIL::HL7::Message& msg)
					{
						msg["MSA"] = MSA;
						msg["ERR"] = ERR;
					}

				public:

					GIL::Hl7Parser::Segmentos::MSA MSA;
					GIL::Hl7Parser::Segmentos::ERR ERR;
				};
		}
	}
}
