//todo xml, ignores given init if first/last/__current is used
        public Initiative CreateInitiative(RelativeInitiativeOrder relativeOrder, Initiative targetInitiative)
        {
            switch (relativeOrder)
            {
            case RelativeInitiativeOrder.BeforeCurrent:
            case RelativeInitiativeOrder.Current:
            case RelativeInitiativeOrder.AfterCurrent:
                if (currentlyExecuting == null)
                {
                    throw new InvalidOperationException("There is no currently executing event from which to get an initiative");
                }
                break;

            case RelativeInitiativeOrder.BeforeTarget:
            case RelativeInitiativeOrder.Target:
            case RelativeInitiativeOrder.AfterTarget:
                if (targetInitiative == null)
                {
                    throw new ArgumentNullException(nameof(targetInitiative), "The chosen RelativeInitiativeOrder requires a target initiative, but no initiative was passed in.");
                }
                break;
            }

            InternalInitiative init = new InternalInitiative();

            InsertInitiative(relativeOrder, init, targetInitiative);
            return(init);
        }
        //todo xml?
        public Initiative CreateInitiative(RelativeInitiativeOrder relativeOrder, EventScheduling targetEventScheduling)
        {
            if (targetEventScheduling == null)
            {
                throw new ArgumentNullException(nameof(targetEventScheduling));
            }
            if (!targetEventScheduling.IsLive)
            {
                throw new InvalidOperationException("This event scheduling has already executed or been canceled, and can't be reused");
            }
            var es = targetEventScheduling as InternalEventScheduling;

            if (es == null)
            {
                throw new InvalidOperationException("User-created subtypes of EventScheduling are not supported");
            }
            return(CreateInitiative(relativeOrder, es.Initiative));
        }
        //todo xml, no checks, just does the call
        private void InsertInitiative(RelativeInitiativeOrder relativeOrder, Initiative initToInsert, Initiative targetInitiative = null)
        {
            switch (relativeOrder)
            {
            case RelativeInitiativeOrder.First:
                oc.InsertAtStart(initToInsert);
                break;

            case RelativeInitiativeOrder.Last:
                oc.InsertAtEnd(initToInsert);
                break;

            case RelativeInitiativeOrder.BeforeCurrent:
                oc.InsertBefore(currentlyExecuting.Initiative, initToInsert);
                break;

            case RelativeInitiativeOrder.Current:
                throw new InvalidOperationException("Can't reinsert current initiative");

            case RelativeInitiativeOrder.AfterCurrent:
                oc.InsertAfter(currentlyExecuting.Initiative, initToInsert);
                break;

            case RelativeInitiativeOrder.BeforeTarget:
                oc.InsertBefore(targetInitiative, initToInsert);                         // This call throws if targetInitiative isn't in the collection
                break;

            case RelativeInitiativeOrder.Target:
                throw new InvalidOperationException("Can't reinsert target initiative");

            case RelativeInitiativeOrder.AfterTarget:
                oc.InsertAfter(targetInitiative, initToInsert);                         // This call throws if targetInitiative isn't in the collection
                break;

            default:
                throw new InvalidOperationException("Unknown value for relativeOrder");
            }
        }
        public Initiative CreateInitiative(RelativeInitiativeOrder relativeOrder)
        {
            switch (relativeOrder)
            {
            case RelativeInitiativeOrder.BeforeCurrent:
            case RelativeInitiativeOrder.Current:
            case RelativeInitiativeOrder.AfterCurrent:
                if (currentlyExecuting == null)
                {
                    throw new InvalidOperationException("There is no currently executing event from which to get an initiative");
                }
                break;

            case RelativeInitiativeOrder.BeforeTarget:
            case RelativeInitiativeOrder.Target:
            case RelativeInitiativeOrder.AfterTarget:
                throw new ArgumentException("The chosen RelativeInitiativeOrder requires a target initiative - use other overload");
            }

            InternalInitiative init = new InternalInitiative();

            InsertInitiative(relativeOrder, init);
            return(init);
        }
        private EventScheduling ScheduleWithRelativeInitiativeInternal(IEvent scheduledEvent, long ticksInFuture, RelativeInitiativeOrder relativeInitiativeOrder, Initiative targetInitiative)
        {
            if (scheduledEvent == null)
            {
                throw new ArgumentNullException(nameof(scheduledEvent));
            }
            switch (relativeInitiativeOrder)
            {
            case RelativeInitiativeOrder.BeforeCurrent:
            case RelativeInitiativeOrder.Current:
            case RelativeInitiativeOrder.AfterCurrent:
                if (currentlyExecuting == null)
                {
                    throw new InvalidOperationException("There is no currently executing event from which to get an initiative");
                }
                break;

            case RelativeInitiativeOrder.BeforeTarget:
            case RelativeInitiativeOrder.Target:
            case RelativeInitiativeOrder.AfterTarget:
                if (targetInitiative == null)
                {
                    throw new ArgumentNullException(nameof(targetInitiative), "The chosen RelativeInitiativeOrder requires a target initiative, but no initiative was passed in.");
                }
                break;
            }
            Initiative init;

            if (relativeInitiativeOrder == RelativeInitiativeOrder.Current)
            {
                init = currentlyExecuting.Initiative;
            }
            else if (relativeInitiativeOrder == RelativeInitiativeOrder.Target)
            {
                init = targetInitiative;
                if (!oc.Contains(init))
                {
                    throw new InvalidOperationException("Target initiative must exist in this event scheduler");
                }
            }
            else
            {
                init = new InternalInitiative {
                    AutoRemove = true
                };
                InsertInitiative(relativeInitiativeOrder, init);
            }
            return(CreateAndSchedule(scheduledEvent, ticksInFuture, init));
        }
 //todo xml, make sure to reinforce here that ticksInFuture is from the CURRENT tick only.
 public EventScheduling ScheduleWithRelativeInitiative(IEvent scheduledEvent, long ticksInFuture, RelativeInitiativeOrder relativeInitiativeOrder, Initiative targetInitiative)
 => ScheduleWithRelativeInitiativeInternal(scheduledEvent, ticksInFuture, relativeInitiativeOrder, targetInitiative);