///<summary></summary>
		public static long Insert(EhrLabClinicalInfo ehrLabClinicalInfo) {
			if(RemotingClient.RemotingRole==RemotingRole.ClientWeb) {
				ehrLabClinicalInfo.EhrLabClinicalInfoNum=Meth.GetLong(MethodBase.GetCurrentMethod(),ehrLabClinicalInfo);
				return ehrLabClinicalInfo.EhrLabClinicalInfoNum;
			}
			return Crud.EhrLabClinicalInfoCrud.Insert(ehrLabClinicalInfo);
		}
Example #2
0
		///<summary>Surround with Try/Catch.  Processes an HL7 message into an EHRLab object.</summary>
		public static List<EhrLab> ProcessHl7Message(string message, Patient patCur, bool isImport){
			//Patient patcur;
			string PIDSegment="";//used to store the PID segment and attached to each lab order generated by this message.
			List<EhrLab> listRetVal=new List<EhrLab>();
			EhrLab ehrLabCur=new EhrLab();
			if(!message.StartsWith("MSH")){
				//cannnot parse message without message header at the very least
				throw new Exception("MSH segment not found.");
			}
			string[] segments=message.Split(new string[] { "\r\n" },StringSplitOptions.None);
			string[] fields;
			string noteSegment="";//used to attach notes to the right objects.
			for(int s=0;s<segments.Length;s++) {
				string segment=segments[s];
				fields=segment.Split('|');
				switch(fields[0]) {//Segment Identifier.
					case "MSH":
						if(fields[8]!="ORU^R01^ORU_R01") {
							throw new Exception("MSH.9 contained wrong value.  \""+fields[8]+"\" was found, \"ORU^R01^ORU_R01\" was expected.");
						}
						if(fields[11]!="2.5.1") {
							throw new Exception("MSH.12 shows message version \""+fields[11]+"\", only version \"2.5.1\" is currently supported.");
						}
						containsRequiredSegmentsHelper(message); //validate required segments here, after we have verified this is an ORU_R01 message
						if(fields[20].Split('~').Length==0) {
							throw new Exception("MSH.21 does not contain any values, the LRI_GU_RU_Profile value \"2.16.840.1.113883.9.17\" is expected.");
						}
						for(int i=0;i<fields[20].Split('~').Length;i++) {
							if(i==fields[20].Split('~').Length) {
								throw new Exception("MSH.21 ("+i+") indicates sender's message does not conform to LRI_GU_RU_Profile \"2.16.840.1.113883.9.17\"");
							}
							if(fields[20].Split('~')[i]=="2.16.840.1.113883.9.17") {
								break;//found expected value.
							}
						}
						break;
					//case "SFT": //Software Segment
					//	break;
					case "PID":
						PIDSegment=segment;
						noteSegment="PID";
						for(int i=0;i<fields[3].Split('~').Length;i++) {
							if(patCur==null) {
								patCur=Patients.GetByGUID(fields[3].Split('~')[i].Split('^')[0],								//ID Number
																					fields[3].Split('~')[i].Split('^')[3].Split('&')[1]);	//Assigning Authority ID 
							}
							if(patCur!=null) {
								ehrLabCur.PatNum=patCur.PatNum;
							}
							else {
								ehrLabCur.PatNum=0;
								//if(i==fields[3].Split('~').Length) {//we have checked all patient ID's and none of them were a valid patnum in our DB.
								//	throw new Exception("PID.3 does not contain a known patient ID.");//we should have an option to manually associate lab results with a patient record, in the UI layer.
								//}
							}
						}
						//all other PID segments are informative, PID.3 is the only one we need to process.
						break;
					//case "PD1": //patient demographics
					//	break;
					//case "NK1": //Next of Kin/Associated Parties
					//	break;
					//case "PV1": //Patient Visit
					//	break;
					//case "PV2": //Patient Visit addiotional information
					//	break;
					case "ORC":
						//Each new ORC segment designates a new EhrLabOrder attached to the same patient.
						if(ehrLabCur.PlacerOrderNum!=null || ehrLabCur.FillerOrderNum!=null) {//these fields are filled by the ORC segment, if they are blank, this is the first ORC segment encountered.
							listRetVal.Add(ehrLabCur);
							ehrLabCur=new EhrLab();
							ehrLabCur.PatNum=listRetVal[0].PatNum;
						}
						ehrLabCur.OriginalPIDSegment=PIDSegment;//may not match actual PatNum/Patient information.
						try {
							ehrLabCur.OrderControlCode=(HL70119)Enum.Parse(typeof(HL70119),fields[1]);
						}
						catch {
							throw new Exception("ORC.1 does not contain a valid Order Control Code (HL70119 value set).");
						}
						//Placer Order Num
						if(fields[2].Length!=0) {//optional field, length may be 0 if field was ommitted.
							ehrLabCur.PlacerOrderNum							=fields[2].Split('^')[0];
							ehrLabCur.PlacerOrderNamespace				=fields[2].Split('^')[1];
							ehrLabCur.PlacerOrderUniversalID			=fields[2].Split('^')[2];
							ehrLabCur.PlacerOrderUniversalIDType	=fields[2].Split('^')[3];
						}
						//Filler Order Num
						ehrLabCur.FillerOrderNum							=fields[3].Split('^')[0];
						ehrLabCur.FillerOrderNamespace				=fields[3].Split('^')[1];
						ehrLabCur.FillerOrderUniversalID			=fields[3].Split('^')[2];
						ehrLabCur.FillerOrderUniversalIDType	=fields[3].Split('^')[3];
						//Filler Group Num
						if(fields[4].Length!=0) {
							ehrLabCur.PlacerGroupNum							=fields[4].Split('^')[0];
							ehrLabCur.PlacerGroupNamespace				=fields[4].Split('^')[1];
							ehrLabCur.PlacerGroupUniversalID			=fields[4].Split('^')[2];
							ehrLabCur.PlacerGroupUniversalIDType	=fields[4].Split('^')[3];
						}
						//Ordering Provider
						ehrLabCur.OrderingProviderID															=fields[12].Split('^')[0];
						ehrLabCur.OrderingProviderLName													=fields[12].Split('^')[1];
						ehrLabCur.OrderingProviderFName													=fields[12].Split('^')[2];
						ehrLabCur.OrderingProviderMiddleNames										=fields[12].Split('^')[3];
						ehrLabCur.OrderingProviderSuffix													=fields[12].Split('^')[4];
						ehrLabCur.OrderingProviderPrefix													=fields[12].Split('^')[5];
						ehrLabCur.OrderingProviderAssigningAuthorityNamespaceID	=fields[12].Split('^')[8].Split('&')[0];
						ehrLabCur.OrderingProviderAssigningAuthorityUniversalID	=fields[12].Split('^')[8].Split('&')[1];
						ehrLabCur.OrderingProviderAssigningAuthorityIDType				=fields[12].Split('^')[8].Split('&')[2];
						try {
							ehrLabCur.OrderingProviderNameTypeCode=(HL70200)Enum.Parse(typeof(HL70200),fields[12].Split('^')[9]);
						}
						catch {
							throw new Exception("ORC.12.10 does not contain a valid Name Type Code (HL70200 value set).");
						}
						try {
							ehrLabCur.OrderingProviderIdentifierTypeCode	=(HL70203)Enum.Parse(typeof(HL70203),fields[12].Split('^')[12]);
						}
						catch {
							throw new Exception("ORC.12.13 does not contain a valid Identifier Type Code (HL70203 value set).");
						}
						break;
					case "OBR":
						noteSegment="OBR";
						ehrLabCur.SetIdOBR=PIn.Long(fields[1]);
						if(isImport) {
							ehrLabCur.ListEhrLabNotes=new List<EhrLabNote>();
							ehrLabCur.ListEhrLabResults=new List<EhrLabResult>();
						}
						//OBR order num should always be identical to OCR order number//Not true.
						if(ehrLabCur.FillerOrderNum!=fields[3].Split('^')[0]) {
							throw new Exception("Filler order numbers in OCR.3 and OBR.3 segments do not match.");
						}
						//Universal Service ID
						ehrLabCur.UsiID											=																			fields[4].Split('^')[0];
						ehrLabCur.UsiText										=																			fields[4].Split('^')[1];
						try { ehrLabCur.UsiCodeSystemName			=																			fields[4].Split('^')[2]; }
						catch { }
						try { ehrLabCur.UsiIDAlt							=																			fields[4].Split('^')[3]; }
						catch { }
						try { ehrLabCur.UsiTextAlt						=																			fields[4].Split('^')[4]; }
						catch { }
						try { ehrLabCur.UsiCodeSystemNameAlt	=																			fields[4].Split('^')[5]; }
						catch { }
						try { ehrLabCur.UsiTextOriginal				=																			fields[4].Split('^')[6]; }
						catch { }
						//Observation Date Time
						ehrLabCur.ObservationDateTimeStart		=fields[7];
						if(fields[8].Length!=0) {
							ehrLabCur.ObservationDateTimeEnd		=fields[8];
						}
						try { ehrLabCur.SpecimenActionCode		=(HL70065)Enum.Parse(typeof(HL70065),fields[11]); }
						catch { }
						if(isImport) {
							ehrLabCur.ListRelevantClinicalInformations=new List<EhrLabClinicalInfo>();
						}
						for(int i=0;i<fields[13].Split('~').Length;i++) {
							if(fields[13].Length==0) {
								break;//nothing to process
							}
							string tempClinInfo=fields[13].Split('~')[i];
							EhrLabClinicalInfo ehrLabClinicalInfo=new EhrLabClinicalInfo();
							ehrLabClinicalInfo.ClinicalInfoID											=tempClinInfo.Split('^')[0];
							try { ehrLabClinicalInfo.ClinicalInfoText										=tempClinInfo.Split('^')[1]; }
							catch { }
							try { ehrLabClinicalInfo.ClinicalInfoCodeSystemName					=tempClinInfo.Split('^')[2]; }
							catch { }
							try { ehrLabClinicalInfo.ClinicalInfoIDAlt									=tempClinInfo.Split('^')[3]; }
							catch { }
							try { ehrLabClinicalInfo.ClinicalInfoTextAlt								=tempClinInfo.Split('^')[4]; }
							catch { }
							try { ehrLabClinicalInfo.ClinicalInfoCodeSystemNameAlt			=tempClinInfo.Split('^')[5]; }
							catch { }
							try { ehrLabClinicalInfo.ClinicalInfoTextOriginal						=tempClinInfo.Split('^')[6]; }
							catch { }
							ehrLabCur.ListRelevantClinicalInformations.Add(ehrLabClinicalInfo);
						}
						//OBR 16; Ordering Provider same as OCR. //not validating or checking at this time.
						ehrLabCur.ResultDateTime=fields[22];
						if(fields.Length<=25) { break; }//likely that fields beyond this are left out.
						try { ehrLabCur.ResultStatus												=(HL70123)Enum.Parse(typeof(HL70123),fields[25]); }
						catch { }
						//Parent Result
						if(fields.Length<=26) { break; }//likely that fields beyond this are left out.
						ehrLabCur.ParentObservationID												=fields[26].Split('^')[0].Split('&')[0];
						try { ehrLabCur.ParentObservationText									=fields[26].Split('^')[0].Split('&')[1]; }
						catch { }
						try { ehrLabCur.ParentObservationCodeSystemName				=fields[26].Split('^')[0].Split('&')[2]; }
						catch { }
						try { ehrLabCur.ParentObservationIDAlt								=fields[26].Split('^')[0].Split('&')[3]; }
						catch { }
						try { ehrLabCur.ParentObservationTextAlt							=fields[26].Split('^')[0].Split('&')[4]; }
						catch { }
						try { ehrLabCur.ParentObservationCodeSystemNameAlt		=fields[26].Split('^')[0].Split('&')[5]; }
						catch { }
						try { ehrLabCur.ParentObservationTextOriginal					=fields[26].Split('^')[0].Split('&')[6]; }
						catch { }
						try { ehrLabCur.ParentObservationSubID								=fields[26].Split('^')[1]; }
						catch { }
						//Results Copy To
						if(isImport) {
							ehrLabCur.ListEhrLabResultsCopyTo=new List<EhrLabResultsCopyTo>();
						}
						if(fields.Length<28) { break; }//likely that fields beyond this are left out.
						for(int i=0;i<fields[28].Split('~').Length;i++) {
							EhrLabResultsCopyTo tempRCT=new EhrLabResultsCopyTo();
							string stringRCT=fields[28].Split('~')[i];
							if(stringRCT.Length==0) {
								continue;//usually only if nothing was sent, but also if an empty field was sent.
							}
							tempRCT.CopyToID															=stringRCT.Split('^')[0];
							tempRCT.CopyToLName														=stringRCT.Split('^')[1];
							tempRCT.CopyToFName														=stringRCT.Split('^')[2];
							tempRCT.CopyToMiddleNames											=stringRCT.Split('^')[3];
							tempRCT.CopyToSuffix													=stringRCT.Split('^')[4];
							tempRCT.CopyToPrefix													=stringRCT.Split('^')[5];
							tempRCT.CopyToAssigningAuthorityUniversalID		=stringRCT.Split('^')[8].Split('&')[0];
							tempRCT.CopyToAssigningAuthorityNamespaceID		=stringRCT.Split('^')[8].Split('&')[1];
							tempRCT.CopyToAssigningAuthorityIDType				=stringRCT.Split('^')[8].Split('&')[2];
							try {
								tempRCT.CopyToNameTypeCode=(HL70200)Enum.Parse(typeof(HL70200),stringRCT.Split('^')[9]);
							}
							catch {
								throw new Exception("ORC.12.10 does not contain a valid Name Type Code (HL70200 value set).");
							}
							try {
								ehrLabCur.OrderingProviderIdentifierTypeCode	=(HL70203)Enum.Parse(typeof(HL70203),stringRCT.Split('^')[12]);
							}
							catch {
								throw new Exception("ORC.12.13 does not contain a valid Identifier Type Code (HL70203 value set).");
							}
							ehrLabCur.ListEhrLabResultsCopyTo.Add(tempRCT);
						}
						//Parent Lab
						if(fields.Length<29) { break; }//likely that fields beyond this are left out.
						ehrLabCur.ParentPlacerOrderNum												=fields[29].Split('^')[0].Split('&')[0];
						try { ehrLabCur.ParentPlacerOrderNamespace							=fields[29].Split('^')[0].Split('&')[1]; }
						catch { }
						try { ehrLabCur.ParentPlacerOrderUniversalID						=fields[29].Split('^')[0].Split('&')[2]; }
						catch { }
						try { ehrLabCur.ParentPlacerOrderUniversalIDType				=fields[29].Split('^')[0].Split('&')[3]; }
						catch { }
						try { ehrLabCur.ParentFillerOrderNum										=fields[29].Split('^')[1].Split('&')[0]; }
						catch { }
						try { ehrLabCur.ParentFillerOrderNamespace							=fields[29].Split('^')[1].Split('&')[1]; }
						catch { }
						try { ehrLabCur.ParentFillerOrderUniversalID						=fields[29].Split('^')[1].Split('&')[2]; }
						catch { }
						try { ehrLabCur.ParentFillerOrderUniversalIDType				=fields[29].Split('^')[1].Split('&')[3]; }
						catch { }
						if(fields.Length<31) {
							break;//next segment. all additional fields were omitted from this one.
						}
						if(fields.Length<49) { break; }//likely that fields beyond this are left out.
						//result Handling
						ehrLabCur.ListEhrLabResultsHandlingF										=fields[49].Contains("F");
						ehrLabCur.ListEhrLabResultsHandlingN										=fields[49].Contains("N");
						break;
					case "NTE":
						//Each not can contain any number of comments, these comments will be carrot delimited. That will be handled later in the UI.  Just store this NTE Segment in an EHRLabNote
						EhrLabNote ehrNote=new EhrLabNote();
						//todo:No SetIDNTE?
						ehrNote.Comments=fields[3];
						switch(noteSegment) {
							case "OBX":
								//Attach note to observation.
								ehrLabCur.ListEhrLabResults[ehrLabCur.ListEhrLabResults.Count-1].ListEhrLabResultNotes.Add(ehrNote);
								break;
							case "PID":
							case "OBR":
							default:
								//if PID, OBR, or Other just attach note to the lab.
								ehrLabCur.ListEhrLabNotes.Add(ehrNote);
								break;
						}
						break;
					case "TQ1":
						ehrLabCur.TQ1SetId=PIn.Long(fields[1]);
						ehrLabCur.TQ1DateTimeStart=fields[7];
						ehrLabCur.TQ1DateTimeEnd=fields[8];
						break;
					//case "TQ2": //Timing/Quantity Order Sequence
					//	break;
					//case "CTD": //Contact Data
					//	break;
					case "OBX":
						noteSegment="OBX";
						//if(ehrLabCur.ListEhrLabResults==null) {
						//	ehrLabCur.ListEhrLabResults=new List<EhrLabResult>();
						//}
						EhrLabResult labResult=new EhrLabResult();
						labResult.SetIdOBX=PIn.Long(fields[1]);
						try { labResult.ValueType=(HL70125)Enum.Parse(typeof(HL70125),fields[2]); }
						catch { }
						//Lab Result Observation Identifier (LOINC)
						labResult.ObservationIdentifierID									=fields[3].Split('^')[0];
						try { labResult.ObservationIdentifierText								=fields[3].Split('^')[1]; }
						catch { }
						try { labResult.ObservationIdentifierCodeSystemName			=fields[3].Split('^')[2]; }
						catch { }
						try { labResult.ObservationIdentifierIDAlt							=fields[3].Split('^')[3]; }
						catch { }
						try { labResult.ObservationIdentifierTextAlt						=fields[3].Split('^')[4]; }
						catch { }
						try { labResult.ObservationIdentifierCodeSystemNameAlt	=fields[3].Split('^')[5]; }
						catch { }
						if(fields[3].Split('^').Length>6) {
							labResult.ObservationIdentifierTextOriginal							=fields[3].Split('^')[6];
						}
						labResult.ObservationIdentifierSub=fields[4];
						//Observation Value
						switch(labResult.ValueType) {
							case HL70125.CE:
							case HL70125.CWE:
								labResult.ObservationValueCodedElementID										=fields[5].Split('^')[0];
								try { labResult.ObservationValueCodedElementText									=fields[5].Split('^')[1]; }
								catch { }
								try { labResult.ObservationValueCodedElementCodeSystemName				=fields[5].Split('^')[2]; }
								catch { }
								try { labResult.ObservationValueCodedElementIDAlt									=fields[5].Split('^')[3]; }
								catch { }
								try { labResult.ObservationValueCodedElementTextAlt								=fields[5].Split('^')[4]; }
								catch { }
								try { labResult.ObservationValueCodedElementCodeSystemNameAlt			=fields[5].Split('^')[5]; }
								catch { }
								if(labResult.ValueType==HL70125.CWE) {
									labResult.ObservationValueCodedElementTextOriginal=fields[5].Split('^')[6];
								}
								break;
							case HL70125.DT:
							case HL70125.TS:
								labResult.ObservationValueDateTime=fields[5];
								break;
							case HL70125.FT://formatted text
							case HL70125.ST://string
							case HL70125.TX://text
								labResult.ObservationValueText=fields[5];
								break;
							case HL70125.NM:
								//data may contain positive or negative sign.  Below, the sign is handled first, and then multiplied by PIn.Double(val)
								labResult.ObservationValueNumeric=  (fields[5].Contains("-")?-1f:1f)  *  PIn.Double(fields[5].Trim('+').Trim('-'));
								break;
							case HL70125.SN:
								labResult.ObservationValueComparator						=						fields[5].Split('^')[0];
								try { labResult.ObservationValueNumber1						=PIn.Double(fields[5].Split('^')[1]); }
								catch { }//optional, may be a null reference
								try { labResult.ObservationValueSeparatorOrSuffix	=						fields[5].Split('^')[2]; }
								catch { }//optional, may be a null reference
								try { labResult.ObservationValueNumber2						=PIn.Double(fields[5].Split('^')[3]); }
								catch { }//optional, may be a null reference
								break;
							case HL70125.TM:
								labResult.ObservationValueTime=PIn.Time(fields[5]);
								break;
						}
						//Units
						if(fields[6].Length!=0) {
							labResult.UnitsID											=fields[6].Split('^')[0];
							labResult.UnitsText										=fields[6].Split('^')[1];
							try { labResult.UnitsCodeSystemName			=fields[6].Split('^')[2]; }
							catch { }
							try { labResult.UnitsIDAlt							=fields[6].Split('^')[3]; }
							catch { }
							try { labResult.UnitsTextAlt						=fields[6].Split('^')[4]; }
							catch { }
							try { labResult.UnitsCodeSystemNameAlt	=fields[6].Split('^')[5]; }
							catch { }
							try { labResult.UnitsTextOriginal				=fields[6].Split('^')[6]; }
							catch { }
						}

						labResult.referenceRange=fields[7];
						labResult.AbnormalFlags=fields[8].Replace('~',',');//TODO: may need additional formatting/testing
						try { labResult.ObservationResultStatus	=(HL70085)Enum.Parse(typeof(HL70085),fields[11]); }
						catch { }
						labResult.ObservationDateTime=fields[14];
						labResult.AnalysisDateTime=fields[19];
						//performing organization Name (with additional info)
						labResult.PerformingOrganizationName=fields[23].Split('^')[0];
						labResult.PerformingOrganizationNameAssigningAuthorityNamespaceId			=fields[23].Split('^')[5].Split('&')[0];
						labResult.PerformingOrganizationNameAssigningAuthorityUniversalId			=fields[23].Split('^')[5].Split('&')[1];
						labResult.PerformingOrganizationNameAssigningAuthorityUniversalIdType	=fields[23].Split('^')[5].Split('&')[2];
						try { labResult.PerformingOrganizationIdentifierTypeCode	=(HL70203)Enum.Parse(typeof(HL70203),fields[23].Split('^')[7]); }
						catch { }
						labResult.PerformingOrganizationIdentifier=fields[23].Split('^')[9];
						//Performing Organization Address
						labResult.PerformingOrganizationAddressStreet									=fields[24].Split('^')[0].Split('&')[0];
						try { labResult.PerformingOrganizationAddressOtherDesignation		=fields[24].Split('^')[1]; }
						catch { }
						try { labResult.PerformingOrganizationAddressCity								=fields[24].Split('^')[2]; }
						catch { }
						try { labResult.PerformingOrganizationAddressStateOrProvince		=(USPSAlphaStateCode)Enum.Parse(typeof(USPSAlphaStateCode),fields[24].Split('^')[3]); }
						catch { }
						try { labResult.PerformingOrganizationAddressZipOrPostalCode		=fields[24].Split('^')[4]; }
						catch { }
						try { labResult.PerformingOrganizationAddressCountryCode				=fields[24].Split('^')[5]; }
						catch { }
						try { labResult.PerformingOrganizationAddressAddressType				=(HL70190)Enum.Parse(typeof(HL70190),fields[24].Split('^')[6]); }
						catch { }
						try { labResult.PerformingOrganizationAddressCountyOrParishCode	=fields[24].Split('^')[7]; }
						catch { }
						//Performing Organization Medical Director
						if(fields.Length<=25) {
							break;//next segment. this one is finished.
						}
						labResult.MedicalDirectorID										=fields[25].Split('^')[0];
						try { labResult.MedicalDirectorFName						=fields[25].Split('^')[1]; }
						catch { }
						try { labResult.MedicalDirectorLName						=fields[25].Split('^')[2]; }
						catch { }
						try { labResult.MedicalDirectorMiddleNames			=fields[25].Split('^')[3]; }
						catch { }
						try { labResult.MedicalDirectorSuffix						=fields[25].Split('^')[4]; }
						catch { }
						try { labResult.MedicalDirectorPrefix						=fields[25].Split('^')[5]; }
						catch { }
						try { labResult.MedicalDirectorAssigningAuthorityNamespaceID		=fields[25].Split('^')[8].Split('&')[0]; }
						catch { }
						try { labResult.MedicalDirectorAssigningAuthorityUniversalID		=fields[25].Split('^')[8].Split('&')[1]; }
						catch { }
						try { labResult.MedicalDirectorAssigningAuthorityIDType					=fields[25].Split('^')[8].Split('&')[2]; }
						catch { }
						try { labResult.MedicalDirectorNameTypeCode						=(HL70200)Enum.Parse(typeof(HL70200),fields[25].Split('^')[9]); }
						catch { }
						try { labResult.MedicalDirectorIdentifierTypeCode			=(HL70203)Enum.Parse(typeof(HL70203),fields[25].Split('^')[12]); }
						catch { }
						ehrLabCur.ListEhrLabResults.Add(labResult);
						break;
					//case "FTI": //Financial Transaction
					//	break;
					//case "CTI": //Clinical Trial Identification
					//	break;
					case "SPM":
						//if(retVal.ListEhrLabSpecimin==null) {
						//	retVal.ListEhrLabSpecimin=new List<EhrLabSpecimen>();
						//}
						EhrLabSpecimen ehrLabSpecimen=new EhrLabSpecimen();
						ehrLabSpecimen.SetIdSPM=PIn.Long(fields[1]);
						//Specimen Type
						ehrLabSpecimen.SpecimenTypeID											= fields[4].Split('^')[0];
						try { ehrLabSpecimen.SpecimenTypeText								= fields[4].Split('^')[1]; }
						catch { }
						try { ehrLabSpecimen.SpecimenTypeCodeSystemName			= fields[4].Split('^')[2]; }
						catch { }
						try { ehrLabSpecimen.SpecimenTypeIDAlt							= fields[4].Split('^')[3]; }
						catch { }
						try { ehrLabSpecimen.SpecimenTypeTextAlt						= fields[4].Split('^')[4]; }
						catch { }
						try { ehrLabSpecimen.SpecimenTypeCodeSystemNameAlt	= fields[4].Split('^')[5]; }
						catch { }
						try { ehrLabSpecimen.SpecimenTypeTextOriginal				= fields[4].Split('^')[6]; }
						catch { }
						//TODO:? check to see if either triplet contained a valid code.
						//Collection Date Time
						ehrLabSpecimen.CollectionDateTimeStart		=fields[17].Split('^')[0];
						try { ehrLabSpecimen.CollectionDateTimeEnd	=fields[17].Split('^')[1]; }
						catch { }
						if(fields.Length<19) {
							ehrLabCur.ListEhrLabSpecimens.Add(ehrLabSpecimen);
							break;//next segment. This one has no more fields
						}
						//if(ehrLabSpecimen.ListEhrLabSpecimenRejectReason==null) {
						//	ehrLabSpecimen.ListEhrLabSpecimenRejectReason=new List<EhrLabSpecimenRejectReason>();
						//}
						//Reject Reason
						for(int i=0;i<fields[21].Split('~').Length;i++) {
							if(fields[21].Length==0) {
								break;//nothing in this field
							}
							EhrLabSpecimenRejectReason ehrLabRR=new EhrLabSpecimenRejectReason();
							ehrLabRR.SpecimenRejectReasonID											=fields[21].Split('~')[i].Split('^')[0];
							try { ehrLabRR.SpecimenRejectReasonText								=fields[21].Split('~')[i].Split('^')[1]; }
							catch { }
							try { ehrLabRR.SpecimenRejectReasonCodeSystemName			=fields[21].Split('~')[i].Split('^')[2]; }
							catch { }
							try { ehrLabRR.SpecimenRejectReasonIDAlt							=fields[21].Split('~')[i].Split('^')[3]; }
							catch { }
							try { ehrLabRR.SpecimenRejectReasonTextAlt						=fields[21].Split('~')[i].Split('^')[4]; }
							catch { }
							try { ehrLabRR.SpecimenRejectReasonCodeSystemNameAlt	=fields[21].Split('~')[i].Split('^')[5]; }
							catch { }
							try { ehrLabRR.SpecimenRejectReasonTextOriginal				=fields[21].Split('~')[i].Split('^')[6]; }
							catch { }
							//TODO:? check to see if either triplet contained a valid code.
							ehrLabSpecimen.ListEhrLabSpecimenRejectReason.Add(ehrLabRR);
						}
						//Specimen Condition
						for(int i=0;i<fields[24].Split('~').Length;i++) {
							if(fields[24].Length==0) {
								break;//nothing in this field
							}
							EhrLabSpecimenCondition ehrLabSC=new EhrLabSpecimenCondition();
							ehrLabSC.SpecimenConditionID											=fields[24].Split('~')[i].Split('^')[0];
							try { ehrLabSC.SpecimenConditionText								=fields[24].Split('~')[i].Split('^')[1]; }
							catch { }
							try { ehrLabSC.SpecimenConditionCodeSystemName			=fields[24].Split('~')[i].Split('^')[2]; }
							catch { }
							try { ehrLabSC.SpecimenConditionIDAlt								=fields[24].Split('~')[i].Split('^')[3]; }
							catch { }
							try { ehrLabSC.SpecimenConditionTextAlt							=fields[24].Split('~')[i].Split('^')[4]; }
							catch { }
							try { ehrLabSC.SpecimenConditionCodeSystemNameAlt		=fields[24].Split('~')[i].Split('^')[5]; }
							catch { }
							try { ehrLabSC.SpecimenConditionTextOriginal				=fields[24].Split('~')[i].Split('^')[6]; }
							catch { }
							ehrLabSpecimen.ListEhrLabSpecimenCondition.Add(ehrLabSC);
						}
						ehrLabCur.ListEhrLabSpecimens.Add(ehrLabSpecimen);
						break;
					default:
						//to catch unsupported or malformed segments.
						break;
				}//end switch
			}//end foreach segment
			//TODO:Message has been processed into an EHR Lab... Now we can do other things if we want to...
			listRetVal.Add(ehrLabCur);//other labs may have already been added to retval in the code above.
			return listRetVal;
		}