private HashSet <LumpSplitExportModel> CreateSplitExportList(IEnumerable <ITaxon> taxa)
        {
            var splitExportList = new HashSet <LumpSplitExportModel>();

            foreach (ITaxon taxon in taxa)
            {
                LumpSplitEventList lumpEvents = null;
                if (taxon.ChangeStatus.Id == (Int32)TaxonChangeStatusId.InvalidDueToSplit)
                {
                    lumpEvents = CoreData.TaxonManager.GetLumpSplitEventsByOldReplacedTaxon(_user, taxon);
                }
                else if (taxon.ChangeStatus.Id == (Int32)TaxonChangeStatusId.ValidAfterSplit)
                {
                    lumpEvents = CoreData.TaxonManager.GetLumpSplitEventsByNewReplacingTaxon(_user, taxon);
                }

                if (lumpEvents != null && lumpEvents.Count > 0)
                {
                    foreach (ILumpSplitEvent lumpSplitEvent in lumpEvents)
                    {
                        var lumpExportModel = LumpSplitExportModel.Create(_user, lumpSplitEvent);
                        if (!splitExportList.Contains(lumpExportModel))
                        {
                            splitExportList.Add(lumpExportModel);
                        }
                    }
                }
            }
            return(splitExportList);
        }
        /// <summary>
        /// Gets the lump events including related lump events for taxon.
        /// </summary>
        /// <param name="userContext">The user context.</param>
        /// <param name="taxon">The taxon.</param>
        /// <returns>Lump events including related lumpevents for the taxon.</returns>
        private static LumpSplitEventList GetLumpEventsIncludingRelatedLumpEventsForTaxon(IUserContext userContext, ITaxon taxon)
        {
            LumpSplitEventList lumpEvents = null;

            if (taxon.ChangeStatus.Id == (int)TaxonChangeStatusId.InvalidDueToLump)
            {
                lumpEvents = CoreData.TaxonManager.GetLumpSplitEventsByOldReplacedTaxon(userContext, taxon);

                if (lumpEvents != null && lumpEvents.Count > 0)
                {
                    ILumpSplitEvent firstLumpEvent = lumpEvents.First(x => x.Type.Id == (int)LumpSplitEventTypeId.Lump);
                    if (firstLumpEvent != null)
                    {
                        lumpEvents = CoreData.TaxonManager.GetLumpSplitEventsByNewReplacingTaxon(userContext, firstLumpEvent.TaxonAfter);
                    }

                    //lumpEvents.RemoveAll(x => x.Type.Id != (int)LumpSplitEventTypeId.Lump);
                }
            }
            else if (taxon.ChangeStatus.Id == (int)TaxonChangeStatusId.ValidAfterLump)
            {
                lumpEvents = CoreData.TaxonManager.GetLumpSplitEventsByNewReplacingTaxon(userContext, taxon);
                //lumpEvents.RemoveAll(x => x.Type.Id != (int)LumpSplitEventTypeId.Lump);
            }

            return(lumpEvents);
        }
        private LumpSplitEventList GetSplitEvents(IUserContext userContext, ITaxon taxon)
        {
            LumpSplitEventList lumpEvents = null;

            if (taxon.ChangeStatus.Id == (Int32)TaxonChangeStatusId.InvalidDueToSplit)
            {
                lumpEvents = CoreData.TaxonManager.GetLumpSplitEventsByOldReplacedTaxon(userContext, taxon);
            }
            else if (taxon.ChangeStatus.Id == (Int32)TaxonChangeStatusId.ValidAfterSplit)
            {
                lumpEvents = CoreData.TaxonManager.GetLumpSplitEventsByNewReplacingTaxon(userContext, taxon);
            }

            return(lumpEvents);
        }
        /// <summary>
        /// Gets all split event lists for taxa set.
        /// </summary>
        /// <param name="userContext">The user context.</param>
        /// <param name="nodes">The nodes.</param>
        /// <returns>All split event lists for taxa set.</returns>
        private static HashSet <LumpSplitEventList> GetAllSplitEventListsForTaxa(IUserContext userContext, HashSet <ITaxonRelationsTreeNode> nodes)
        {
            HashSet <LumpSplitEventList> splitSet = new HashSet <LumpSplitEventList>(new LumpSplitEventListComparer());

            foreach (ITaxonRelationsTreeNode treeNode in nodes)
            {
                LumpSplitEventList splitList = GetSplitEventsIncludingRelatedSplitEventsForTaxon(userContext, treeNode.Taxon);
                if (splitList != null && splitList.Count > 0)
                {
                    splitSet.Add(splitList);
                }
            }

            return(splitSet);
        }
        /// <summary>
        /// Gets the split events including related split events for taxon.
        /// </summary>
        /// <param name="userContext">The user context.</param>
        /// <param name="taxon">The taxon.</param>
        /// <returns>All split events including related split events for taxon.</returns>
        private static LumpSplitEventList GetSplitEventsIncludingRelatedSplitEventsForTaxon(IUserContext userContext, ITaxon taxon)
        {
            LumpSplitEventList splitEvents = null;

            if (taxon.ChangeStatus.Id == (int)TaxonChangeStatusId.InvalidDueToSplit)
            {
                splitEvents = CoreData.TaxonManager.GetLumpSplitEventsByOldReplacedTaxon(userContext, taxon);
                //splitEvents.RemoveAll(x => x.Type.Id != (int)LumpSplitEventTypeId.Split);
            }
            else if (taxon.ChangeStatus.Id == (int)TaxonChangeStatusId.ValidAfterSplit)
            {
                splitEvents = CoreData.TaxonManager.GetLumpSplitEventsByNewReplacingTaxon(userContext, taxon);

                ILumpSplitEvent firstSplitEvent = splitEvents.First(x => x.Type.Id == (int)LumpSplitEventTypeId.Split);
                if (firstSplitEvent != null)
                {
                    splitEvents = CoreData.TaxonManager.GetLumpSplitEventsByNewReplacingTaxon(userContext, firstSplitEvent.TaxonBefore);
                }

                //splitEvents.RemoveAll(x => x.Type.Id != (int)LumpSplitEventTypeId.Split);
            }

            return(splitEvents);
        }
        /// <summary>
        /// Adds the split cluster.
        /// </summary>
        /// <param name="sb">The string builder.</param>
        /// <param name="lumpSplitEventList">The lump split event list.</param>
        /// <param name="clusterCount">The cluster count.</param>
        /// <param name="taxaSet">The taxa set.</param>
        private static void AddSplitCluster(
            StringBuilder sb,
            LumpSplitEventList lumpSplitEventList,
            int clusterCount,
            HashSet <ITaxon> taxaSet)
        {
            HashSet <ITaxon> splitNodes = new HashSet <ITaxon>();

            foreach (ILumpSplitEvent lumpSplitEvent in lumpSplitEventList)
            {
                splitNodes.Add(lumpSplitEvent.TaxonAfter);
                splitNodes.Add(lumpSplitEvent.TaxonBefore);
            }
            sb.AppendLine("");
            sb.AppendLine(string.Format("subgraph cluster_{0} {{", clusterCount));
            sb.AppendLine("style = dashed;");
            sb.AppendLine("color = red;");
            sb.AppendLine("label = \"Split\";");

            // Nodes
            foreach (ITaxon node in splitNodes)
            {
                sb.AppendLine(string.Format(
                                  "node_{0}cluster_{5} [label=\"{1}\", shape=box, style=rounded, color={2}, peripheries={3}, penwidth={4}];",
                                  node.Id,
                                  GetNodeLabel(node),
                                  node.IsValid ? "black" : "red",
                                  node.Category.IsTaxonomic ? 1 : 2,
                                  node.IsValid ? 1 : 2,
                                  clusterCount));
            }

            // Edges
            foreach (ILumpSplitEvent lumpSplitEvent in lumpSplitEventList)
            {
                //var edge = tree.GetTreeEdge(lumpSplitEvent.TaxonBefore.Id, lumpSplitEvent.TaxonAfter.Id);

                sb.AppendLine(string.Format(
                                  "node_{0}cluster_{5} -> node_{1}cluster_{5} [style={2}, color={3}, label=\"{4}\"];",
                                  lumpSplitEvent.TaxonBefore.Id,
                                  lumpSplitEvent.TaxonAfter.Id,
                                  "solid",
                                  "black",
                                  lumpSplitEvent.Description,
                                  clusterCount));

                //edge.IsMain ? "solid" : "dashed",
                //    edge.IsValid ? "black" : "red",
                //    edge.IsValid ? edge.TaxonRelation.Id.ToString() : string.Format("({0})\\n\\[Not valid\\]", edge.TaxonRelation.Id)));
            }

            sb.AppendLine("}");
            bool appendOnlyLumpedIntoRelationFromCluster = false;

            if (appendOnlyLumpedIntoRelationFromCluster)
            {
                sb.AppendLine(
                    string.Format(
                        "node_{0}lump -> node_{0} [style={1}, color={2}, label=\"{3}\", arrowhead=\"{4}\"];",
                        lumpSplitEventList[0].TaxonAfter.Id,
                        "solid",
                        "black",
                        "",
                        "dot"));
            }
            else
            {
                foreach (ITaxon taxon in splitNodes)
                {
                    if (taxaSet.Any(x => x.Id == taxon.Id))
                    {
                        sb.AppendLine(
                            string.Format(
                                "node_{0}cluster_{5} -> node_{0} [style={1}, color={2}, label=\"{3}\", arrowhead=\"{4}\"];",
                                taxon.Id,
                                "solid",
                                "black",
                                "",
                                "dot",
                                clusterCount));
                    }
                }
            }
        }