/// <summary>
        /// RolePlayerChangeRule: typeof(ReadingOrderHasReading), FireTime=LocalCommit, Priority=ORMCoreDomainModel.BeforeDelayValidateRulePriority;
        /// </summary>
        private static void EnforceNoEmptyReadingOrderRolePlayerChangeRule(RolePlayerChangedEventArgs e)
        {
            ReadingOrderHasReading link = e.ElementLink as ReadingOrderHasReading;

            if (e.DomainRole.Id == ReadingOrderHasReading.ReadingOrderDomainRoleId)
            {
                ReadingOrder order = (ReadingOrder)e.OldRolePlayer;
                if (!order.IsDeleted && order.ReadingCollection.Count == 0)
                {
                    order.Delete();
                }
            }
        }
        /// <summary>
        /// DeleteRule: typeof(ReadingOrderHasReading), FireTime=LocalCommit, Priority=ORMCoreDomainModel.BeforeDelayValidateRulePriority;
        /// If the ReadingOrder.ReadingCollection is empty then remove the ReadingOrder
        /// </summary>
        private static void EnforceNoEmptyReadingOrderDeleteRule(ElementDeletedEventArgs e)
        {
            ReadingOrderHasReading link    = e.ModelElement as ReadingOrderHasReading;
            ReadingOrder           readOrd = link.ReadingOrder;

            if (!readOrd.IsDeleted)
            {
                if (readOrd.ReadingCollection.Count == 0)
                {
                    readOrd.Delete();
                }
            }
        }
        /// <summary>
        /// Verify that all <see cref="ReadingOrder"/>s have unique <see cref="ReadingOrder.RoleCollection">role collections</see>
        /// </summary>
        /// <param name="element">A <see cref="FactType"/></param>
        private static void DelayValidateReadingOrderCollation(ModelElement element)
        {
            if (element.IsDeleted)
            {
                return;
            }
            FactType factType = (FactType)element;
            LinkedElementCollection <ReadingOrder> ordersCollection = factType.ReadingOrderCollection;
            int orderCount = ordersCollection.Count;

            if (orderCount > 1)
            {
                // Get all orders in a collatable form, starting by caching information locally
                // so it is easily accessed. Note that this will also change the collection we're
                // iterating so we need to be careful about changes.
                ReadingOrder[] orders = new ReadingOrder[orderCount];
                ordersCollection.CopyTo(orders, 0);
                LinkedElementCollection <RoleBase>[] roleCollections = new LinkedElementCollection <RoleBase> [orderCount];
                for (int i = 0; i < orderCount; ++i)
                {
                    roleCollections[i] = orders[i].RoleCollection;
                }

                // Priority is top down, so we move later readings into a higher reading order
                for (int i = 0; i < orderCount; ++i)
                {
                    ReadingOrder currentOrder = orders[i];
                    for (int j = i + 1; j < orderCount; ++j)
                    {
                        ReadingOrder compareToOrder = orders[j];
                        if (compareToOrder != null)                         // Will be null if it has already been recognized as a duplicate
                        {
                            // These should all have the same count, but it doesn't hurt to be defensive
                            LinkedElementCollection <RoleBase> currentRoles   = roleCollections[i];
                            LinkedElementCollection <RoleBase> compareToRoles = roleCollections[j];
                            int roleCount = currentRoles.Count;
                            if (roleCount == compareToRoles.Count)
                            {
                                int k = 0;
                                for (; k < roleCount; ++k)
                                {
                                    if (currentRoles[k] != compareToRoles[k])
                                    {
                                        break;
                                    }
                                }
                                if (k == roleCount)
                                {
                                    // Order is the same, collate the later readings up to the current order
                                    ReadOnlyCollection <ReadingOrderHasReading> readingLinks = ReadingOrderHasReading.GetLinksToReadingCollection(compareToOrder);
                                    int readingCount = readingLinks.Count;
                                    for (int l = 0; l < readingCount; ++l)
                                    {
                                        readingLinks[l].ReadingOrder = currentOrder;
                                    }
                                    orders[j] = null;
                                }
                            }
                        }
                    }
                }
            }
        }