/// <summary>
        /// Updates the reference relations.
        /// </summary>
        /// <param name="taxon">The source taxon.</param>
        /// <param name="guid">The unique identifier.</param>
        /// <param name="newReferenceList">The new reference list.</param>
        /// <param name="applyMode">The apply mode.</param>
        public void UpdateReferenceRelations(
            ITaxon taxon,
            string guid,
            ReferenceViewModel[] newReferenceList,
            ReferenceApplyMode applyMode)
        {
            ReferenceRelationList allReferenceRelationItemsToCreate = new ReferenceRelationList();
            ReferenceRelationList allReferenceRelationItemsToDelete = new ReferenceRelationList();
            ReferenceRelationList createReferenceRelationItems;
            ReferenceRelationList deleteReferenceRelationItems;

            // Handle source taxon reference relations
            createReferenceRelationItems = GetReferenceRelationsThatWillBeCreated(guid, newReferenceList, ReferenceApplyMode.OnlySelected);
            deleteReferenceRelationItems = GetReferenceRelationsThatWillBeDeleted(guid, newReferenceList, ReferenceApplyMode.OnlySelected);
            allReferenceRelationItemsToCreate.AddRange(createReferenceRelationItems);
            allReferenceRelationItemsToDelete.AddRange(deleteReferenceRelationItems);

            if (applyMode != ReferenceApplyMode.OnlySelected)
            {
                // Get all child taxa
                ITaxonSearchCriteria taxonSearchCriteria = new TaxonSearchCriteria();
                taxonSearchCriteria.TaxonIds = new List <int>();
                taxonSearchCriteria.TaxonIds.Add(taxon.Id);
                taxonSearchCriteria.Scope = TaxonSearchScope.AllChildTaxa;
                TaxonList taxonList = CoreData.TaxonManager.GetTaxa(user, taxonSearchCriteria);
                taxonList.Remove(taxon);

                foreach (ITaxon childTaxon in taxonList)
                {
                    createReferenceRelationItems = GetReferenceRelationsThatWillBeCreated(childTaxon.Guid, newReferenceList, applyMode);
                    deleteReferenceRelationItems = GetReferenceRelationsThatWillBeDeleted(childTaxon.Guid, newReferenceList, applyMode);
                    allReferenceRelationItemsToCreate.AddRange(createReferenceRelationItems);
                    allReferenceRelationItemsToDelete.AddRange(deleteReferenceRelationItems);
                }
            }

            if (allReferenceRelationItemsToCreate.Count > 0 || allReferenceRelationItemsToDelete.Count > 0)
            {
                using (ITransaction transaction = user.StartTransaction())
                {
                    CoreData.ReferenceManager.DeleteReferenceRelations(user, allReferenceRelationItemsToDelete);
                    CoreData.ReferenceManager.CreateReferenceRelations(user, allReferenceRelationItemsToCreate);
                    transaction.Commit();
                }
            }
        }
        /// <summary>
        /// Gets the reference relations that will be created.
        /// </summary>
        /// <param name="guid">The unique identifier.</param>
        /// <param name="newReferences">The new references.</param>
        /// <param name="applyMode">The apply mode.</param>
        /// <returns>A list with all reference relations that will be created.</returns>
        private ReferenceRelationList GetReferenceRelationsThatWillBeCreated(string guid, ReferenceViewModel[] newReferences, ReferenceApplyMode applyMode)
        {
            ReferenceRelationList referencesToAdd = new ReferenceRelationList();

            IEnumerable <IReferenceRelation> existingReferenceRelations = CoreData.ReferenceManager.GetReferenceRelations(user, guid);

            if (applyMode == ReferenceApplyMode.ReplaceOnlySourceInUnderlyingTaxa)
            {
                existingReferenceRelations = existingReferenceRelations.Where(referenceRelation => referenceRelation.Type.Id == (int)ReferenceRelationTypeId.Source);
            }

            foreach (ReferenceViewModel newReference in newReferences)
            {
                // If the new reference isn't source and we are in Replace only source in underlying mode, don't add this reference.
                if (applyMode == ReferenceApplyMode.ReplaceOnlySourceInUnderlyingTaxa && newReference.UsageTypeId != (int)ReferenceRelationTypeId.Source)
                {
                    continue;
                }

                bool referenceAlreadyExists = existingReferenceRelations.Any(existingReferenceRelation => newReference.Id == existingReferenceRelation.ReferenceId && newReference.UsageTypeId == existingReferenceRelation.Type.Id);

                if (!referenceAlreadyExists)
                {
                    IReference reference = new ArtDatabanken.Data.Reference();
                    reference.Id = newReference.Id;

                    ReferenceRelation newReferenceRelation = new ReferenceRelation()
                    {
                        RelatedObjectGuid = guid,
                        Type        = CoreData.ReferenceManager.GetReferenceRelationType(user, newReference.UsageTypeId),
                        Reference   = null,
                        ReferenceId = newReference.Id
                    };
                    referencesToAdd.Add(newReferenceRelation);
                }
            }

            return(referencesToAdd);
        }
        /// <summary>
        /// Gets the reference relations that will be deleted.
        /// </summary>
        /// <param name="guid">The unique identifier.</param>
        /// <param name="newReferences">The new references.</param>
        /// <param name="applyMode">The apply mode.</param>
        /// <returns>A list with all reference relations that will be deleted.</returns>
        private ReferenceRelationList GetReferenceRelationsThatWillBeDeleted(string guid, ReferenceViewModel[] newReferences, ReferenceApplyMode applyMode)
        {
            ReferenceRelationList            referenceRelationsToDelete = new ReferenceRelationList();
            IEnumerable <IReferenceRelation> existingReferenceRelations = CoreData.ReferenceManager.GetReferenceRelations(user, guid);

            if (applyMode == ReferenceApplyMode.ReplaceOnlySourceInUnderlyingTaxa)
            {
                existingReferenceRelations = existingReferenceRelations.Where(referenceRelation => referenceRelation.Type.Id == (int)ReferenceRelationTypeId.Source);
            }

            // Don't delete any reference relations in the these modes.
            if (applyMode == ReferenceApplyMode.AddToUnderlyingTaxa)
            {
                return(referenceRelationsToDelete);
            }

            foreach (IReferenceRelation existingReferenceRelation in existingReferenceRelations)
            {
                bool found = newReferences.Any(newReference => newReference.Id == existingReferenceRelation.ReferenceId &&
                                               newReference.UsageTypeId == existingReferenceRelation.Type.Id);
                if (!found)
                {
                    referenceRelationsToDelete.Add(existingReferenceRelation);
                }
            }

            return(referenceRelationsToDelete);
        }