/// <summary>
        /// Groups element into sub-lists of adjacent that share the same property, true or false, from the predicate.
        /// Basically performs edge detection in order to operate.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="elements"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static IEnumerable <Tuple <IEnumerable <T>, bool> > ClusteredByPredicate <T>(this IEnumerable <T> elements, Func <T, bool> predicate)
        {
            // We'll build a list assigning numeric, so we can have true, false AND "added at the front" for edge detection purposes.
            var withTrueFalseAsOneZero = Alg.ReadPoint(elements.Select(x => Tuple.Create(x, predicate(x) ? 1 : 0))).TakenToEnd();

            return(Alg.Map(
                       (c, prior) =>
            {
                var cf = c.First();
                return Alg.When(
                    cf.Item2 != prior.Item2,
                    () => Tuple.Create(c.TakeWhile(x => x.Item2 == cf.Item2).Select(x => x.Item1), (cf.Item2 == 1)));
            },
                       withTrueFalseAsOneZero.Tails().Where(x => x.Any()), new[] { Tuple.Create(default(T), -1) }.Concat(withTrueFalseAsOneZero)).SelectMany(x => x.ToEnumerable()));
        }