context: using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Linq.Expressions;
  using System.Reflection;
  using NHibernate.Impl;
  using NHibernate.Type;
  using NHibernate.Util;
  using Remotion.Linq.Parsing.ExpressionVisitors;
  using System.Threading;
  using System.Threading.Tasks;
  
  namespace NHibernate.Linq
  {
  	/// <summary>
  	/// NHibernate LINQ extension methods. They are meant to work with <see cref="NhQueryable{T}"/>. Supplied <see cref="IQueryable{T}"/> parameters
  	/// should at least have an <see cref="INhQueryProvider"/> <see cref="IQueryable.Provider"/>. <see cref="ISession.Query{T}()"/> and
  	/// its overloads supply such queryables.
  	/// </summary>
  	public static class LinqExtensionMethods
  	{
  		#region AnyAsync
  
  		/// <summary>Determines whether a sequence contains any elements.</summary>
  		/// <param name="source">A sequence to check for being empty.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
  		/// <returns>true if the source sequence contains any elements; otherwise, false.</returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<bool> AnyAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<bool>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AnyDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<bool>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<bool>(ex);
  			}
  		}
  
  		/// <summary>Determines whether any element of a sequence satisfies a condition.</summary>
  		/// <param name="source">A sequence whose elements to test for a condition.</param>
  		/// <param name="predicate">A function to test each element for a condition.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
  		/// <returns>true if any elements in the source sequence pass the test in the specified predicate; otherwise, false.</returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> or <paramref name="predicate" /> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<bool> AnyAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (predicate == null)
  			{
  				throw new ArgumentNullException(nameof(predicate));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<bool>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AnyWithPredicateDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(predicate) };
  				return provider.ExecuteAsync<bool>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<bool>(ex);
  			}
  		}
  
  		#endregion
  
  		#region AllAsync
  
  		/// <summary>Determines whether all elements of a sequence satisfies a condition.</summary>
  		/// <param name="source">A sequence whose elements to test for a condition.</param>
  		/// <param name="predicate">A function to test each element for a condition.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
  		/// <returns>true if all elements in the source sequence pass the test in the specified predicate; otherwise, false.</returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> or <paramref name="predicate" /> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<bool> AllAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (predicate == null)
  			{
  				throw new ArgumentNullException(nameof(predicate));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<bool>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AllDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(predicate) };
  				return provider.ExecuteAsync<bool>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<bool>(ex);
  			}
  		}
  
  		#endregion
  
  		#region CountAsync
  
  		/// <summary>Returns the number of elements in a sequence.</summary>
  		/// <param name="source">The <see cref="T:System.Linq.IQueryable`1" /> that contains the elements to be counted.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
  		/// <returns>The number of elements in the input sequence.</returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The number of elements in <paramref name="source" /> is larger than <see cref="F:System.Int32.MaxValue" />.</exception>
  		public static Task<int> CountAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<int>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.CountDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<int>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<int>(ex);
  			}
  		}
  
  		/// <summary>Returns the number of elements in the specified sequence that satisfies a condition.</summary>
  		/// <param name="source">An <see cref="T:System.Linq.IQueryable`1" /> that contains the elements to be counted.</param>
  		/// <param name="predicate">A function to test each element for a condition.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
  		/// <returns>The number of elements in the sequence that satisfies the condition in the predicate function.</returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> or <paramref name="predicate" /> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The number of elements in <paramref name="source" /> is larger than <see cref="F:System.Int32.MaxValue" />.</exception>
  		public static Task<int> CountAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (predicate == null)
  			{
  				throw new ArgumentNullException(nameof(predicate));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<int>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.CountWithPredicateDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(predicate) };
  				return provider.ExecuteAsync<int>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<int>(ex);
  			}
  		}
  
  		#endregion
  
  		#region SumAsync
  
  		/// <summary>
  		/// Computes the sum of a sequence of <see cref="T:System.Int32"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of <see cref="T:System.Int32"/> values to calculate the sum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The sum of the values in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Int32.MaxValue"/>.</exception>
  		public static Task<int> SumAsync(this IQueryable<int> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<int>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumOfInt;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<int>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<int>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of a sequence of nullable <see cref="T:System.Int32"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of nullable <see cref="T:System.Int32"/> values to calculate the sum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The sum of the values in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Int32.MaxValue"/>.</exception>
  		public static Task<int?> SumAsync(this IQueryable<int?> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<int?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumOfNullableInt;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<int?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<int?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of a sequence of <see cref="T:System.Int64"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of <see cref="T:System.Int64"/> values to calculate the sum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The sum of the values in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Int64.MaxValue"/>.</exception>
  		public static Task<long> SumAsync(this IQueryable<long> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<long>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumOfLong;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<long>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<long>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of a sequence of nullable <see cref="T:System.Int64"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of nullable <see cref="T:System.Int64"/> values to calculate the sum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The sum of the values in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Int64.MaxValue"/>.</exception>
  		public static Task<long?> SumAsync(this IQueryable<long?> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<long?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumOfNullableLong;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<long?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<long?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of a sequence of <see cref="T:System.Single"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of <see cref="T:System.Single"/> values to calculate the sum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The sum of the values in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Single.MaxValue"/>.</exception>
  		public static Task<float> SumAsync(this IQueryable<float> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<float>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumOfFloat;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<float>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<float>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of a sequence of nullable <see cref="T:System.Single"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of nullable <see cref="T:System.Single"/> values to calculate the sum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The sum of the values in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Single.MaxValue"/>.</exception>
  		public static Task<float?> SumAsync(this IQueryable<float?> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<float?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumOfNullableFloat;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<float?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<float?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of a sequence of <see cref="T:System.Double"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of <see cref="T:System.Double"/> values to calculate the sum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The sum of the values in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Double.MaxValue"/>.</exception>
  		public static Task<double> SumAsync(this IQueryable<double> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumOfDouble;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<double>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of a sequence of nullable <see cref="T:System.Double"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of nullable <see cref="T:System.Double"/> values to calculate the sum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The sum of the values in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Double.MaxValue"/>.</exception>
  		public static Task<double?> SumAsync(this IQueryable<double?> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumOfNullableDouble;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<double?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of a sequence of <see cref="T:System.Decimal"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of <see cref="T:System.Decimal"/> values to calculate the sum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The sum of the values in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Decimal.MaxValue"/>.</exception>
  		public static Task<decimal> SumAsync(this IQueryable<decimal> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<decimal>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumOfDecimal;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<decimal>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<decimal>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of a sequence of nullable <see cref="T:System.Decimal"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of nullable <see cref="T:System.Decimal"/> values to calculate the sum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The sum of the values in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Decimal.MaxValue"/>.</exception>
  		public static Task<decimal?> SumAsync(this IQueryable<decimal?> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<decimal?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumOfNullableDecimal;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<decimal?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<decimal?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of the sequence of <see cref="T:System.Int32"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values of type <paramref name="source"/>.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The sum of the projected values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Int32.MaxValue"/>.</exception>
  		public static Task<int> SumAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, int>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<int>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumWithSelectorOfIntDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<int>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<int>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of the sequence of nullable <see cref="T:System.Int32"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values of type <paramref name="source"/>.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The sum of the projected values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Int32.MaxValue"/>.</exception>
  		public static Task<int?> SumAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, int?>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<int?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumWithSelectorOfNullableIntDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<int?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<int?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of the sequence of <see cref="T:System.Int64"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values of type <paramref name="source"/>.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The sum of the projected values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Int64.MaxValue"/>.</exception>
  		public static Task<long> SumAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, long>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<long>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumWithSelectorOfLongDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<long>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<long>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of the sequence of nullable <see cref="T:System.Int64"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values of type <paramref name="source"/>.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The sum of the projected values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Int64.MaxValue"/>.</exception>
  		public static Task<long?> SumAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, long?>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<long?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumWithSelectorOfNullableLongDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<long?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<long?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of the sequence of <see cref="T:System.Single"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values of type <paramref name="source"/>.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The sum of the projected values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Single.MaxValue"/>.</exception>
  		public static Task<float> SumAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, float>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<float>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumWithSelectorOfFloatDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<float>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<float>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of the sequence of nullable <see cref="T:System.Single"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values of type <paramref name="source"/>.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The sum of the projected values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Single.MaxValue"/>.</exception>
  		public static Task<float?> SumAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, float?>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<float?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumWithSelectorOfNullableFloatDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<float?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<float?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of the sequence of <see cref="T:System.Double"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values of type <paramref name="source"/>.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The sum of the projected values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Double.MaxValue"/>.</exception>
  		public static Task<double> SumAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, double>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumWithSelectorOfDoubleDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<double>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of the sequence of nullable <see cref="T:System.Double"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values of type <paramref name="source"/>.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The sum of the projected values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Double.MaxValue"/>.</exception>
  		public static Task<double?> SumAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, double?>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumWithSelectorOfNullableDoubleDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<double?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of the sequence of <see cref="T:System.Decimal"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values of type <paramref name="source"/>.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The sum of the projected values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Decimal.MaxValue"/>.</exception>
  		public static Task<decimal> SumAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, decimal>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<decimal>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumWithSelectorOfDecimalDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<decimal>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<decimal>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the sum of the sequence of nullable <see cref="T:System.Decimal"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values of type <paramref name="source"/>.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The sum of the projected values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The sum is larger than <see cref="F:System.Decimal.MaxValue"/>.</exception>
  		public static Task<decimal?> SumAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, decimal?>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<decimal?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.SumWithSelectorOfNullableDecimalDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<decimal?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<decimal?>(ex);
  			}
  		}
  
  		#endregion
  
  		#region Average
  
  		/// <summary>
  		/// Computes the average of a sequence of <see cref="T:System.Int32"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of <see cref="T:System.Int32"/> values to calculate the average of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The average of the sequence of values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException"><paramref name="source"/> contains no elements.</exception>
  		public static Task<double> AverageAsync(this IQueryable<int> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageOfInt;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<double>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of nullable <see cref="T:System.Int32"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of nullable <see cref="T:System.Int32"/> values to calculate the average of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The average of the sequence of values, or <see langword="null"/> if the source sequence is empty or contains only <see langword="null"/> values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<double?> AverageAsync(this IQueryable<int?> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageOfNullableInt;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<double?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of <see cref="T:System.Int64"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of <see cref="T:System.Int64"/> values to calculate the average of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The average of the sequence of values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException"><paramref name="source"/> contains no elements.</exception>
  		public static Task<double> AverageAsync(this IQueryable<long> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageOfLong;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<double>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of nullable <see cref="T:System.Int64"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of nullable <see cref="T:System.Int64"/> values to calculate the average of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The average of the sequence of values, or <see langword="null"/> if the source sequence is empty or contains only <see langword="null"/> values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<double?> AverageAsync(this IQueryable<long?> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageOfNullableLong;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<double?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of <see cref="T:System.Single"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of <see cref="T:System.Single"/> values to calculate the average of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The average of the sequence of values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException"><paramref name="source"/> contains no elements.</exception>
  		public static Task<float> AverageAsync(this IQueryable<float> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<float>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageOfFloat;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<float>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<float>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of nullable <see cref="T:System.Single"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of nullable <see cref="T:System.Single"/> values to calculate the average of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The average of the sequence of values, or <see langword="null"/> if the source sequence is empty or contains only <see langword="null"/> values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<float?> AverageAsync(this IQueryable<float?> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<float?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageOfNullableFloat;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<float?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<float?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of <see cref="T:System.Double"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of <see cref="T:System.Double"/> values to calculate the average of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The average of the sequence of values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException"><paramref name="source"/> contains no elements.</exception>
  		public static Task<double> AverageAsync(this IQueryable<double> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageOfDouble;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<double>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of nullable <see cref="T:System.Double"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of nullable <see cref="T:System.Double"/> values to calculate the average of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The average of the sequence of values, or <see langword="null"/> if the source sequence is empty or contains only <see langword="null"/> values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<double?> AverageAsync(this IQueryable<double?> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageOfNullableDouble;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<double?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of <see cref="T:System.Decimal"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of <see cref="T:System.Decimal"/> values to calculate the average of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The average of the sequence of values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException"><paramref name="source"/> contains no elements.</exception>
  		public static Task<decimal> AverageAsync(this IQueryable<decimal> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<decimal>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageOfDecimal;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<decimal>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<decimal>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of nullable <see cref="T:System.Decimal"/> values.
  		/// </summary>
  		/// <param name="source">A sequence of nullable <see cref="T:System.Decimal"/> values to calculate the average of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <returns>
  		/// The average of the sequence of values, or <see langword="null"/> if the source sequence is empty or contains only <see langword="null"/> values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<decimal?> AverageAsync(this IQueryable<decimal?> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<decimal?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageOfNullableDecimal;
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<decimal?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<decimal?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of <see cref="T:System.Int32"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values to calculate the average of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The average of the sequence of values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException"><paramref name="source"/> contains no elements.</exception>
  		public static Task<double> AverageAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, int>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageWithSelectorOfIntDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<double>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of nullable <see cref="T:System.Int32"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values to calculate the average of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The average of the sequence of values, or <see langword="null"/> if the <paramref name="source"/> sequence is empty or contains only <see langword="null"/> values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<double?> AverageAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, int?>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageWithSelectorOfNullableIntDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<double?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of <see cref="T:System.Int64"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values to calculate the average of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The average of the sequence of values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException"><paramref name="source"/> contains no elements.</exception>
  		public static Task<double> AverageAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, long>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageWithSelectorOfLongDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<double>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of nullable <see cref="T:System.Int64"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values to calculate the average of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The average of the sequence of values, or <see langword="null"/> if the <paramref name="source"/> sequence is empty or contains only <see langword="null"/> values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<double?> AverageAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, long?>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageWithSelectorOfNullableLongDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<double?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of <see cref="T:System.Single"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values to calculate the average of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The average of the sequence of values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException"><paramref name="source"/> contains no elements.</exception>
  		public static Task<float> AverageAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, float>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<float>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageWithSelectorOfFloatDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<float>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<float>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of nullable <see cref="T:System.Single"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values to calculate the average of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The average of the sequence of values, or <see langword="null"/> if the <paramref name="source"/> sequence is empty or contains only <see langword="null"/> values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<float?> AverageAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, float?>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<float?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageWithSelectorOfNullableFloatDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<float?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<float?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of <see cref="T:System.Double"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values to calculate the average of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The average of the sequence of values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException"><paramref name="source"/> contains no elements.</exception>
  		public static Task<double> AverageAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, double>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageWithSelectorOfDoubleDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<double>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of nullable <see cref="T:System.Double"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values to calculate the average of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The average of the sequence of values, or <see langword="null"/> if the <paramref name="source"/> sequence is empty or contains only <see langword="null"/> values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<double?> AverageAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, double?>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<double?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageWithSelectorOfNullableDoubleDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<double?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<double?>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of <see cref="T:System.Decimal"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values to calculate the average of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The average of the sequence of values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException"><paramref name="source"/> contains no elements.</exception>
  		public static Task<decimal> AverageAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, decimal>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<decimal>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageWithSelectorOfDecimalDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<decimal>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<decimal>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Computes the average of a sequence of nullable <see cref="T:System.Decimal"/> values that is obtained by invoking a projection function on each element of the input sequence.
  		/// </summary>
  		/// <param name="source">A sequence of values to calculate the average of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The average of the sequence of values, or <see langword="null"/> if the <paramref name="source"/> sequence is empty or contains only <see langword="null"/> values.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<decimal?> AverageAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, decimal?>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<decimal?>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.AverageWithSelectorOfNullableDecimalDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<decimal?>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<decimal?>(ex);
  			}
  		}
  
  		#endregion
  
  		#region MinAsync
  
  		/// <summary>
  		/// Returns the minimum value of a generic <see cref="T:System.Linq.IQueryable`1"/>.
  		/// </summary>
  		/// <param name="source">A sequence of values to determine the minimum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The minimum value in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<TSource> MinAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<TSource>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.MinDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<TSource>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<TSource>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Invokes a projection function on each element of a generic <see cref="T:System.Linq.IQueryable`1"/> and returns the minimum resulting value.
  		/// </summary>
  		/// <param name="source">A sequence of values to determine the minimum of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <typeparam name="TResult">The type of the value returned by the function represented by <paramref name="selector"/>.</typeparam>
  		/// <returns>
  		/// The minimum value in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<TResult> MinAsync<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<TResult>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.MinWithSelectorDefinition.MakeGenericMethod(typeof(TSource), typeof(TResult));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<TResult>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<TResult>(ex);
  			}
  		}
  
  		#endregion
  
  		#region MaxAsync
  
  		/// <summary>
  		/// Returns the maximum value in a generic <see cref="T:System.Linq.IQueryable`1"/>.
  		/// </summary>
  		/// <param name="source">A sequence of values to determine the maximum of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <returns>
  		/// The maximum value in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		public static Task<TSource> MaxAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<TSource>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.MaxDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<TSource>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<TSource>(ex);
  			}
  		}
  
  		/// <summary>
  		/// Invokes a projection function on each element of a generic <see cref="T:System.Linq.IQueryable`1"/> and returns the maximum resulting value.
  		/// </summary>
  		/// <param name="source">A sequence of values to determine the maximum of.</param>
  		/// <param name="selector">A projection function to apply to each element.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam>
  		/// <typeparam name="TResult">The type of the value returned by the function represented by <paramref name="selector"/>.</typeparam>
  		/// <returns>
  		/// The maximum value in the sequence.
  		/// </returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  		public static Task<TResult> MaxAsync<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<TSource, TResult>> selector, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (selector == null)
  			{
  				throw new ArgumentNullException(nameof(selector));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<TResult>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.MaxWithSelectorDefinition.MakeGenericMethod(typeof(TSource), typeof(TResult));
  				var expression = new[] { source.Expression, Expression.Quote(selector) };
  				return provider.ExecuteAsync<TResult>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<TResult>(ex);
  			}
  		}
  
  		#endregion
  
  		#region LongCountAsync
  
  		/// <summary>Returns the number of elements in a sequence.</summary>
  		/// <param name="source">The <see cref="T:System.Linq.IQueryable`1" /> that contains the elements to be counted.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
  		/// <returns>The number of elements in the input sequence.</returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The number of elements in <paramref name="source" /> is larger than <see cref="F:System.Int64.MaxValue" />.</exception>
  		public static Task<long> LongCountAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<long>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.LongCountDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression };
  				return provider.ExecuteAsync<long>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<long>(ex);
  			}
  		}
  
  		/// <summary>Returns the number of elements in the specified sequence that satisfies a condition.</summary>
  		/// <param name="source">An <see cref="T:System.Linq.IQueryable`1" /> that contains the elements to be counted.</param>
  		/// <param name="predicate">A function to test each element for a condition.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
  		/// <returns>The number of elements in the sequence that satisfies the condition in the predicate function.</returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> or <paramref name="predicate" /> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.OverflowException">The number of elements in <paramref name="source" /> is larger than <see cref="F:System.Int64.MaxValue" />.</exception>
  		public static Task<long> LongCountAsync<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  				throw new ArgumentNullException(nameof(source));
  			}
  			if (predicate == null)
  			{
  				throw new ArgumentNullException(nameof(predicate));
  			}
  			if (!(source.Provider is INhQueryProvider provider))
  			{
  				throw new NotSupportedException($"Source {nameof(source.Provider)} must be a {nameof(INhQueryProvider)}");
  			}
  			if (cancellationToken.IsCancellationRequested)
  			{
  				return Task.FromCanceled<long>(cancellationToken);
  			}
  			try
  			{
  				var methodInfo = ReflectionCache.QueryableMethods.LongCountWithPredicateDefinition.MakeGenericMethod(typeof(TSource));
  				var expression = new[] { source.Expression, Expression.Quote(predicate) };
  				return provider.ExecuteAsync<long>(Expression.Call(null, methodInfo, expression), cancellationToken);
  			}
  			catch (Exception ex)
  			{
  				return Task.FromException<long>(ex);
  			}
  		}
  
  		#endregion
  
  		#region FirstAsync
  
  		/// <summary>Returns the first element of a sequence.</summary>
  		/// <param name="source">The <see cref="T:System.Linq.IQueryable`1" /> to return the first element of.</param>
  		/// <param name="cancellationToken">A cancellation token that can be used to cancel the work.</param>
  		/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
  		/// <returns>The first element in <paramref name="source" />.</returns>
  		/// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> is <see langword="null"/>.</exception>
  		/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
  		/// <exception cref="T:System.InvalidOperationException">The source sequence is empty.</exception>
  		public static Task<TSource> FirstAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default(CancellationToken))
  		{
  			if (source == null)
  			{
  
gt: 				throw new ArgumentNullException(nameof(source));