/// <summary>
        /// Executes, in parallel chunks, an enumerator function for every element in the given list.
        /// </summary>
        static public IEnumerator ForEachParallel <T>(IList <T> inList, Func <T, IEnumerator> inOperation, int inChunkSize)
        {
            int count = 0;

            if (inList != null && inOperation != null && (count = inList.Count) > 0)
            {
                int           chunkSize   = Math.Min(inChunkSize, count);
                int           numItems    = 0;
                IEnumerator[] enumerators = new IEnumerator[chunkSize];
                for (int i = 0; i < count; ++i)
                {
                    enumerators[numItems++] = inOperation(inList[i]);
                    if (i == count - 1 || numItems == chunkSize)
                    {
                        yield return(Routine.Inline(
                                         Routine.Combine(enumerators)
                                         ));

                        for (int j = 0; j < numItems; ++j)
                        {
                            enumerators[j] = null;
                        }
                        numItems = 0;
                    }
                }
            }
        }
 static private IEnumerator LoopedRoutine(Func <IEnumerator> inRoutine)
 {
     while (true)
     {
         yield return(Routine.Inline(inRoutine()));
     }
 }
 /// <summary>
 /// Returns an IEnumerator that executes a routine after the given number of seconds.
 /// </summary>
 static public IEnumerator Delay(IEnumerator inRoutine, float inSeconds)
 {
     if (inSeconds > 0)
     {
         yield return(inSeconds);
     }
     yield return(Routine.Inline(inRoutine));
 }
        /// <summary>
        /// Wraps a sequence of objects into a yieldable IEnumerator.
        /// This will yield each given object once.
        /// </summary>
        static public IEnumerator Yield(params object[] inObjects)
        {
            if (inObjects == null || inObjects.Length == 0)
            {
                return(null);
            }

            if (inObjects.Length == 1)
            {
                return(Yield(inObjects[0]));
            }

            return(Routine.Inline(new YieldableArray((object[])inObjects.Clone())));
        }
        /// <summary>
        /// Wraps an object into a yieldable IEnumerator.
        /// This will yield the given object once.
        /// </summary>
        static public IEnumerator Yield(object inObject)
        {
            if (inObject == null)
            {
                return(null);
            }

            IEnumerator enumerator = inObject as IEnumerator;

            if (enumerator != null)
            {
                return(Routine.Inline(enumerator));
            }
            return(Routine.Inline(new YieldableObject(inObject)));
        }
        /// <summary>
        /// Wraps a sequence of objects into a yieldable IEnumerator.
        /// This will yield each given object once.
        /// </summary>
        static public IEnumerator Yield(IList <object> inObjects)
        {
            if (inObjects == null || inObjects.Count == 0)
            {
                return(null);
            }

            if (inObjects.Count == 1)
            {
                return(Yield(inObjects[0]));
            }

            object[] objects = new object[inObjects.Count];
            inObjects.CopyTo(objects, 0);
            return(Routine.Inline(new YieldableArray(objects)));
        }
        /// <summary>
        /// Executes, in parallel, an enumerator function for every element in the given list.
        /// </summary>
        static public IEnumerator ForEachParallel <T>(IList <T> inList, Func <T, IEnumerator> inOperation)
        {
            int count = 0;

            if (inList != null && inOperation != null && (count = inList.Count) > 0)
            {
                IEnumerator[] enumerators = new IEnumerator[count];
                for (int i = 0; i < count; ++i)
                {
                    enumerators[i] = inOperation(inList[i]);
                }
                yield return(Routine.Inline(
                                 Routine.Combine(enumerators)
                                 ));
            }
        }
        /// <summary>
        /// Waits for the animator to play and exit the given state.
        /// </summary>
        static public IEnumerator WaitToCompleteState(this Animator inAnimator, string inStateName, int inLayer = 0)
        {
            yield return(Routine.Inline(WaitForState(inAnimator, inStateName, inLayer)));

            yield return(Routine.Inline(WaitForNotState(inAnimator, inStateName, inLayer)));
        }