/// <summary>
        /// Merge old and new species facts to same list.
        /// </summary>
        /// <param name="speciesFacts">New species facts.</param>
        private void MergeSpeciesFacts(SpeciesFactList speciesFacts)
        {
            if (speciesFacts.IsEmpty())
            {
                return;
            }

            if (SpeciesFacts.IsEmpty())
            {
                SpeciesFacts = speciesFacts;
                return;
            }

            foreach (ISpeciesFact speciesFact in speciesFacts)
            {
                if (!SpeciesFacts.Exists(speciesFact.Identifier))
                {
                    // Add new species fact to old species facts.
                    SpeciesFacts.Add(speciesFact);
                }
            }
        }
        /// <summary>
        /// Remove old species facts that are no longer
        /// included in the species fact scope.
        /// </summary>
        private void RemoveSpeciesFactsNotInScope()
        {
            Int32        index;
            ISpeciesFact speciesFact;

            if (SpeciesFacts.IsNotEmpty())
            {
                for (index = SpeciesFacts.Count - 1; index >= 0; index--)
                {
                    speciesFact = SpeciesFacts[index];
                    if ((!Factors.Contains(speciesFact.Factor)) ||
                        (!IndividualCategories.Contains(speciesFact.IndividualCategory)) ||
                        (!Taxa.Contains(speciesFact.Taxon)) ||
                        (speciesFact.HasHost && !Hosts.Contains(speciesFact.Host)) ||
                        (speciesFact.HasPeriod && !Periods.Contains(speciesFact.Period)))
                    {
                        // This species fact is no longer
                        // included in the species fact scope.
                        SpeciesFacts.RemoveAt(index);
                    }
                }
            }
        }
        /// <summary>
        /// Make automated calculations of species facts
        /// that are "automatic" in a species fact list.
        /// </summary>
        /// <param name="userContext">
        /// Information about the user that makes this method call.
        /// </param>
        public virtual void InitAutomatedCalculations(IUserContext userContext)
        {
            if (SpeciesFacts.IsNotEmpty())
            {
                foreach (ISpeciesFact speciesFact in SpeciesFacts)
                {
                    switch (speciesFact.Factor.Id)
                    {
                    case (Int32)(FactorId.RedListCategoryAutomatic):
                        ((SpeciesFactRedListCategory)(speciesFact)).Init(userContext, SpeciesFacts);
                        break;

                    case (Int32)(FactorId.RedListCriteriaAutomatic):
                        ((SpeciesFactRedListCriteria)(speciesFact)).Init(userContext, SpeciesFacts);
                        break;

                    case (Int32)(FactorId.RedListCriteriaDocumentationAutomatic):
                        ((SpeciesFactRedListCriteriaDocumentation)(speciesFact)).Init(userContext, SpeciesFacts);
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Expand a species fact list with empty species facts so
        /// that every combination from the species fact data set
        /// selection is represented.
        /// Factors of type header are excluded.
        /// Periodic factors are not expanded to
        /// individual categories other than the default.
        /// </summary>
        /// <param name="userContext">
        /// Information about the user that makes this method call.
        /// </param>
        private void UpdateWithEmptySpeciesFacts(IUserContext userContext)
        {
            foreach (IFactor factor in Factors)
            {
                if (factor.UpdateMode.IsHeader)
                {
                    // Don't create SpeicesFacts for 'Headers'.
                    continue;
                }

                foreach (IIndividualCategory individualCategory in IndividualCategories)
                {
                    if (factor.IsPeriodic &&
                        (individualCategory.Id != ((Int32)IndividualCategoryId.Default)))
                    {
                        // Periodic factors should only be combined
                        // with default IndividualCategory.
                        continue;
                    }

                    foreach (ITaxon taxon in Taxa)
                    {
                        if (factor.IsPeriodic)
                        {
                            // Factor is periodic
                            foreach (IPeriod period in Periods)
                            {
                                if (factor.IsTaxonomic)
                                {
                                    foreach (ITaxon host in Hosts)
                                    {
                                        SpeciesFacts.Merge(userContext, taxon, individualCategory, factor, host, period);
                                    }
                                }
                                else
                                {
                                    SpeciesFacts.Merge(userContext, taxon, individualCategory, factor, null, period);
                                }
                            }
                            // End factor is periodic
                        }
                        else
                        {
                            // Factor is not periodic
                            if (factor.IsTaxonomic)
                            {
                                foreach (ITaxon host in Hosts)
                                {
                                    SpeciesFacts.Merge(userContext, taxon, individualCategory, factor, host, null);
                                }
                            }
                            else
                            {
                                SpeciesFacts.Merge(userContext, taxon, individualCategory, factor, null, null);
                            }
                            // End factor is not periodic
                        }
                    }
                }
            }
        }