/// <summary>
        /// Gets taxa that matches the specified species observation search criteria.
        /// </summary>
        /// <param name="userContext">User context.</param>
        /// <param name="searchCriteria">The species observation search criteria.</param>
        /// <param name="coordinateSystem">Coordinate system used in geometry search criteria.</param>
        /// <returns>Information about taxa.</returns>
        public TaxonList GetTaxaBySearchCriteria(IUserContext userContext,
                                                 ISpeciesObservationSearchCriteria searchCriteria,
                                                 ICoordinateSystem coordinateSystem)
        {
            TaxonList taxa = DataSource.GetTaxaBySearchCriteria(userContext, searchCriteria, coordinateSystem);

            taxa.Sort();
            return(taxa);
        }
        /// <summary>
        /// Get all unique child taxa.
        /// This method operates on current taxon tree in contrast to
        /// the full taxon tree with all taxon tree nodes.
        /// </summary>
        /// <returns>All child taxa.</returns>
        public virtual TaxonList GetChildTaxa()
        {
            TaxonList childTaxa;

            childTaxa = new TaxonList(true);
            if (Children.IsNotEmpty())
            {
                // Add taxa for child taxon tree node.
                foreach (ITaxonTreeNode childTaxonTreeNode in Children)
                {
                    GetChildTaxa(childTaxonTreeNode, childTaxa);
                }
            }

            childTaxa.Sort();
            return(childTaxa);
        }
        /// <summary>
        /// Get all unique parent taxa.
        /// This method operates on current taxon tree in contrast to
        /// the full taxon tree with all taxon tree nodes.
        /// </summary>
        /// <returns>All parent taxa.</returns>
        public virtual TaxonList GetParentTaxa()
        {
            TaxonList parentTaxa;

            parentTaxa = new TaxonList(true);
            if (Parents.IsNotEmpty())
            {
                // Add taxa for parent taxon tree node.
                foreach (ITaxonTreeNode parentTaxonTreeNode in Parents)
                {
                    GetParentTaxa(parentTaxonTreeNode, parentTaxa);
                }
            }

            parentTaxa.Sort();
            return(parentTaxa);
        }
        /// <summary>
        /// Get all unique taxa in this species fact list.
        /// </summary>
        /// <returns>All unique taxa in this species fact list.</returns>
        public TaxonList GetTaxa()
        {
            TaxonList taxa;

            taxa = new TaxonList();
            if (this.IsNotEmpty())
            {
                foreach (ISpeciesFact speciesFact in this)
                {
                    if (speciesFact.Taxon.IsNotNull())
                    {
                        taxa.Merge(speciesFact.Taxon);
                    }
                }

                taxa.Sort();
            }

            return(taxa);
        }
        /// <summary>
        /// Get all unique hosts in this species fact list.
        /// </summary>
        /// <returns>All unique hosts in this species fact list.</returns>
        public TaxonList GetHosts()
        {
            TaxonList hosts;

            hosts = new TaxonList();
            if (this.IsNotEmpty())
            {
                foreach (ISpeciesFact speciesFact in this)
                {
                    if (speciesFact.Host.IsNotNull() &&
                        speciesFact.Host.Id != (Int32)(TaxonId.Life))
                    {
                        hosts.Merge(speciesFact.Host);
                    }
                }

                hosts.Sort();
            }

            return(hosts);
        }
        /// <summary>
        /// Update information about which factors, hosts,
        /// individual categories, periods, references and taxa
        /// that are used in the species facts.
        /// </summary>
        /// <param name="userContext">
        /// Information about the user that makes this method call.
        /// </param>
        /// <param name="selection">
        /// Scope of the data set is defined by this
        /// species fact data set selection.
        /// </param>
        /// <param name="speciesFacts">Species facts.</param>
        private void UpdateScope(IUserContext userContext,
                                 ISpeciesFactDataSetSelection selection,
                                 SpeciesFactList speciesFacts)
        {
            Factors = new FactorList(true);
            Factors.AddRange(selection.Factors);
            Hosts = new TaxonList(true);
            Hosts.AddRange(selection.Hosts);
            IndividualCategories = new IndividualCategoryList(true);
            IndividualCategories.AddRange(selection.IndividualCategories);
            Periods = new PeriodList(true);
            Periods.AddRange(selection.Periods);
            References = new ReferenceList(true);
            Taxa       = new TaxonList(true);
            Taxa.AddRange(selection.Taxa);

            if (speciesFacts.IsNotEmpty())
            {
                foreach (ISpeciesFact speciesFact in speciesFacts)
                {
                    Factors.Merge(speciesFact.Factor);
                    if (speciesFact.HasHost)
                    {
                        Hosts.Merge(speciesFact.Host);
                    }

                    IndividualCategories.Merge(speciesFact.IndividualCategory);
                    if (speciesFact.HasPeriod)
                    {
                        Periods.Merge(speciesFact.Period);
                    }

                    if (speciesFact.HasReference)
                    {
                        References.Merge(speciesFact.Reference);
                    }

                    Taxa.Merge(speciesFact.Taxon);
                }
            }

            // Set default values if no values are entered.
            if (Hosts.IsEmpty())
            {
                Hosts.Add(CoreData.TaxonManager.GetTaxon(userContext, TaxonId.Life));
            }

            if (IndividualCategories.IsEmpty())
            {
                IndividualCategories.Add(CoreData.FactorManager.GetDefaultIndividualCategory(userContext));
            }

            if (Periods.IsEmpty())
            {
                Periods.AddRange(CoreData.FactorManager.GetPeriods(userContext));
            }

            // Sort all lists.
            Factors.Sort();
            Hosts.Sort();
            IndividualCategories.Sort();
            Periods.Sort();
            References.Sort();
            Taxa.Sort();
        }