/// <summary>
 /// Select the result alternative which consumed the most amount of input and use that to
 /// continue the parse. If there are no alternatives, returns failure. If there are ties,
 /// the first is selected.
 /// </summary>
 /// <typeparam name="TInput"></typeparam>
 /// <typeparam name="TOutput"></typeparam>
 /// <param name="multiParser"></param>
 /// <returns></returns>
 public static IParser <TInput, TOutput> Longest <TInput, TOutput>(this IMultiParser <TInput, TOutput> multiParser)
 => multiParser.Select(args =>
 {
     var longest = args.Result.Results
                   .Where(r => r.Success)
                   .OrderByDescending(r => r.Consumed)
                   .FirstOrDefault();
     return(longest != null ? args.Success(longest) : args.Failure());
 });
 /// <summary>
 /// Returns the first successful alternative which matches a predicate to continue the
 /// parse with.
 /// </summary>
 /// <typeparam name="TInput"></typeparam>
 /// <typeparam name="TOutput"></typeparam>
 /// <param name="multiParser"></param>
 /// <param name="predicate"></param>
 /// <returns></returns>
 public static IParser <TInput, TOutput> First <TInput, TOutput>(this IMultiParser <TInput, TOutput> multiParser, Func <IResultAlternative <TOutput>, bool> predicate)
 {
     Assert.ArgumentNotNull(predicate, nameof(predicate));
     return(multiParser.Select(args =>
     {
         var selected = args.Result.Results.FirstOrDefault(predicate);
         return selected != null ? args.Success(selected) : args.Failure();
     }));
 }
 /// <summary>
 /// Expect the IMultiResult to contain exactly 1 alternative, and select that to continue.
 /// </summary>
 /// <typeparam name="TInput"></typeparam>
 /// <typeparam name="TOutput"></typeparam>
 /// <param name="multiParser"></param>
 /// <returns></returns>
 public static IParser <TInput, TOutput> Single <TInput, TOutput>(this IMultiParser <TInput, TOutput> multiParser)
 => multiParser.Select(args =>
 {
     if (args.Result.Results.Count == 1)
     {
         return(args.Success(args.Result.Results[0]));
     }
     return(args.Failure());
 });