/*
 * Copyright 2011 NEHTA
 *
 * Licensed under the NEHTA Open Source (Apache) License; you may not use this
 * file except in compliance with the License. A copy of the License is in the
 * 'license.txt' file, which should be provided with this work.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;

using Nehta.VendorLibrary.CDA.Common;
using Nehta.VendorLibrary.CDA.Generator.Enums;
using Nehta.VendorLibrary.CDA.SCSModel.Common;
using Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Interfaces;
using Nehta.VendorLibrary.Common;
using Nehta.VendorLibrary.CDA.Common.Enums;

namespace Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary
{
    /// <summary>
    /// This eDischargeSummary object is a composition of the context and content objects that define
    /// a CDA eDischargeSummary document
    /// 
    /// This object is also responsible for providing the factory methods used to instantiate any E-DischargeSummary
    /// objects that are required to build a valid E-DischargeSummary CDA document
    /// </summary>
    [DataContract]
    [KnownType(typeof(Content))]
    [KnownType(typeof(Context))]
    [KnownType(typeof(CDAContext))]
    [KnownType(typeof(BaseCDAModel))]
    public class EDischargeSummary : BaseCDAModel
    {
        #region Constants

        private const String HEALTH_IDENTIFIER_QUALIFIER = "1.2.36.1.2001.1003.0.";

        #endregion

        #region Properties
        /// <summary>
        /// An ICDAContextEDischargeSummary that contains the CDA context for this e-DischargeSummary record
        /// </summary>
        [DataMember]
        public ICDAContextEDischargeSummary CDAContext { get; set; }

        /// <summary>
        /// An IEDischargeSummaryContent that contains the content for this e-DischargeSummary record
        /// </summary>
        [DataMember]
        public IEDischargeSummaryContent SCSContent { get; set; }

        /// <summary>
        /// An IDispenseRecordContext that contains the context for this e-DischargeSummary record
        /// </summary>
        [DataMember]
        public IEDischargeSummaryContext SCSContext { get; set; }
        #endregion

        #region Constructors
        /// <summary>
        /// Instantiates an eDichargeSummary model; the status of this CDA document will be 
        /// set to the status passed into this constructor
        /// </summary>
        /// <param name="documentStatus">Document Status</param>
        public EDischargeSummary(DocumentStatus documentStatus)
        {
            DocumentStatus = documentStatus;
        }

        /// <summary>
        /// Instantiates an eDischargeSummary model; the status of this document will be 
        /// set to final
        /// </summary>
        public EDischargeSummary() : this(DocumentStatus.Final)
        {
        }
        #endregion

        #region Validation
        /// <summary>
        /// Validates this eDischargeSummary object and its child objects
        /// </summary>
        /// <param name="path">The path to this object as a string</param>
        /// <param name="messages">the validation messages to date, these may be added to within this method</param>
        public void Validate(string path, List<ValidationMessage> messages)
        {
            var vb = new ValidationBuilder(path, messages);

            if (vb.ArgumentRequiredCheck("CDAContext", CDAContext))
               CDAContext.Validate(vb.Path + "CDAContext", vb.Messages);
 
            if (vb.ArgumentRequiredCheck("SCSContext", SCSContext))
                SCSContext.Validate(vb.Path + "SCSContext", vb.Messages);

            if (vb.ArgumentRequiredCheck("SCSContent", SCSContent))
                SCSContent.Validate(vb.Path + "SCSContent", vb.Messages);

        }
        #endregion

        //#region Static Methods
        /// <summary>
        /// Creates an EDischargeSummary
        /// </summary>
        /// <returns>An EDischargeSummary Object</returns>
        public static EDischargeSummary CreateEDischargeSummary()
        {
            return new EDischargeSummary();
        }

        /// <summary>
        /// Creates a CDA Context
        /// </summary>
        /// <returns>(ICDAContextEDischargeSummary) Context</returns>
        public static ICDAContextEDischargeSummary CreateCDAContext()
        {
            return new CDAContext();
        }

        /// <summary>
        /// Creates a SCS Context
        /// </summary>
        /// <returns>(IEDischargeSummaryContext) Context</returns>
        public static IEDischargeSummaryContext CreateSCSContext()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Context();
        }

        /// <summary>
        /// Create a Facility
        /// </summary>
        /// <returns>(IParticipationFacility) Facility</returns>
        public static IParticipationFacility CreateFacility()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participation();
        }

        /// <summary>
        /// Creates a facility Participant 
        /// </summary>
        /// <returns>(IFacility) facility</returns>
        public static IFacility CreateParticipantForFacility()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participant();
        }

        /// <summary>
        /// Creates a Nominated Primary HealthCare Provider
        /// </summary>
        /// <returns>INominatedPrimaryHealthCareProvider</returns>
        public static INominatedPrimaryHealthCareProvider CreateParticipantForNominatedPrimaryHealthProvider()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participant();
        }
        /// <summary>
        /// Creates an imaging examination result
        /// </summary>
        /// <returns>(IImagingExaminationResultDischargeSummary) Imaging Examination Result Discharge Summary</returns>
        public static IImagingExaminationResultDischargeSummary CreateImagingExaminationResult()
        {
            return new ImagingExaminationResult();
        }

        /// <summary>
        /// Creates a participation constrained down to an IParticipationSubjectOfCare
        /// </summary>
        /// <returns>(IParticipationSubjectOfCare) Participation</returns>
        public static new IParticipationSubjectOfCare CreateSubjectOfCare()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participation();
        }

        /// <summary>
        /// Creates a participation constrained down to an ISubjectOfCare
        /// </summary>
        /// <returns>(ISubjectOfCare) Participation</returns>
        public static new ISubjectOfCare CreateParticipantForSubjectOfCare()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participant();
        }

        /// <summary>
        /// Creates a SCS Content
        /// </summary>
        /// <returns>(IEDischargeSummaryContent) Content</returns>
        public static IEDischargeSummaryContent CreateSCSContent()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Content();
        }

        /// <summary>
        /// Creates an Event
        /// </summary>
        /// <returns>An Event</returns>
        public static Event CreateEvent()
        {
            return new Event();
        }

        /// <summary>
        /// Creates an Encounter
        /// </summary>
        /// <returns>An Encounter</returns>
        public static Encounter CreateEncounter()
        {
            return new Encounter();
        }

        /// <summary>
        /// Creates an Health Professional Participation Object
        /// </summary>
        /// <returns>(IParticipationResponsibleHealthProfessional) Participation</returns>
        public static IParticipationResponsibleHealthProfessional CreateResponsibleHealthProfessional()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participation();
        }

         /// <summary>
        /// Creates an Health Person Or Organisation
        /// </summary>
        /// <returns>(IHealthPersonOrOrganisation) IHealthPersonOrOrganisation</returns>
        public static IHealthPersonOrOrganisation CreateHealthPersonOrOrganisation()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participant();
        }

        /// <summary>
        /// Creates an Other Participant Participation Object
        /// </summary>
        /// <returns>(IParticipationOtherParticipant) Participation</returns>
        public static IParticipationOtherParticipant CreateOtherParticipant()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participation();
        }

        /// <summary>
        /// Create Participant for a Responsible Health Professional
        /// </summary>
        /// <returns>(IResponsibleHealthProfessional)Participant</returns>
        public static IResponsibleHealthProfessional CreateParticipantForResponsibleHealthProfessional()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participant();
        }

        /// <summary>
        /// Create Participant for IParticipationHealthProfessional
        /// </summary>
        /// <returns>(IOtherParticipant) Participant</returns>
        public static IOtherParticipant CreateParticipantForOtherParticipant()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participant();
        }

         /// <summary>
        /// Create Participant For Recommendation Recipient
        /// </summary>
        /// <returns>(IHealthPersonOrOrganisation) Participant</returns>
        public static IHealthPersonOrOrganisation CreateParticipantForRecommendationRecipient()
        {
            return new Participant();
        }

        /// <summary>
        /// Creates a HealthEventIdentification
        /// </summary>
        /// <returns>A HealthEventIdentification Object</returns>
        public static HealthEventIdentification CreateHealthEventIdentification()
        {
            return new HealthEventIdentification();
        }

        /// <summary>
        /// Creates a result value
        /// </summary>
        /// <returns>A ResultValue Object</returns>
        public static ResultValue CreateResultValue()
        {
            return new ResultValue();
        }

        /// <summary>
        /// Creates a DischargeSummaryProblemDiagnosis
        /// </summary>
        /// <returns> (IDischargeSummaryProblemDiagnosis) ProblemDiagnosis</returns>
        public static IDischargeSummaryProblemDiagnosis CreateProblemDiagnosis()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.ProblemDiagnosis();
        }

        /// <summary>
        /// Creates a ProblemDiagnoses This Visit Object
        /// </summary>
        /// <returns>A ProblemDiagnosesThisVisit Object</returns>
        public static ProblemDiagnosesThisVisit CreateProblemDiagnosesThisVisit()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.ProblemDiagnosesThisVisit();
        }

        /// <summary>
        /// Creates an IStatement exclusion statement
        /// </summary>
        /// <returns>(IStatement) Statement</returns>
        public static Statement CreateExclusionStatement()
        {
            return new Statement();
        }

        /// <summary>
        /// Create a Clinical Synopsis for a discharge summary
        /// </summary>
        /// <returns>A ClinicalSynopsis Object</returns>
        public static ClinicalSynopsis CreateClinicalSynopsis()
        {
            return new ClinicalSynopsis();
        }

        /// <summary>
        /// Create a ClinicalIntervention for a discharge summary
        /// </summary>
        /// <returns>A ClinicalIntervention Object</returns>
        public static ClinicalIntervention CreateClinicalIntervention()
        {
            return new ClinicalIntervention();
        }

        /// <summary>
        /// Creates a Diagnostic Investigation
        /// </summary>
        /// <returns>(IDiagnosticInvestigationsDischargeSummary) DiagnosticInvestigations</returns>
        public static IDiagnosticInvestigationsDischargeSummary CreateDiagnosticInvestigations()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.DiagnosticInvestigations();
        }

        /// <summary>
        /// Create an ImagingTest
        /// </summary>
        /// <returns>An ImagingTest Object</returns>
        public static ImagingTest CreateImagingTest()
        {
            return new ImagingTest();
        }

        /// <summary>
        /// Create an ImageDetails 
        /// </summary>
        /// <returns>(IImageDetailsDischargeSummary) ImageDetails</returns>
        public static IImageDetails CreateImageDetails()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.ImageDetails();
        }

        /// <summary>
        /// Create a View
        /// </summary>
        /// <returns>A View</returns>
        public static View CreateView()
        {
            return new View();
        }

        /// <summary>
        /// Create a Protocol
        /// </summary>
        /// <returns>A Protocol</returns>
        public static Protocol CreateProtocol()
        {
            return new Protocol();
        }

        /// <summary>
        /// Creates Medications for Discharge Summary
        /// </summary>
        /// <returns>(IMedicationsDischargeSummary) Medications</returns>
        public static IMedicationsDischargeSummary CreateMedications()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Medications();
        }

        /// <summary>
        /// Creates Current Medications for Discharge Summary
        /// </summary>
        /// <returns>(CurrentMedications) CurrentMedications</returns>
        public static CurrentMedications CreateCurrentMedications()
        {
            return new CurrentMedications();
        }

        /// <summary>
        /// Create TherapeuticGood for Discharge Summary
        /// </summary>
        /// <returns>(ITherapeuticGood) TherapeuticGood</returns>
        public static ITherapeuticGood CreateTherapeuticGood()
        {
            return new TherapeuticGood();
        }

        /// <summary>
        /// Create CreateMedicationHistory for Discharge Summary
        /// </summary>
        /// <returns>(IMedicalHistory) MedicationHistory</returns>
        public static IMedicationHistory CreateMedicationHistory()
        {
            return new MedicationHistory();
        }

        /// <summary>
        /// Creates an imaging result
        /// </summary>
        /// <returns>(IImagingResult) Result</returns>
        public static IImagingResult CreateImagingResult()
        {
            return new Result();
        }

        /// <summary>
        /// Creates a test result group
        /// </summary>
        /// <returns>(ITestResultGroup) ResultGroup</returns>
        public static ITestResultGroup CreateTestResultGroup()
        {
            return new ResultGroup();
        }

        /// <summary>
        /// Creates a test result
        /// </summary>
        /// <returns>(ITestResult) Result</returns>
        public static ITestResult CreateTestResult()
        {
            return new Result();
        }

        /// <summary>
        /// Creates an Image Result Group
        /// </summary>
        /// <returns>(IImagingResultGroup) ResultGroup</returns>
        public static IImagingResultGroup CreateImagingResultGroup()
        {
            return new ResultGroup();
        }

        /// <summary>
        /// Creates a result value reference range detail
        /// </summary>
        /// <returns>A ResultValueReferenceRangeDetail Object</returns>
        public static ResultValueReferenceRangeDetail CreateResultValueReferenceRangeDetail()
        {
            return new ResultValueReferenceRangeDetail();
        }

        /// <summary>
        /// Creates an examination result name
        /// </summary>
        /// <param name="code">examination result name code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining an examination result name</returns>
        public static ICodableText CreateExaminationResultName(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates an anatomical location
        /// </summary>
        /// <returns>An AnatomicalLocation Object</returns>
        public static AnatomicalLocation CreateAnatomicalLocation()
        {
            return new AnatomicalLocation();
        }

        /// <summary>
        /// Creates a sampling precondition
        /// </summary>
        /// <param name="code">sampling precondition code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a sampling precondition</returns>
        public static ICodableText CreateSamplingPreconditions(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates an anatomic location side
        /// </summary>
        /// <param name="code">anatomic location side code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining an anatomic location side</returns>
        /// <returns>A CodableText Object</returns>
        public static ICodableText CreateAnatomicLocationSide(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a result value reference range meaning
        /// </summary>
        /// <param name="code">result value reference range meaning code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a result value reference range meaning</returns>
        public static ICodableText CreateResultValueReferenceRangeMeaning(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a specimen tissue type
        /// </summary>
        /// <param name="code">specimen tissue type code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a specimen tissue type</returns>
        public static ICodableText CreateSpecimenTissueType(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a modality
        /// </summary>
        /// <param name="code">modality code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a modality</returns>
        public static ICodableText CreateModality(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a collection procedure
        /// </summary>
        /// <param name="code">collection procedure code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a collection procedure</returns>
        public static ICodableText CreateCollectionProcedure(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates an anatomic location name
        /// </summary>
        /// <param name="code">anatomic location name code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="translations">Any translations that are associated with this anatomic location name</param>
        /// <returns>CodableText defining an anatomic location name</returns>
        public static ICodableText CreateAnatomicLocationName(String code, CodingSystem? codeSystem, String displayName, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, null, translations);
        }

        /// <summary>
        /// Creates a test request
        /// </summary>
        /// <returns>(ITestRequest) Request</returns>
        public static ITestRequest CreateTestRequest()
        {
            return new Request();
        }

        /// <summary>
        /// Create CreateMedicationHistoryCeased for Discharge Summary  
        /// </summary>
        /// <returns>(IMedicationHistoryCeased) MedicationHistory</returns>
        public static IMedicationHistoryCeased CreateMedicationHistoryCeased()
        {
            return new MedicationHistory();
        }
        
        /// <summary>
        /// Creates CeasedMedications for Discharge Summary
        /// </summary>
        /// <returns>A CeasedMedications Object</returns>
        public static CeasedMedications CreateCeasedMedications()
        {
            return new CeasedMedications();
        }
        
        /// <summary>
        /// Create TherapeuticGood for Discharge Summary TherapeuticGoodCeased
        /// </summary>
        /// <returns>(ITherapeuticGoodCeased) TherapeuticGood</returns>
        public static ITherapeuticGoodCeased CreateTherapeuticGoodCeased()
        {
            return new TherapeuticGood();
        }

        /// <summary>
        /// Create HealthProfile for Discharge Summary 
        /// </summary>
        /// <returns>A HealthProfile Object</returns>
        public static HealthProfile CreateHealthProfile()
        {
            return new HealthProfile();
        }

        /// <summary>
        /// Create Participation Nominated Primary Health Care Provider for Discharge Summary 
        /// </summary>
        /// <returns>(IParticipationNominatedPrimaryHealthCareProvider) Participation</returns>
        public static IParticipationNominatedPrimaryHealthCareProvider CreateNominatedPrimaryHealthCareProvider()
        {
            return new Participation();
        }

        /// <summary>
        /// Create AdverseReaction for Discharge Summary 
        /// </summary>
        /// <returns> (IAdverseReactionDischargeSummary) AdverseReaction </returns>
        public static IAdverseReactionDischargeSummary CreateReactions()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.AdverseReaction();
        }

        /// <summary>
        /// Create AdverseReactions for Discharge Summary 
        /// </summary>
        /// <returns>An AdverseReactions Object</returns>
        public static AdverseReactions CreateAdverseReactions()
        {
            return new AdverseReactions();
        }

        /// <summary>
        /// Create Alert for Discharge Summary 
        /// </summary>
        /// <returns>An Alert Object</returns>
        public static Alerts CreateAlerts()
        {
            return new Alerts();
        }


        /// <summary>
        /// Create Alert for Discharge Summary 
        /// </summary>
        /// <returns>An Alert Object</returns>
        public static Alert CreateAlert()
        {
          return new Alert();
        }

        /// <summary>
        /// Create Plan for Discharge Summary 
        /// </summary>
        /// <returns>A Plan Object</returns>
        public static Plan CreatePlan()
        {
            return new Plan();
        }

        /// <summary>
        /// Create Arranged Services for Discharge Summary 
        /// </summary>
        /// <returns>A ArrangedServices Object</returns>
        public static ArrangedServices CreateArrangedServices()
        {
            return new ArrangedServices();
        }
 
        /// <summary>
        /// Create RecommendationsInformationProvided for Discharge Summary 
        /// </summary>
        /// <returns>(RecommendationsInformationProvided) Recommendations Information Provided</returns>
        public static RecommendationsInformationProvided CreateRecommendationsInformationProvided()
        {
            return new RecommendationsInformationProvided();
        }

        /// <summary>
        /// Create Recommendations Provided for Discharge Summary 
        /// </summary>
        /// <returns>A RecommendationsProvided Object</returns>
        public static RecommendationsProvided CreateRecommendationsProvided()
        {
            return new RecommendationsProvided();
        }

        /// <summary>
        /// Creates an Recommendation Recipient Object
        /// </summary>
        /// <returns>(IParticipationHealthProfessional) Participation</returns>
        public static IParticipationHealthProfessional CreateRecommendationRecipient()
        {
            return new Nehta.VendorLibrary.CDA.SCSModel.DischargeSummary.Participation();
        }

        /// <summary>
        /// Creates an Information Provided Object
        /// </summary>
        /// <returns>An InformationProvided Object</returns>
        public static InformationProvided CreateInformationProvided()
        {
            return new InformationProvided();
        }

        #region CodableText

        /// <summary>
        /// Creates a medicine CodableText
        /// </summary>
        /// <param name="code">Medicine code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a medicine</returns>
        public static ICodableText CreateMedicine(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a Arranged Service Description CodableText
        /// </summary>
        /// <param name="code">type of participation</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a participation type</returns>
        public static ICodableText CreateArrangedServiceDescription(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a Service Booking Status CodableText
        /// </summary>
        /// <param name="code">type of participation</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a participation type</returns>
        public static ICodableText CreateServiceBookingStatus(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a NoKnownAdverseReactionTo CodableText
        /// </summary>
        /// <param name="code">type of participation</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a participation type</returns>
        public static ICodableText CreateNoKnownAdverseReactionTo(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a CreateNoKnownAllergicReactionTo CodableText
        /// </summary>
        /// <param name="code">type of participation</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a participation type</returns>
        public static ICodableText CreateNoKnownAllergicReactionTo(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a CreateReactionDescriptions CodableText
        /// </summary>
        /// <param name="code">type of participation</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a participation type</returns>
        public static ICodableText CreateReactionDescriptions(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a CreateNoKnownHypersensitivityReactionTo CodableText
        /// </summary>
        /// <param name="code">type of participation</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a participation type</returns>
        public static ICodableText CreateNoKnownHypersensitivityReactionTo(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a CreateNoKnownIntoleranceTo CodableText
        /// </summary>
        /// <param name="code">type of participation</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a participation type</returns>
        public static ICodableText CreateNoKnownIntoleranceTo(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a CreateAgentDescription CodableText
        /// </summary>
        /// <param name="code">type of participation</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a participation type</returns>
        public static ICodableText CreateAgentDescription(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a CreateAdverseReactionType CodableText
        /// </summary>
        /// <param name="code">type of participation</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a participation type</returns>
        public static ICodableText CreateAdverseReactionType(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a CreateAdverseReactionType NullFlavour
        /// </summary>
        /// <param name="nullFlavour">type of participation</param>
        /// <returns>CodableText defining a participation type</returns>
        public static ICodableText CreateAdverseReactionType(NullFlavour nullFlavour)
        {
          return CreateCodableText(nullFlavour);
        }
		
        /// <summary>
        /// Creates a separation mode CodableText.
        /// </summary>
        /// <param name="separationMode">Separation mode.</param>
        /// <returns>Separation mode ICodableText</returns>
        public static ICodableText CreateSeparationMode(ModeOfSeparation separationMode)
        {
            return CreateCodableText(
                separationMode.GetAttributeValue<NameAttribute, string>(x => x.Code),
                CodingSystem.AIHW,
                separationMode.GetAttributeValue<NameAttribute, string>(x => x.Name),
                null,
                null);
        }

        /// <summary>
        /// Create a Specialty CodableText
        /// </summary>
        /// <param name="code">Specialty mode code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateSpecialty(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create a Specialty CodableText nullFlavor
        /// </summary>
        /// <param name="nullFlavor">Specialty mode nullflavor</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateSpecialty(NullFlavour nullFlavor)
        {
          return CreateCodableText(nullFlavor);
        }

        /// <summary>
        /// Create a CareSetting CodableText
        /// </summary>
        /// <param name="code">Care Setting mode code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateCareSetting(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }
		
        /// <summary>
        /// Create a ProblemDiagnosisDescription CodableText
        /// </summary>
        /// <param name="code">Problem Diagnosis Description code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateProblemDiagnosisDescription(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create a ProblemDiagnosisType CodableText
        /// </summary>
        /// <param name="code">Problem Diagnosis Type code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param> 
        /// <returns>CodableText </returns>
        public static ICodableText CreateProblemDiagnosisType(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }
		
		/// <summary>
        /// Create a Clinical Intervention Description CodableText
        /// </summary>
        /// <param name="code">Clinical Intervention Type code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateClinicalInterventionDescription(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }
		
	    /// <summary>
        /// Create a Alert Type CodableText
        /// </summary>
        /// <param name="code">Alert Type code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateAlertType(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create an Alert Description CodableText
        /// </summary>
        /// <param name="code">Alert Description code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateAlertDescription(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a pathological diagnosis CodableText
        /// </summary>
        /// <param name="code">pathological diagnosis code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a pathological diagnosis</returns>
        public static ICodableText CreatePathologicalDiagnois(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create a Clinical Category CodableText
        /// </summary>
        /// <param name="code">Category code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateCategory(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create a CreateTestName CodableText
        /// </summary>
        /// <param name="code">CreateTestName code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateTestName(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create a CreatePerViewFindings CodableText
        /// </summary>
        /// <param name="code">CreatePerViewFindings code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreatePerViewFindings(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create a ViewName CodableText
        /// </summary>
        /// <param name="code">ViewName code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateViewName(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create a ImagingQuality CodableText
        /// </summary>
        /// <param name="code">ImagingQuality code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateImagingQuality(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create a OverallFinding CodableText
        /// </summary>
        /// <param name="code">OverallFinding code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText </returns>
        public static ICodableText CreateOverallFinding(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }
		
        /// <summary>
        /// Create a CreateTherapeuticGoodIdentification CodableText
        /// </summary>
        /// <param name="code">CreateTherapeuticGoodIdentification code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CreateTherapeuticGoodIdentification </returns>
        public static ICodableText CreateTherapeuticGoodIdentification(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create a ItemStatus CodableText
        /// </summary>
        /// <param name="code">ItemStatus code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CreateItemStatus </returns>
        public static ICodableText CreateItemStatus(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Create a ChangesMade CodableText
        /// </summary>
        /// <param name="code">ChangesMade code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CreateChangesMade </returns>
        public static ICodableText CreateChangesMade(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a result name CodableText
        /// </summary>
        /// <param name="code">result name code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this procedure</param>
        /// <returns>CodableText defining a result name</returns>
        public static ICodableText CreateResultName(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        /// <summary>
        /// Creates a test request name.
        /// </summary>
        /// <param name="code">Test request code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <returns>CodableText defining a test request name</returns>
        public static ICodableText CreateTestRequestName(String code, CodingSystem? codeSystem, String displayName)
        {
            return CreateCodableText(code, codeSystem, displayName, null, null);
        }

        /// <summary>
        /// Creates a Image View Name
        /// </summary>
        /// <param name="code">Image View Name name code</param>
        /// <param name="codeSystem">The code system associated with the code</param>
        /// <param name="displayName">The display name associated with the code</param>
        /// <param name="originalText">Original text, usually applicable in the absence of a code and display name</param>
        /// <param name="translations">Any translations that are associated with this result group name</param>
        /// <returns>CodableText defining a result group name</returns>
        public static ICodableText CreateImageViewName(String code, CodingSystem? codeSystem, String displayName, String originalText, List<ICodableTranslation> translations)
        {
            return CreateCodableText(code, codeSystem, displayName, originalText, translations);
        }

        #endregion

        #region Serialisation Methods
        /// <summary>
        /// This method serializes this model into an XML document and returns this document
        /// </summary>
        /// <returns>XmlDocument</returns>
        public XmlDocument SerializeModel()
        {
            XmlDocument xmlDocument = null;
            var dataContractSerializer = new DataContractSerializer(typeof(EDischargeSummary));

            using (var memoryStream = new MemoryStream())
            {
                xmlDocument = new XmlDocument();

                dataContractSerializer.WriteObject(memoryStream, this);

                memoryStream.Seek(0, SeekOrigin.Begin);

                xmlDocument.Load(memoryStream);
            }

            return xmlDocument;
        }

        /// <summary>
        /// This method deserializes the xml document into an eDischargeSummary object
        /// </summary>
        /// <returns>XmlDocument</returns>
        public static EDischargeSummary DeserializeXmlDocument(XmlDocument xmlDocument)
        {
            EDischargeSummary eDischargeSummary = null;

            var dataContractSerializer = new DataContractSerializer(typeof(EDischargeSummary));

            using (var memoryStream = new MemoryStream())
            {
                xmlDocument.Save(memoryStream);

                memoryStream.Position = 0;

                eDischargeSummary = (EDischargeSummary)dataContractSerializer.ReadObject(memoryStream);
            }

            return eDischargeSummary;
        }
        #endregion
    }
}
