/// <summary>
        /// Mark merge conflicts in the database
        /// </summary>
        public void MarkConflicts(SVC.Core.DataTypes.VersionedDomainIdentifier recordId, IEnumerable <SVC.Core.DataTypes.VersionedDomainIdentifier> matches)
        {
            if (recordId.Domain != ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid)
            {
                throw new ArgumentException(String.Format("Must be drawn from the '{0}' domain", ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid), "recordId");
            }


            // Construct connection
            IDbConnection  conn = DatabasePersistenceService.ConnectionManager.GetConnection();
            IDbTransaction tx   = null;

            try
            {
                tx = conn.BeginTransaction();

                // Save matches
                foreach (var id in matches)
                {
                    using (IDbCommand cmd = DbUtil.CreateCommandStoredProc(conn, tx))
                    {
                        cmd.CommandText = "crt_mrg_cand";
                        cmd.Parameters.Add(DbUtil.CreateParameterIn(cmd, "hsr_id_in", DbType.Decimal, Decimal.Parse(recordId.Identifier)));
                        cmd.Parameters.Add(DbUtil.CreateParameterIn(cmd, "cand_hsr_id_in", DbType.Decimal, Decimal.Parse(id.Identifier)));
                        cmd.ExecuteNonQuery();
                    }
                }
                tx.Commit();
            }
            catch (Exception e)
            {
                if (tx != null)
                {
                    tx.Rollback();
                }
            }
            finally
            {
                DatabasePersistenceService.ConnectionManager.ReleaseConnection(conn);
            }
        }
        /// <summary>
        /// Merge two items together
        /// </summary>
        public void Resolve(IEnumerable <SVC.Core.DataTypes.VersionedDomainIdentifier> victimIds, SVC.Core.DataTypes.VersionedDomainIdentifier survivorId, SVC.Core.Services.DataPersistenceMode mode)
        {
            // First, we load the survivor
            if (survivorId.Domain != ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid)
            {
                throw new ArgumentException(String.Format("Must be drawn from the '{0}' domain", ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid), "survivorId");
            }

            // Load the survivor
            var persistenceService        = this.Context.GetService(typeof(IDataPersistenceService)) as IDataPersistenceService;
            var survivorRegistrationEvent = persistenceService.GetContainer(survivorId, true) as RegistrationEvent;

            if (survivorRegistrationEvent == null)
            {
                throw new InvalidOperationException("Could not load target registration event");
            }
            var survivorPerson = survivorRegistrationEvent.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;

            if (survivorPerson == null)
            {
                throw new InvalidOperationException("Target registration event has no SubjectOf relationship of type Person");
            }

            // Create the merge registration event
            RegistrationEvent mergeRegistrationEvent = new RegistrationEvent()
            {
                Mode            = RegistrationEventType.Replace,
                EventClassifier = RegistrationEventType.Register,
                LanguageCode    = survivorRegistrationEvent.LanguageCode
            };

            mergeRegistrationEvent.EventType = new CodeValue("ADMIN_MRG");
            mergeRegistrationEvent.Add(new ChangeSummary()
            {
                ChangeType    = new CodeValue("ADMIN_MRG"),
                EffectiveTime = new TimestampSet()
                {
                    Parts = new List <TimestampPart>()
                    {
                        new TimestampPart(TimestampPart.TimestampPartType.Standlone, DateTime.Now, "F")
                    }
                },
                Timestamp    = DateTime.Now,
                LanguageCode = survivorRegistrationEvent.LanguageCode
            }, "CHG", HealthServiceRecordSiteRoleType.ReasonFor | HealthServiceRecordSiteRoleType.OlderVersionOf, null);
            survivorPerson.Site = null;

            mergeRegistrationEvent.Add(survivorPerson, "SUBJ", HealthServiceRecordSiteRoleType.SubjectOf, null);

            // Next, we do a replaces relationship for each of the victims (loading them as well since the ID is of the patient not reg event)
            foreach (var id in victimIds)
            {
                var replacementReg = persistenceService.GetContainer(id, true) as RegistrationEvent;
                if (replacementReg == null)
                {
                    throw new InvalidOperationException("Could not load victim registration event");
                }
                var replacementPerson = replacementReg.FindComponent(HealthServiceRecordSiteRoleType.SubjectOf) as Person;
                if (replacementPerson == null)
                {
                    throw new InvalidOperationException("Victim registration event has no SubjectOf relationship of type Person");
                }

                // Now, create replaces
                survivorPerson.Add(new PersonRegistrationRef()
                {
                    AlternateIdentifiers = new List <DomainIdentifier>()
                    {
                        new DomainIdentifier()
                        {
                            Domain     = ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.CLIENT_CRID).Oid,
                            Identifier = replacementPerson.Id.ToString()
                        }
                    }
                }, Guid.NewGuid().ToString(), HealthServiceRecordSiteRoleType.ReplacementOf, null);
            }

            // Now persist the replacement
            IDbConnection  conn = DatabasePersistenceService.ConnectionManager.GetConnection();
            IDbTransaction tx   = null;

            try
            {
                // Update container
                var vid = persistenceService.UpdateContainer(mergeRegistrationEvent, DataPersistenceMode.Production);

                tx = conn.BeginTransaction();

                foreach (var id in victimIds)
                {
                    using (IDbCommand cmd = DbUtil.CreateCommandStoredProc(conn, tx))
                    {
                        cmd.CommandText = "mrg_cand";
                        cmd.Parameters.Add(DbUtil.CreateParameterIn(cmd, "from_id_in", DbType.Decimal, Decimal.Parse(id.Identifier)));
                        cmd.Parameters.Add(DbUtil.CreateParameterIn(cmd, "to_id_in", DbType.Decimal, Decimal.Parse(survivorId.Identifier)));
                        cmd.ExecuteNonQuery();
                    }
                    // Obsolete the victim identifier merges
                    using (IDbCommand cmd = DbUtil.CreateCommandStoredProc(conn, tx))
                    {
                        cmd.CommandText = "obslt_mrg";
                        cmd.Parameters.Add(DbUtil.CreateParameterIn(cmd, "from_id_in", DbType.Decimal, Decimal.Parse(id.Identifier)));
                        cmd.ExecuteNonQuery();
                    }
                }
                tx.Commit();
            }
            catch (Exception e)
            {
                if (tx != null)
                {
                    tx.Rollback();
                }
                throw;
            }
            finally
            {
                DatabasePersistenceService.ConnectionManager.ReleaseConnection(conn);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="recordId"></param>
        /// <returns></returns>
        public IEnumerable <SVC.Core.DataTypes.VersionedDomainIdentifier> GetConflicts(SVC.Core.DataTypes.VersionedDomainIdentifier recordId)
        {
            if (recordId.Domain != ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid)
            {
                throw new ArgumentException(String.Format("Must be drawn from the '{0}' domain", ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid), "recordId");
            }

            // Construct connection
            IDbConnection conn = DatabasePersistenceService.ConnectionManager.GetConnection();

            try
            {
                List <VersionedDomainIdentifier> retVal = new List <VersionedDomainIdentifier>();
                using (IDbCommand cmd = DbUtil.CreateCommandStoredProc(conn, null))
                {
                    cmd.CommandText = "get_mrg_cand";
                    cmd.Parameters.Add(DbUtil.CreateParameterIn(cmd, "hsr_id_in", DbType.Decimal, recordId.Identifier));

                    using (IDataReader rdr = cmd.ExecuteReader())
                        while (rdr.Read())
                        {
                            retVal.Add(new VersionedDomainIdentifier()
                            {
                                Domain     = ApplicationContext.ConfigurationService.OidRegistrar.GetOid(ClientRegistryOids.REGISTRATION_EVENT).Oid,
                                Identifier = Convert.ToString(rdr["cand_hsr_id"]),
                                Version    = Convert.ToString(rdr["cand_vrsn_id"])
                            });
                        }
                }
                return(retVal);
            }
            finally
            {
                DatabasePersistenceService.ConnectionManager.ReleaseConnection(conn);
            }
        }