/// <summary>
        /// Update the specified PID
        /// </summary>
        public void UpdatePID(Core.ComponentModel.RegistrationEvent registrationEvent, NHapi.Model.V25.Segment.PID pid, bool summaryOnly)
        {
            var subject = registrationEvent.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.SubjectOf) as Person;
            var aut     = registrationEvent.FindComponent(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.AuthorOf) as RepositoryDevice;

            // Update time
            pid.LastUpdateDateTime.Time.Value = ((TS)subject.Timestamp).Value;
            if (aut != null)
            {
                pid.LastUpdateFacility.NamespaceID.Value = aut.Jurisdiction;
            }

            // Alternate identifiers
            foreach (var altId in subject.AlternateIdentifiers)
            {
                var id = pid.GetPatientIdentifierList(pid.PatientIdentifierListRepetitionsUsed);
                UpdateCX(altId, id);
            }

            // Other identifiers
            foreach (var othId in subject.OtherIdentifiers)
            {
                var id = pid.GetPatientIdentifierList(pid.PatientIdentifierListRepetitionsUsed);
                UpdateCX(othId.Value, id);

                // Correct v3 codes
                if (othId.Key.CodeSystem == "1.3.6.1.4.1.33349.3.98.12")
                {
                    id.IdentifierTypeCode.Value = othId.Key.Code;
                }
                else if (othId.Key.CodeSystem == "2.16.840.1.113883.2.20.3.85")
                {
                    switch (othId.Key.Code)
                    {
                    case "SIN":
                        id.IdentifierTypeCode.Value = "SS";
                        break;

                    case "DL":
                        id.IdentifierTypeCode.Value = othId.Key.Code;
                        break;

                    default:
                        id.IdentifierTypeCode.Value = null;
                        break;
                    }
                }
                else
                {
                    id.IdentifierTypeCode.Value = null;
                }
            }

            // IHE: This first repetition should be null
            if (summaryOnly)
            {
                pid.GetPatientName(0);
                pid.GetPatientName(1).NameTypeCode.Value = "S";
                return;
            }

            // Populate Names
            if (subject.Names != null)
            {
                foreach (var name in subject.Names)
                {
                    var xpn = pid.GetPatientName(pid.PatientNameRepetitionsUsed);
                    UpdateXPN(name, xpn);
                }
            }

            // Birth time
            if (subject.BirthTime != null)
            {
                MARC.Everest.DataTypes.TS ts = new Everest.DataTypes.TS(subject.BirthTime.Value, ReverseLookup(ComponentUtility.TS_PREC_MAP, subject.BirthTime.Precision));
                pid.DateTimeOfBirth.Time.Value = MARC.Everest.Connectors.Util.ToWireFormat(ts);
            }

            // Admin Sex
            if (subject.GenderCode != null)
            {
                pid.AdministrativeSex.Value = subject.GenderCode;
            }

            // Address
            if (subject.Addresses != null)
            {
                foreach (var addr in subject.Addresses)
                {
                    var ad = pid.GetPatientAddress(pid.PatientAddressRepetitionsUsed);
                    UpdateAD(addr, ad);
                }
            }

            // Death
            if (subject.DeceasedTime != null)
            {
                pid.PatientDeathIndicator.Value = "Y";
                MARC.Everest.DataTypes.TS ts = new Everest.DataTypes.TS(subject.DeceasedTime.Value, ReverseLookup(ComponentUtility.TS_PREC_MAP, subject.DeceasedTime.Precision));
                pid.PatientDeathDateAndTime.Time.Value = MARC.Everest.Connectors.Util.ToWireFormat(ts);
            }

            // MB Order
            if (subject.BirthOrder.HasValue)
            {
                pid.MultipleBirthIndicator.Value = "Y";
                if (subject.BirthOrder.Value > 0)
                {
                    pid.BirthOrder.Value = subject.BirthOrder.ToString();
                }
            }

            // Citizenship
            if (subject.Citizenship != null)
            {
                foreach (var cit in subject.Citizenship)
                {
                    if (cit.Status == SVC.Core.ComponentModel.Components.StatusType.Active)
                    {
                        var c = pid.GetCitizenship(pid.CitizenshipRepetitionsUsed);
                        UpdateCE(new CodeValue(cit.CountryCode, this.m_config.OidRegistrar.GetOid("ISO3166-1").Oid), c);
                    }
                }
            }

            if (subject.MaritalStatus != null)
            {
                UpdateCE(subject.MaritalStatus, pid.MaritalStatus);
            }
            // Language
            if (subject.Language != null)
            {
                foreach (var lang in subject.Language)
                {
                    if (lang.Type == LanguageType.Preferred)
                    {
                        UpdateCE(new CodeValue(lang.Language, this.m_config.OidRegistrar.GetOid("ISO639-1").Oid), pid.PrimaryLanguage);
                        break;
                    }
                }
            }

            // Mothers name
            var relations = subject.FindAllComponents(SVC.Core.ComponentModel.HealthServiceRecordSiteRoleType.RepresentitiveOf);

            foreach (var r in relations)
            {
                if (r is PersonalRelationship)
                {
                    var psn = r as PersonalRelationship;
                    if (psn.RelationshipKind != "MTH")
                    {
                        continue;
                    }

                    if (psn.AlternateIdentifiers != null)
                    {
                        foreach (var altid in psn.AlternateIdentifiers)
                        {
                            var id = pid.GetMotherSIdentifier(pid.MotherSIdentifierRepetitionsUsed);
                            UpdateCX(altid, id);
                        }
                    }
                    if (psn.LegalName != null)
                    {
                        UpdateXPN(psn.LegalName, pid.GetMotherSMaidenName(0));
                    }
                }
            }

            // Telecom addresses
            foreach (var tel in subject.TelecomAddresses)
            {
                if (tel.Use == "HP" && tel.Value.StartsWith("tel"))
                {
                    MessageUtil.XTNFromTel(new TEL()
                    {
                        Value        = tel.Value,
                        Use          = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationAddressUse> > >(tel.Use),
                        Capabilities = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationCabability> > >(tel.Capability)
                    }, pid.GetPhoneNumberHome(pid.PhoneNumberHomeRepetitionsUsed));
                }
                else if (tel.Use == "HP")
                {
                    pid.GetPhoneNumberHome(pid.PhoneNumberHomeRepetitionsUsed).EmailAddress.Value = tel.Value;
                }
                else if (tel.Use == "WP" && tel.Value.StartsWith("tel"))
                {
                    MessageUtil.XTNFromTel(new TEL()
                    {
                        Value        = tel.Value,
                        Use          = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationAddressUse> > >(tel.Use),
                        Capabilities = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationCabability> > >(tel.Capability)
                    }, pid.GetPhoneNumberBusiness(pid.PhoneNumberBusinessRepetitionsUsed));
                }
                else if (tel.Use == "WP")
                {
                    pid.GetPhoneNumberBusiness(pid.PhoneNumberBusinessRepetitionsUsed).EmailAddress.Value = tel.Value;
                }
            }

            // Race
            if (subject.Race != null)
            {
                foreach (var rc in subject.Race)
                {
                    this.UpdateCE(rc, pid.GetRace(pid.RaceRepetitionsUsed));
                }
            }

            // Ethnic code
            if (subject.EthnicGroup != null)
            {
                foreach (var e in subject.EthnicGroup)
                {
                    this.UpdateCE(e, pid.GetEthnicGroup(pid.EthnicGroupRepetitionsUsed));
                }
            }


            // Place of birth
            if (subject.BirthPlace != null)
            {
                pid.BirthPlace.Value = subject.BirthPlace.Name;
            }
        }
        /// <summary>
        /// Update the NK1 segment
        /// </summary>
        private void UpdateNK1(PersonalRelationship subject, NK1 nk1)
        {
            if (subject.AlternateIdentifiers != null)
            {
                foreach (var altId in subject.AlternateIdentifiers)
                {
                    UpdateCX(altId, nk1.GetNextOfKinAssociatedPartySIdentifiers(nk1.NextOfKinAssociatedPartySIdentifiersRepetitionsUsed));
                }
            }

            // Birth time
            if (subject.BirthTime != null)
            {
                MARC.Everest.DataTypes.TS ts = new Everest.DataTypes.TS(subject.BirthTime.Value, ReverseLookup(ComponentUtility.TS_PREC_MAP, subject.BirthTime.Precision));
                nk1.DateTimeOfBirth.Time.Value = MARC.Everest.Connectors.Util.ToWireFormat(ts);
            }

            if (subject.GenderCode != null)
            {
                nk1.AdministrativeSex.Value = subject.GenderCode;
            }

            if (subject.LegalName != null)
            {
                UpdateXPN(subject.LegalName, nk1.GetName(0));
            }

            if (subject.PerminantAddress != null)
            {
                UpdateAD(subject.PerminantAddress, nk1.GetAddress(0));
            }

            if (subject.RelationshipKind != null)
            {
                nk1.Relationship.Identifier.Value = subject.RelationshipKind;
            }

            if (subject.TelecomAddresses != null)
            {
                foreach (var tel in subject.TelecomAddresses)
                {
                    if (tel.Use == "HP" && tel.Value.StartsWith("tel"))
                    {
                        MessageUtil.XTNFromTel(new TEL()
                        {
                            Value        = tel.Value,
                            Use          = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationAddressUse> > >(tel.Use),
                            Capabilities = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationCabability> > >(tel.Capability)
                        }, nk1.GetContactPersonSTelephoneNumber(nk1.ContactPersonSTelephoneNumberRepetitionsUsed));
                    }
                    else if (tel.Use == "HP")
                    {
                        nk1.GetPhoneNumber(nk1.ContactPersonSTelephoneNumberRepetitionsUsed).EmailAddress.Value = tel.Value;
                    }
                    else if (tel.Use == "WP" && tel.Value.StartsWith("tel"))
                    {
                        MessageUtil.XTNFromTel(new TEL()
                        {
                            Value        = tel.Value,
                            Use          = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationAddressUse> > >(tel.Use),
                            Capabilities = MARC.Everest.Connectors.Util.Convert <SET <CS <TelecommunicationCabability> > >(tel.Capability)
                        }, nk1.GetContactPersonSTelephoneNumber(nk1.ContactPersonSTelephoneNumberRepetitionsUsed));
                    }
                    else if (tel.Use == "WP")
                    {
                        nk1.GetPhoneNumber(nk1.ContactPersonSTelephoneNumberRepetitionsUsed).EmailAddress.Value = tel.Value;
                    }
                }
            }
        }