using System;
using System.Linq.Expressions;
using System.Reactive.Linq;
using System.Reflection;

namespace System.Reactive.Joins
{
	public class QueryablePattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, T, U, V> : QueryablePattern
	{
		internal QueryablePattern(Expression expression)
			: base(expression)
		{
		}

		public QueryablePattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, T, U, V, W> And<W>(IObservable<W> other)
		{
			if (other == null)
			{
				throw new ArgumentNullException("other");
			}
			MethodInfo methodInfo = typeof(QueryablePattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, T, U, V>).GetMethod("And").MakeGenericMethod(new Type[] { typeof(W) });
			return new QueryablePattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, T, U, V, W>(Expression.Call(base.Expression, methodInfo, new Expression[] { Qbservable.GetSourceExpression<W>(other) }));
		}

		public QueryablePlan<TResult> Then<TResult>(Expression<Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, T, U, V, TResult>> selector)
		{
			if (selector == null)
			{
				throw new ArgumentNullException("selector");
			}
			MethodInfo methodInfo = typeof(QueryablePattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, T, U, V>).GetMethod("Then").MakeGenericMethod(new Type[] { typeof(TResult) });
			return new QueryablePlan<TResult>(Expression.Call(base.Expression, methodInfo, new Expression[] { selector }));
		}
	}
}
