瀏覽代碼

Adding join patterns.

Bart De Smet 8 年之前
父節點
當前提交
38aefd618b

+ 0 - 4
AsyncRx.NET/ApiCompare/Program.cs

@@ -23,10 +23,6 @@ namespace ApiCompare
 
                 "Subscribe",  // Trivially renamed to SubscribeAsync.
 
-                "And",   // Postponing patterns.
-                "Then",  // Postponing patterns.
-                "When",  // Postponing patterns.
-
                 "If",       // Postponing imperative operators.
                 "DoWhile",  // Postponing imperative operators.
                 "Case",     // Postponing imperative operators.

+ 27 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System.Reactive.Async.Linq.csproj

@@ -23,6 +23,21 @@
   </ItemGroup>
 
   <ItemGroup>
+    <Compile Update="System\Reactive\Joins\ActiveAsyncPlan.Generated.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>ActiveAsyncPlan.Generated.tt</DependentUpon>
+    </Compile>
+    <Compile Update="System\Reactive\Joins\AsyncPattern.Generated.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>AsyncPattern.Generated.tt</DependentUpon>
+    </Compile>
+    <Compile Update="System\Reactive\Joins\AsyncPlan.Generated.cs">
+      <DesignTime>True</DesignTime>
+      <AutoGen>True</AutoGen>
+      <DependentUpon>AsyncPlan.Generated.tt</DependentUpon>
+    </Compile>
     <Compile Update="System\Reactive\Linq\Operators\Average.Generated.cs">
       <DependentUpon>Average.Generated.tt</DependentUpon>
       <DesignTime>True</DesignTime>
@@ -71,6 +86,18 @@
   </ItemGroup>
 
   <ItemGroup>
+    <None Update="System\Reactive\Joins\ActiveAsyncPlan.Generated.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>ActiveAsyncPlan.Generated.cs</LastGenOutput>
+    </None>
+    <None Update="System\Reactive\Joins\AsyncPattern.Generated.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>AsyncPattern.Generated.cs</LastGenOutput>
+    </None>
+    <None Update="System\Reactive\Joins\AsyncPlan.Generated.tt">
+      <Generator>TextTemplatingFileGenerator</Generator>
+      <LastGenOutput>AsyncPlan.Generated.cs</LastGenOutput>
+    </None>
     <None Update="System\Reactive\Linq\Operators\Average.Generated.tt">
       <LastGenOutput>Average.Generated.cs</LastGenOutput>
       <Generator>TextTemplatingFileGenerator</Generator>

+ 1081 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/ActiveAsyncPlan.Generated.cs

@@ -0,0 +1,1081 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System.Threading.Tasks;
+
+namespace System.Reactive.Joins
+{
+    internal sealed class ActiveAsyncPlan<TSource1> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, Func<TSource1, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+
+            AddJoinObserver(observer1);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, Func<TSource1, TSource2, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, Func<TSource1, TSource2, TSource3, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, Func<TSource1, TSource2, TSource3, TSource4, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, Func<TSource1, TSource2, TSource3, TSource4, TSource5, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+        private readonly AsyncJoinObserver<TSource7> _observer7;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, AsyncJoinObserver<TSource7> observer7, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+            _observer7 = observer7;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+            AddJoinObserver(observer7);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0 && _observer7.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+                var notification7 = _observer7.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted || notification7.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value, notification7.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+        private readonly AsyncJoinObserver<TSource7> _observer7;
+        private readonly AsyncJoinObserver<TSource8> _observer8;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, AsyncJoinObserver<TSource7> observer7, AsyncJoinObserver<TSource8> observer8, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+            _observer7 = observer7;
+            _observer8 = observer8;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+            AddJoinObserver(observer7);
+            AddJoinObserver(observer8);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0 && _observer7.Queue.Count > 0 && _observer8.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+                var notification7 = _observer7.Queue.Peek();
+                var notification8 = _observer8.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted || notification7.Kind == NotificationKind.OnCompleted || notification8.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value, notification7.Value, notification8.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+        private readonly AsyncJoinObserver<TSource7> _observer7;
+        private readonly AsyncJoinObserver<TSource8> _observer8;
+        private readonly AsyncJoinObserver<TSource9> _observer9;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, AsyncJoinObserver<TSource7> observer7, AsyncJoinObserver<TSource8> observer8, AsyncJoinObserver<TSource9> observer9, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+            _observer7 = observer7;
+            _observer8 = observer8;
+            _observer9 = observer9;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+            AddJoinObserver(observer7);
+            AddJoinObserver(observer8);
+            AddJoinObserver(observer9);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0 && _observer7.Queue.Count > 0 && _observer8.Queue.Count > 0 && _observer9.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+                var notification7 = _observer7.Queue.Peek();
+                var notification8 = _observer8.Queue.Peek();
+                var notification9 = _observer9.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted || notification7.Kind == NotificationKind.OnCompleted || notification8.Kind == NotificationKind.OnCompleted || notification9.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value, notification7.Value, notification8.Value, notification9.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+        private readonly AsyncJoinObserver<TSource7> _observer7;
+        private readonly AsyncJoinObserver<TSource8> _observer8;
+        private readonly AsyncJoinObserver<TSource9> _observer9;
+        private readonly AsyncJoinObserver<TSource10> _observer10;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, AsyncJoinObserver<TSource7> observer7, AsyncJoinObserver<TSource8> observer8, AsyncJoinObserver<TSource9> observer9, AsyncJoinObserver<TSource10> observer10, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+            _observer7 = observer7;
+            _observer8 = observer8;
+            _observer9 = observer9;
+            _observer10 = observer10;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+            AddJoinObserver(observer7);
+            AddJoinObserver(observer8);
+            AddJoinObserver(observer9);
+            AddJoinObserver(observer10);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0 && _observer7.Queue.Count > 0 && _observer8.Queue.Count > 0 && _observer9.Queue.Count > 0 && _observer10.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+                var notification7 = _observer7.Queue.Peek();
+                var notification8 = _observer8.Queue.Peek();
+                var notification9 = _observer9.Queue.Peek();
+                var notification10 = _observer10.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted || notification7.Kind == NotificationKind.OnCompleted || notification8.Kind == NotificationKind.OnCompleted || notification9.Kind == NotificationKind.OnCompleted || notification10.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value, notification7.Value, notification8.Value, notification9.Value, notification10.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+        private readonly AsyncJoinObserver<TSource7> _observer7;
+        private readonly AsyncJoinObserver<TSource8> _observer8;
+        private readonly AsyncJoinObserver<TSource9> _observer9;
+        private readonly AsyncJoinObserver<TSource10> _observer10;
+        private readonly AsyncJoinObserver<TSource11> _observer11;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, AsyncJoinObserver<TSource7> observer7, AsyncJoinObserver<TSource8> observer8, AsyncJoinObserver<TSource9> observer9, AsyncJoinObserver<TSource10> observer10, AsyncJoinObserver<TSource11> observer11, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+            _observer7 = observer7;
+            _observer8 = observer8;
+            _observer9 = observer9;
+            _observer10 = observer10;
+            _observer11 = observer11;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+            AddJoinObserver(observer7);
+            AddJoinObserver(observer8);
+            AddJoinObserver(observer9);
+            AddJoinObserver(observer10);
+            AddJoinObserver(observer11);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0 && _observer7.Queue.Count > 0 && _observer8.Queue.Count > 0 && _observer9.Queue.Count > 0 && _observer10.Queue.Count > 0 && _observer11.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+                var notification7 = _observer7.Queue.Peek();
+                var notification8 = _observer8.Queue.Peek();
+                var notification9 = _observer9.Queue.Peek();
+                var notification10 = _observer10.Queue.Peek();
+                var notification11 = _observer11.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted || notification7.Kind == NotificationKind.OnCompleted || notification8.Kind == NotificationKind.OnCompleted || notification9.Kind == NotificationKind.OnCompleted || notification10.Kind == NotificationKind.OnCompleted || notification11.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value, notification7.Value, notification8.Value, notification9.Value, notification10.Value, notification11.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+        private readonly AsyncJoinObserver<TSource7> _observer7;
+        private readonly AsyncJoinObserver<TSource8> _observer8;
+        private readonly AsyncJoinObserver<TSource9> _observer9;
+        private readonly AsyncJoinObserver<TSource10> _observer10;
+        private readonly AsyncJoinObserver<TSource11> _observer11;
+        private readonly AsyncJoinObserver<TSource12> _observer12;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, AsyncJoinObserver<TSource7> observer7, AsyncJoinObserver<TSource8> observer8, AsyncJoinObserver<TSource9> observer9, AsyncJoinObserver<TSource10> observer10, AsyncJoinObserver<TSource11> observer11, AsyncJoinObserver<TSource12> observer12, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+            _observer7 = observer7;
+            _observer8 = observer8;
+            _observer9 = observer9;
+            _observer10 = observer10;
+            _observer11 = observer11;
+            _observer12 = observer12;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+            AddJoinObserver(observer7);
+            AddJoinObserver(observer8);
+            AddJoinObserver(observer9);
+            AddJoinObserver(observer10);
+            AddJoinObserver(observer11);
+            AddJoinObserver(observer12);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0 && _observer7.Queue.Count > 0 && _observer8.Queue.Count > 0 && _observer9.Queue.Count > 0 && _observer10.Queue.Count > 0 && _observer11.Queue.Count > 0 && _observer12.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+                var notification7 = _observer7.Queue.Peek();
+                var notification8 = _observer8.Queue.Peek();
+                var notification9 = _observer9.Queue.Peek();
+                var notification10 = _observer10.Queue.Peek();
+                var notification11 = _observer11.Queue.Peek();
+                var notification12 = _observer12.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted || notification7.Kind == NotificationKind.OnCompleted || notification8.Kind == NotificationKind.OnCompleted || notification9.Kind == NotificationKind.OnCompleted || notification10.Kind == NotificationKind.OnCompleted || notification11.Kind == NotificationKind.OnCompleted || notification12.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value, notification7.Value, notification8.Value, notification9.Value, notification10.Value, notification11.Value, notification12.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+        private readonly AsyncJoinObserver<TSource7> _observer7;
+        private readonly AsyncJoinObserver<TSource8> _observer8;
+        private readonly AsyncJoinObserver<TSource9> _observer9;
+        private readonly AsyncJoinObserver<TSource10> _observer10;
+        private readonly AsyncJoinObserver<TSource11> _observer11;
+        private readonly AsyncJoinObserver<TSource12> _observer12;
+        private readonly AsyncJoinObserver<TSource13> _observer13;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, AsyncJoinObserver<TSource7> observer7, AsyncJoinObserver<TSource8> observer8, AsyncJoinObserver<TSource9> observer9, AsyncJoinObserver<TSource10> observer10, AsyncJoinObserver<TSource11> observer11, AsyncJoinObserver<TSource12> observer12, AsyncJoinObserver<TSource13> observer13, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+            _observer7 = observer7;
+            _observer8 = observer8;
+            _observer9 = observer9;
+            _observer10 = observer10;
+            _observer11 = observer11;
+            _observer12 = observer12;
+            _observer13 = observer13;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+            AddJoinObserver(observer7);
+            AddJoinObserver(observer8);
+            AddJoinObserver(observer9);
+            AddJoinObserver(observer10);
+            AddJoinObserver(observer11);
+            AddJoinObserver(observer12);
+            AddJoinObserver(observer13);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0 && _observer7.Queue.Count > 0 && _observer8.Queue.Count > 0 && _observer9.Queue.Count > 0 && _observer10.Queue.Count > 0 && _observer11.Queue.Count > 0 && _observer12.Queue.Count > 0 && _observer13.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+                var notification7 = _observer7.Queue.Peek();
+                var notification8 = _observer8.Queue.Peek();
+                var notification9 = _observer9.Queue.Peek();
+                var notification10 = _observer10.Queue.Peek();
+                var notification11 = _observer11.Queue.Peek();
+                var notification12 = _observer12.Queue.Peek();
+                var notification13 = _observer13.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted || notification7.Kind == NotificationKind.OnCompleted || notification8.Kind == NotificationKind.OnCompleted || notification9.Kind == NotificationKind.OnCompleted || notification10.Kind == NotificationKind.OnCompleted || notification11.Kind == NotificationKind.OnCompleted || notification12.Kind == NotificationKind.OnCompleted || notification13.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value, notification7.Value, notification8.Value, notification9.Value, notification10.Value, notification11.Value, notification12.Value, notification13.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+        private readonly AsyncJoinObserver<TSource7> _observer7;
+        private readonly AsyncJoinObserver<TSource8> _observer8;
+        private readonly AsyncJoinObserver<TSource9> _observer9;
+        private readonly AsyncJoinObserver<TSource10> _observer10;
+        private readonly AsyncJoinObserver<TSource11> _observer11;
+        private readonly AsyncJoinObserver<TSource12> _observer12;
+        private readonly AsyncJoinObserver<TSource13> _observer13;
+        private readonly AsyncJoinObserver<TSource14> _observer14;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, AsyncJoinObserver<TSource7> observer7, AsyncJoinObserver<TSource8> observer8, AsyncJoinObserver<TSource9> observer9, AsyncJoinObserver<TSource10> observer10, AsyncJoinObserver<TSource11> observer11, AsyncJoinObserver<TSource12> observer12, AsyncJoinObserver<TSource13> observer13, AsyncJoinObserver<TSource14> observer14, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+            _observer7 = observer7;
+            _observer8 = observer8;
+            _observer9 = observer9;
+            _observer10 = observer10;
+            _observer11 = observer11;
+            _observer12 = observer12;
+            _observer13 = observer13;
+            _observer14 = observer14;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+            AddJoinObserver(observer7);
+            AddJoinObserver(observer8);
+            AddJoinObserver(observer9);
+            AddJoinObserver(observer10);
+            AddJoinObserver(observer11);
+            AddJoinObserver(observer12);
+            AddJoinObserver(observer13);
+            AddJoinObserver(observer14);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0 && _observer7.Queue.Count > 0 && _observer8.Queue.Count > 0 && _observer9.Queue.Count > 0 && _observer10.Queue.Count > 0 && _observer11.Queue.Count > 0 && _observer12.Queue.Count > 0 && _observer13.Queue.Count > 0 && _observer14.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+                var notification7 = _observer7.Queue.Peek();
+                var notification8 = _observer8.Queue.Peek();
+                var notification9 = _observer9.Queue.Peek();
+                var notification10 = _observer10.Queue.Peek();
+                var notification11 = _observer11.Queue.Peek();
+                var notification12 = _observer12.Queue.Peek();
+                var notification13 = _observer13.Queue.Peek();
+                var notification14 = _observer14.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted || notification7.Kind == NotificationKind.OnCompleted || notification8.Kind == NotificationKind.OnCompleted || notification9.Kind == NotificationKind.OnCompleted || notification10.Kind == NotificationKind.OnCompleted || notification11.Kind == NotificationKind.OnCompleted || notification12.Kind == NotificationKind.OnCompleted || notification13.Kind == NotificationKind.OnCompleted || notification14.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value, notification7.Value, notification8.Value, notification9.Value, notification10.Value, notification11.Value, notification12.Value, notification13.Value, notification14.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+        private readonly AsyncJoinObserver<TSource7> _observer7;
+        private readonly AsyncJoinObserver<TSource8> _observer8;
+        private readonly AsyncJoinObserver<TSource9> _observer9;
+        private readonly AsyncJoinObserver<TSource10> _observer10;
+        private readonly AsyncJoinObserver<TSource11> _observer11;
+        private readonly AsyncJoinObserver<TSource12> _observer12;
+        private readonly AsyncJoinObserver<TSource13> _observer13;
+        private readonly AsyncJoinObserver<TSource14> _observer14;
+        private readonly AsyncJoinObserver<TSource15> _observer15;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, AsyncJoinObserver<TSource7> observer7, AsyncJoinObserver<TSource8> observer8, AsyncJoinObserver<TSource9> observer9, AsyncJoinObserver<TSource10> observer10, AsyncJoinObserver<TSource11> observer11, AsyncJoinObserver<TSource12> observer12, AsyncJoinObserver<TSource13> observer13, AsyncJoinObserver<TSource14> observer14, AsyncJoinObserver<TSource15> observer15, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+            _observer7 = observer7;
+            _observer8 = observer8;
+            _observer9 = observer9;
+            _observer10 = observer10;
+            _observer11 = observer11;
+            _observer12 = observer12;
+            _observer13 = observer13;
+            _observer14 = observer14;
+            _observer15 = observer15;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+            AddJoinObserver(observer7);
+            AddJoinObserver(observer8);
+            AddJoinObserver(observer9);
+            AddJoinObserver(observer10);
+            AddJoinObserver(observer11);
+            AddJoinObserver(observer12);
+            AddJoinObserver(observer13);
+            AddJoinObserver(observer14);
+            AddJoinObserver(observer15);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0 && _observer7.Queue.Count > 0 && _observer8.Queue.Count > 0 && _observer9.Queue.Count > 0 && _observer10.Queue.Count > 0 && _observer11.Queue.Count > 0 && _observer12.Queue.Count > 0 && _observer13.Queue.Count > 0 && _observer14.Queue.Count > 0 && _observer15.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+                var notification7 = _observer7.Queue.Peek();
+                var notification8 = _observer8.Queue.Peek();
+                var notification9 = _observer9.Queue.Peek();
+                var notification10 = _observer10.Queue.Peek();
+                var notification11 = _observer11.Queue.Peek();
+                var notification12 = _observer12.Queue.Peek();
+                var notification13 = _observer13.Queue.Peek();
+                var notification14 = _observer14.Queue.Peek();
+                var notification15 = _observer15.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted || notification7.Kind == NotificationKind.OnCompleted || notification8.Kind == NotificationKind.OnCompleted || notification9.Kind == NotificationKind.OnCompleted || notification10.Kind == NotificationKind.OnCompleted || notification11.Kind == NotificationKind.OnCompleted || notification12.Kind == NotificationKind.OnCompleted || notification13.Kind == NotificationKind.OnCompleted || notification14.Kind == NotificationKind.OnCompleted || notification15.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value, notification7.Value, notification8.Value, notification9.Value, notification10.Value, notification11.Value, notification12.Value, notification13.Value, notification14.Value, notification15.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+    internal sealed class ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16> : ActiveAsyncPlan
+    {
+        private readonly Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+        private readonly AsyncJoinObserver<TSource1> _observer1;
+        private readonly AsyncJoinObserver<TSource2> _observer2;
+        private readonly AsyncJoinObserver<TSource3> _observer3;
+        private readonly AsyncJoinObserver<TSource4> _observer4;
+        private readonly AsyncJoinObserver<TSource5> _observer5;
+        private readonly AsyncJoinObserver<TSource6> _observer6;
+        private readonly AsyncJoinObserver<TSource7> _observer7;
+        private readonly AsyncJoinObserver<TSource8> _observer8;
+        private readonly AsyncJoinObserver<TSource9> _observer9;
+        private readonly AsyncJoinObserver<TSource10> _observer10;
+        private readonly AsyncJoinObserver<TSource11> _observer11;
+        private readonly AsyncJoinObserver<TSource12> _observer12;
+        private readonly AsyncJoinObserver<TSource13> _observer13;
+        private readonly AsyncJoinObserver<TSource14> _observer14;
+        private readonly AsyncJoinObserver<TSource15> _observer15;
+        private readonly AsyncJoinObserver<TSource16> _observer16;
+
+        internal ActiveAsyncPlan(AsyncJoinObserver<TSource1> observer1, AsyncJoinObserver<TSource2> observer2, AsyncJoinObserver<TSource3> observer3, AsyncJoinObserver<TSource4> observer4, AsyncJoinObserver<TSource5> observer5, AsyncJoinObserver<TSource6> observer6, AsyncJoinObserver<TSource7> observer7, AsyncJoinObserver<TSource8> observer8, AsyncJoinObserver<TSource9> observer9, AsyncJoinObserver<TSource10> observer10, AsyncJoinObserver<TSource11> observer11, AsyncJoinObserver<TSource12> observer12, AsyncJoinObserver<TSource13> observer13, AsyncJoinObserver<TSource14> observer14, AsyncJoinObserver<TSource15> observer15, AsyncJoinObserver<TSource16> observer16, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+            _observer1 = observer1;
+            _observer2 = observer2;
+            _observer3 = observer3;
+            _observer4 = observer4;
+            _observer5 = observer5;
+            _observer6 = observer6;
+            _observer7 = observer7;
+            _observer8 = observer8;
+            _observer9 = observer9;
+            _observer10 = observer10;
+            _observer11 = observer11;
+            _observer12 = observer12;
+            _observer13 = observer13;
+            _observer14 = observer14;
+            _observer15 = observer15;
+            _observer16 = observer16;
+
+            AddJoinObserver(observer1);
+            AddJoinObserver(observer2);
+            AddJoinObserver(observer3);
+            AddJoinObserver(observer4);
+            AddJoinObserver(observer5);
+            AddJoinObserver(observer6);
+            AddJoinObserver(observer7);
+            AddJoinObserver(observer8);
+            AddJoinObserver(observer9);
+            AddJoinObserver(observer10);
+            AddJoinObserver(observer11);
+            AddJoinObserver(observer12);
+            AddJoinObserver(observer13);
+            AddJoinObserver(observer14);
+            AddJoinObserver(observer15);
+            AddJoinObserver(observer16);
+        }
+
+        internal override Task Match()
+        {
+            if (_observer1.Queue.Count > 0 && _observer2.Queue.Count > 0 && _observer3.Queue.Count > 0 && _observer4.Queue.Count > 0 && _observer5.Queue.Count > 0 && _observer6.Queue.Count > 0 && _observer7.Queue.Count > 0 && _observer8.Queue.Count > 0 && _observer9.Queue.Count > 0 && _observer10.Queue.Count > 0 && _observer11.Queue.Count > 0 && _observer12.Queue.Count > 0 && _observer13.Queue.Count > 0 && _observer14.Queue.Count > 0 && _observer15.Queue.Count > 0 && _observer16.Queue.Count > 0)
+            {
+                var notification1 = _observer1.Queue.Peek();
+                var notification2 = _observer2.Queue.Peek();
+                var notification3 = _observer3.Queue.Peek();
+                var notification4 = _observer4.Queue.Peek();
+                var notification5 = _observer5.Queue.Peek();
+                var notification6 = _observer6.Queue.Peek();
+                var notification7 = _observer7.Queue.Peek();
+                var notification8 = _observer8.Queue.Peek();
+                var notification9 = _observer9.Queue.Peek();
+                var notification10 = _observer10.Queue.Peek();
+                var notification11 = _observer11.Queue.Peek();
+                var notification12 = _observer12.Queue.Peek();
+                var notification13 = _observer13.Queue.Peek();
+                var notification14 = _observer14.Queue.Peek();
+                var notification15 = _observer15.Queue.Peek();
+                var notification16 = _observer16.Queue.Peek();
+
+                if (notification1.Kind == NotificationKind.OnCompleted || notification2.Kind == NotificationKind.OnCompleted || notification3.Kind == NotificationKind.OnCompleted || notification4.Kind == NotificationKind.OnCompleted || notification5.Kind == NotificationKind.OnCompleted || notification6.Kind == NotificationKind.OnCompleted || notification7.Kind == NotificationKind.OnCompleted || notification8.Kind == NotificationKind.OnCompleted || notification9.Kind == NotificationKind.OnCompleted || notification10.Kind == NotificationKind.OnCompleted || notification11.Kind == NotificationKind.OnCompleted || notification12.Kind == NotificationKind.OnCompleted || notification13.Kind == NotificationKind.OnCompleted || notification14.Kind == NotificationKind.OnCompleted || notification15.Kind == NotificationKind.OnCompleted || notification16.Kind == NotificationKind.OnCompleted)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(notification1.Value, notification2.Value, notification3.Value, notification4.Value, notification5.Value, notification6.Value, notification7.Value, notification8.Value, notification9.Value, notification10.Value, notification11.Value, notification12.Value, notification13.Value, notification14.Value, notification15.Value, notification16.Value);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+}

+ 90 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/ActiveAsyncPlan.Generated.tt

@@ -0,0 +1,90 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ import namespace="System.Linq" #>
+<#@ import namespace="System.Text" #>
+<#@ import namespace="System.Collections.Generic" #>
+<#@ output extension=".cs" #>
+using System.Threading.Tasks;
+
+namespace System.Reactive.Joins
+{
+<#
+for (var i = 1; i <= 16; i++)
+{
+    var genArgs = string.Join(", ", Enumerable.Range(1, i).Select(j => "TSource" + j));
+    var args = string.Join(", ", Enumerable.Range(1, i).Select(j => "IAsyncObservable<TSource" + j + "> source" + j));
+    var observers = string.Join(", ", Enumerable.Range(1, i).Select(j => "AsyncJoinObserver<TSource" + j + "> observer" + j));
+#>
+    internal sealed class ActiveAsyncPlan<<#=genArgs#>> : ActiveAsyncPlan
+    {
+        private readonly Func<<#=genArgs#>, Task> _onNext;
+        private readonly Func<Task> _onCompleted;
+
+<#
+for (var j = 1; j <= i; j++)
+{
+#>
+        private readonly AsyncJoinObserver<TSource<#=j#>> _observer<#=j#>;
+<#
+}
+#>
+
+        internal ActiveAsyncPlan(<#=observers#>, Func<<#=genArgs#>, Task> onNext, Func<Task> onCompleted)
+        {
+            _onNext = onNext;
+            _onCompleted = onCompleted;
+
+<#
+for (var j = 1; j <= i; j++)
+{
+#>
+            _observer<#=j#> = observer<#=j#>;
+<#
+}
+#>
+
+<#
+for (var j = 1; j <= i; j++)
+{
+#>
+            AddJoinObserver(observer<#=j#>);
+<#
+}
+#>
+        }
+
+        internal override Task Match()
+        {
+            if (<#=string.Join(" && ", Enumerable.Range(1, i).Select(j => "_observer" + j + ".Queue.Count > 0"))#>)
+            {
+<#
+for (var j = 1; j <= i; j++)
+{
+#>
+                var notification<#=j#> = _observer<#=j#>.Queue.Peek();
+<#
+}
+#>
+
+                if (<#=string.Join(" || ", Enumerable.Range(1, i).Select(j => "notification" + j + ".Kind == NotificationKind.OnCompleted"))#>)
+                {
+                    return _onCompleted();
+                }
+
+                Dequeue();
+
+                return _onNext(<#=string.Join(", ", Enumerable.Range(1, i).Select(j => "notification" + j + ".Value"))#>);
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+
+<#
+}
+#>
+}

+ 29 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/ActiveAsyncPlan.cs

@@ -0,0 +1,29 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Reactive.Joins
+{
+    internal abstract class ActiveAsyncPlan
+    {
+        private readonly Dictionary<IAsyncJoinObserver, IAsyncJoinObserver> joinObservers = new Dictionary<IAsyncJoinObserver, IAsyncJoinObserver>();
+
+        internal abstract Task Match();
+
+        protected void AddJoinObserver(IAsyncJoinObserver joinObserver)
+        {
+            joinObservers.Add(joinObserver, joinObserver);
+        }
+
+        protected void Dequeue()
+        {
+            foreach (var observer in joinObservers.Values)
+            {
+                observer.Dequeue();
+            }
+        }
+    }
+}

+ 96 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/AsyncJoinObserver.cs

@@ -0,0 +1,96 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+using System.Reactive.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.Reactive.Joins
+{
+    internal sealed class AsyncJoinObserver<T> : AsyncObserverBase<Notification<T>>, IAsyncJoinObserver
+    {
+        private readonly IAsyncObservable<T> _source;
+        private readonly Func<Exception, Task> _onError;
+
+        private readonly List<ActiveAsyncPlan> _activePlans = new List<ActiveAsyncPlan>();
+        private readonly SingleAssignmentAsyncDisposable _subscription = new SingleAssignmentAsyncDisposable();
+
+        private AsyncLock _gate;
+        private bool _isDisposed;
+
+        public AsyncJoinObserver(IAsyncObservable<T> source, Func<Exception, Task> onError)
+        {
+            _source = source;
+            _onError = onError;
+        }
+
+        public Queue<Notification<T>> Queue { get; } = new Queue<Notification<T>>();
+
+        public void Dequeue() => Queue.Dequeue();
+
+        public void AddActivePlan(ActiveAsyncPlan activePlan)
+        {
+            _activePlans.Add(activePlan);
+        }
+
+        internal async Task RemoveActivePlan(ActiveAsyncPlan activePlan)
+        {
+            _activePlans.Remove(activePlan);
+
+            if (_activePlans.Count == 0)
+            {
+                await DisposeAsync().ConfigureAwait(false);
+            }
+        }
+
+        public async Task DisposeAsync()
+        {
+            if (!_isDisposed)
+            {
+                await _subscription.DisposeAsync().ConfigureAwait(false);
+
+                _isDisposed = true;
+            }
+        }
+
+        public async Task SubscribeAsync(AsyncLock gate)
+        {
+            _gate = gate;
+
+            var d = await _source.Materialize().SubscribeSafeAsync(this).ConfigureAwait(false);
+            await _subscription.AssignAsync(d).ConfigureAwait(false);
+        }
+
+        protected override Task OnCompletedAsyncCore() => Task.CompletedTask;
+
+        protected override Task OnErrorAsyncCore(Exception error) => Task.CompletedTask;
+
+        protected override async Task OnNextAsyncCore(Notification<T> notification)
+        {
+            using (await _gate.LockAsync().ConfigureAwait(false))
+            {
+                if (!_isDisposed)
+                {
+                    if (notification.Kind == NotificationKind.OnError)
+                    {
+                        await _onError(notification.Exception).ConfigureAwait(false);
+                    }
+                    else
+                    {
+                        Queue.Enqueue(notification);
+
+                        var plans = _activePlans.ToArray();
+
+                        for (var i = 0; i < plans.Length; i++)
+                        {
+                            await plans[i].Match().ConfigureAwait(false); // REVIEW: Consider concurrent matching.
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 535 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/AsyncPattern.Generated.cs

@@ -0,0 +1,535 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+namespace System.Reactive.Joins
+{
+    public class AsyncPattern<TSource1> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1)
+        {
+            Source1 = source1;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2)
+        {
+            Source1 = source1;
+            Source2 = source2;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+        internal IAsyncObservable<TSource7> Source7 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6, IAsyncObservable<TSource7> source7)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+            Source7 = source7;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+        internal IAsyncObservable<TSource7> Source7 { get; }
+        internal IAsyncObservable<TSource8> Source8 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6, IAsyncObservable<TSource7> source7, IAsyncObservable<TSource8> source8)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+            Source7 = source7;
+            Source8 = source8;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+        internal IAsyncObservable<TSource7> Source7 { get; }
+        internal IAsyncObservable<TSource8> Source8 { get; }
+        internal IAsyncObservable<TSource9> Source9 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6, IAsyncObservable<TSource7> source7, IAsyncObservable<TSource8> source8, IAsyncObservable<TSource9> source9)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+            Source7 = source7;
+            Source8 = source8;
+            Source9 = source9;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+        internal IAsyncObservable<TSource7> Source7 { get; }
+        internal IAsyncObservable<TSource8> Source8 { get; }
+        internal IAsyncObservable<TSource9> Source9 { get; }
+        internal IAsyncObservable<TSource10> Source10 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6, IAsyncObservable<TSource7> source7, IAsyncObservable<TSource8> source8, IAsyncObservable<TSource9> source9, IAsyncObservable<TSource10> source10)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+            Source7 = source7;
+            Source8 = source8;
+            Source9 = source9;
+            Source10 = source10;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+        internal IAsyncObservable<TSource7> Source7 { get; }
+        internal IAsyncObservable<TSource8> Source8 { get; }
+        internal IAsyncObservable<TSource9> Source9 { get; }
+        internal IAsyncObservable<TSource10> Source10 { get; }
+        internal IAsyncObservable<TSource11> Source11 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6, IAsyncObservable<TSource7> source7, IAsyncObservable<TSource8> source8, IAsyncObservable<TSource9> source9, IAsyncObservable<TSource10> source10, IAsyncObservable<TSource11> source11)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+            Source7 = source7;
+            Source8 = source8;
+            Source9 = source9;
+            Source10 = source10;
+            Source11 = source11;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+        internal IAsyncObservable<TSource7> Source7 { get; }
+        internal IAsyncObservable<TSource8> Source8 { get; }
+        internal IAsyncObservable<TSource9> Source9 { get; }
+        internal IAsyncObservable<TSource10> Source10 { get; }
+        internal IAsyncObservable<TSource11> Source11 { get; }
+        internal IAsyncObservable<TSource12> Source12 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6, IAsyncObservable<TSource7> source7, IAsyncObservable<TSource8> source8, IAsyncObservable<TSource9> source9, IAsyncObservable<TSource10> source10, IAsyncObservable<TSource11> source11, IAsyncObservable<TSource12> source12)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+            Source7 = source7;
+            Source8 = source8;
+            Source9 = source9;
+            Source10 = source10;
+            Source11 = source11;
+            Source12 = source12;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+        internal IAsyncObservable<TSource7> Source7 { get; }
+        internal IAsyncObservable<TSource8> Source8 { get; }
+        internal IAsyncObservable<TSource9> Source9 { get; }
+        internal IAsyncObservable<TSource10> Source10 { get; }
+        internal IAsyncObservable<TSource11> Source11 { get; }
+        internal IAsyncObservable<TSource12> Source12 { get; }
+        internal IAsyncObservable<TSource13> Source13 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6, IAsyncObservable<TSource7> source7, IAsyncObservable<TSource8> source8, IAsyncObservable<TSource9> source9, IAsyncObservable<TSource10> source10, IAsyncObservable<TSource11> source11, IAsyncObservable<TSource12> source12, IAsyncObservable<TSource13> source13)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+            Source7 = source7;
+            Source8 = source8;
+            Source9 = source9;
+            Source10 = source10;
+            Source11 = source11;
+            Source12 = source12;
+            Source13 = source13;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+        internal IAsyncObservable<TSource7> Source7 { get; }
+        internal IAsyncObservable<TSource8> Source8 { get; }
+        internal IAsyncObservable<TSource9> Source9 { get; }
+        internal IAsyncObservable<TSource10> Source10 { get; }
+        internal IAsyncObservable<TSource11> Source11 { get; }
+        internal IAsyncObservable<TSource12> Source12 { get; }
+        internal IAsyncObservable<TSource13> Source13 { get; }
+        internal IAsyncObservable<TSource14> Source14 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6, IAsyncObservable<TSource7> source7, IAsyncObservable<TSource8> source8, IAsyncObservable<TSource9> source9, IAsyncObservable<TSource10> source10, IAsyncObservable<TSource11> source11, IAsyncObservable<TSource12> source12, IAsyncObservable<TSource13> source13, IAsyncObservable<TSource14> source14)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+            Source7 = source7;
+            Source8 = source8;
+            Source9 = source9;
+            Source10 = source10;
+            Source11 = source11;
+            Source12 = source12;
+            Source13 = source13;
+            Source14 = source14;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+        internal IAsyncObservable<TSource7> Source7 { get; }
+        internal IAsyncObservable<TSource8> Source8 { get; }
+        internal IAsyncObservable<TSource9> Source9 { get; }
+        internal IAsyncObservable<TSource10> Source10 { get; }
+        internal IAsyncObservable<TSource11> Source11 { get; }
+        internal IAsyncObservable<TSource12> Source12 { get; }
+        internal IAsyncObservable<TSource13> Source13 { get; }
+        internal IAsyncObservable<TSource14> Source14 { get; }
+        internal IAsyncObservable<TSource15> Source15 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6, IAsyncObservable<TSource7> source7, IAsyncObservable<TSource8> source8, IAsyncObservable<TSource9> source9, IAsyncObservable<TSource10> source10, IAsyncObservable<TSource11> source11, IAsyncObservable<TSource12> source12, IAsyncObservable<TSource13> source13, IAsyncObservable<TSource14> source14, IAsyncObservable<TSource15> source15)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+            Source7 = source7;
+            Source8 = source8;
+            Source9 = source9;
+            Source10 = source10;
+            Source11 = source11;
+            Source12 = source12;
+            Source13 = source13;
+            Source14 = source14;
+            Source15 = source15;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult>(this, selector);
+        }
+    }
+
+    public class AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16> : AsyncPattern
+    {
+        internal IAsyncObservable<TSource1> Source1 { get; }
+        internal IAsyncObservable<TSource2> Source2 { get; }
+        internal IAsyncObservable<TSource3> Source3 { get; }
+        internal IAsyncObservable<TSource4> Source4 { get; }
+        internal IAsyncObservable<TSource5> Source5 { get; }
+        internal IAsyncObservable<TSource6> Source6 { get; }
+        internal IAsyncObservable<TSource7> Source7 { get; }
+        internal IAsyncObservable<TSource8> Source8 { get; }
+        internal IAsyncObservable<TSource9> Source9 { get; }
+        internal IAsyncObservable<TSource10> Source10 { get; }
+        internal IAsyncObservable<TSource11> Source11 { get; }
+        internal IAsyncObservable<TSource12> Source12 { get; }
+        internal IAsyncObservable<TSource13> Source13 { get; }
+        internal IAsyncObservable<TSource14> Source14 { get; }
+        internal IAsyncObservable<TSource15> Source15 { get; }
+        internal IAsyncObservable<TSource16> Source16 { get; }
+
+        internal AsyncPattern(IAsyncObservable<TSource1> source1, IAsyncObservable<TSource2> source2, IAsyncObservable<TSource3> source3, IAsyncObservable<TSource4> source4, IAsyncObservable<TSource5> source5, IAsyncObservable<TSource6> source6, IAsyncObservable<TSource7> source7, IAsyncObservable<TSource8> source8, IAsyncObservable<TSource9> source9, IAsyncObservable<TSource10> source10, IAsyncObservable<TSource11> source11, IAsyncObservable<TSource12> source12, IAsyncObservable<TSource13> source13, IAsyncObservable<TSource14> source14, IAsyncObservable<TSource15> source15, IAsyncObservable<TSource16> source16)
+        {
+            Source1 = source1;
+            Source2 = source2;
+            Source3 = source3;
+            Source4 = source4;
+            Source5 = source5;
+            Source6 = source6;
+            Source7 = source7;
+            Source8 = source8;
+            Source9 = source9;
+            Source10 = source10;
+            Source11 = source11;
+            Source12 = source12;
+            Source13 = source13;
+            Source14 = source14;
+            Source15 = source15;
+            Source16 = source16;
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult>(this, selector);
+        }
+    }
+
+}

+ 54 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/AsyncPattern.Generated.tt

@@ -0,0 +1,54 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ import namespace="System.Linq" #>
+<#@ import namespace="System.Text" #>
+<#@ import namespace="System.Collections.Generic" #>
+<#@ output extension=".cs" #>
+namespace System.Reactive.Joins
+{
+<#
+for (var i = 1; i <= 16; i++)
+{
+    var genArgs = string.Join(", ", Enumerable.Range(1, i).Select(j => "TSource" + j));
+    var args = string.Join(", ", Enumerable.Range(1, i).Select(j => "IAsyncObservable<TSource" + j + "> source" + j));
+#>
+    public class AsyncPattern<<#=genArgs#>> : AsyncPattern
+    {
+<#
+for (var j = 1; j <= i; j++)
+{
+#>
+        internal IAsyncObservable<TSource<#=j#>> Source<#=j#> { get; }
+<#
+}
+#>
+
+        internal AsyncPattern(<#=args#>)
+        {
+<#
+for (var j = 1; j <= i; j++)
+{
+#>
+            Source<#=j#> = source<#=j#>;
+<#
+}
+#>
+        }
+
+        public AsyncPlan<TResult> Then<TResult>(Func<<#=genArgs#>, TResult> selector)
+        {
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPlan<<#=genArgs#>, TResult>(this, selector);
+        }
+    }
+
+<#
+}
+#>
+}

+ 13 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/AsyncPattern.cs

@@ -0,0 +1,13 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+namespace System.Reactive.Joins
+{
+    public abstract class AsyncPattern
+    {
+        internal AsyncPattern()
+        {
+        }
+    }
+}

+ 1306 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/AsyncPlan.Generated.cs

@@ -0,0 +1,1306 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Reactive.Joins
+{
+    public class AsyncPlan<TSource1, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1> Expression { get; }
+
+        public Func<TSource1, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1> expression, Func<TSource1, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1>);
+
+            activePlan = new ActiveAsyncPlan<TSource1>(
+                joinObserver1,
+                async (arg1) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2> Expression { get; }
+
+        public Func<TSource1, TSource2, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2> expression, Func<TSource1, TSource2, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2>(
+                joinObserver1,
+                joinObserver2,
+                async (arg1, arg2) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3> expression, Func<TSource1, TSource2, TSource3, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                async (arg1, arg2, arg3) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4> expression, Func<TSource1, TSource2, TSource3, TSource4, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                async (arg1, arg2, arg3, arg4) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                async (arg1, arg2, arg3, arg4, arg5) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                async (arg1, arg2, arg3, arg4, arg5, arg6) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+            var joinObserver7 = AsyncPlan<TResult>.CreateObserver<TSource7>(externalSubscriptions, this.Expression.Source7, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                joinObserver7,
+                async (arg1, arg2, arg3, arg4, arg5, arg6, arg7) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver7.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+            joinObserver7.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+            var joinObserver7 = AsyncPlan<TResult>.CreateObserver<TSource7>(externalSubscriptions, this.Expression.Source7, onError);
+            var joinObserver8 = AsyncPlan<TResult>.CreateObserver<TSource8>(externalSubscriptions, this.Expression.Source8, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                joinObserver7,
+                joinObserver8,
+                async (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver7.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver8.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+            joinObserver7.AddActivePlan(activePlan);
+            joinObserver8.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+            var joinObserver7 = AsyncPlan<TResult>.CreateObserver<TSource7>(externalSubscriptions, this.Expression.Source7, onError);
+            var joinObserver8 = AsyncPlan<TResult>.CreateObserver<TSource8>(externalSubscriptions, this.Expression.Source8, onError);
+            var joinObserver9 = AsyncPlan<TResult>.CreateObserver<TSource9>(externalSubscriptions, this.Expression.Source9, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                joinObserver7,
+                joinObserver8,
+                joinObserver9,
+                async (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver7.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver8.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver9.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+            joinObserver7.AddActivePlan(activePlan);
+            joinObserver8.AddActivePlan(activePlan);
+            joinObserver9.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+            var joinObserver7 = AsyncPlan<TResult>.CreateObserver<TSource7>(externalSubscriptions, this.Expression.Source7, onError);
+            var joinObserver8 = AsyncPlan<TResult>.CreateObserver<TSource8>(externalSubscriptions, this.Expression.Source8, onError);
+            var joinObserver9 = AsyncPlan<TResult>.CreateObserver<TSource9>(externalSubscriptions, this.Expression.Source9, onError);
+            var joinObserver10 = AsyncPlan<TResult>.CreateObserver<TSource10>(externalSubscriptions, this.Expression.Source10, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                joinObserver7,
+                joinObserver8,
+                joinObserver9,
+                joinObserver10,
+                async (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver7.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver8.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver9.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver10.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+            joinObserver7.AddActivePlan(activePlan);
+            joinObserver8.AddActivePlan(activePlan);
+            joinObserver9.AddActivePlan(activePlan);
+            joinObserver10.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+            var joinObserver7 = AsyncPlan<TResult>.CreateObserver<TSource7>(externalSubscriptions, this.Expression.Source7, onError);
+            var joinObserver8 = AsyncPlan<TResult>.CreateObserver<TSource8>(externalSubscriptions, this.Expression.Source8, onError);
+            var joinObserver9 = AsyncPlan<TResult>.CreateObserver<TSource9>(externalSubscriptions, this.Expression.Source9, onError);
+            var joinObserver10 = AsyncPlan<TResult>.CreateObserver<TSource10>(externalSubscriptions, this.Expression.Source10, onError);
+            var joinObserver11 = AsyncPlan<TResult>.CreateObserver<TSource11>(externalSubscriptions, this.Expression.Source11, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                joinObserver7,
+                joinObserver8,
+                joinObserver9,
+                joinObserver10,
+                joinObserver11,
+                async (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver7.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver8.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver9.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver10.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver11.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+            joinObserver7.AddActivePlan(activePlan);
+            joinObserver8.AddActivePlan(activePlan);
+            joinObserver9.AddActivePlan(activePlan);
+            joinObserver10.AddActivePlan(activePlan);
+            joinObserver11.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+            var joinObserver7 = AsyncPlan<TResult>.CreateObserver<TSource7>(externalSubscriptions, this.Expression.Source7, onError);
+            var joinObserver8 = AsyncPlan<TResult>.CreateObserver<TSource8>(externalSubscriptions, this.Expression.Source8, onError);
+            var joinObserver9 = AsyncPlan<TResult>.CreateObserver<TSource9>(externalSubscriptions, this.Expression.Source9, onError);
+            var joinObserver10 = AsyncPlan<TResult>.CreateObserver<TSource10>(externalSubscriptions, this.Expression.Source10, onError);
+            var joinObserver11 = AsyncPlan<TResult>.CreateObserver<TSource11>(externalSubscriptions, this.Expression.Source11, onError);
+            var joinObserver12 = AsyncPlan<TResult>.CreateObserver<TSource12>(externalSubscriptions, this.Expression.Source12, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                joinObserver7,
+                joinObserver8,
+                joinObserver9,
+                joinObserver10,
+                joinObserver11,
+                joinObserver12,
+                async (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver7.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver8.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver9.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver10.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver11.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver12.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+            joinObserver7.AddActivePlan(activePlan);
+            joinObserver8.AddActivePlan(activePlan);
+            joinObserver9.AddActivePlan(activePlan);
+            joinObserver10.AddActivePlan(activePlan);
+            joinObserver11.AddActivePlan(activePlan);
+            joinObserver12.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+            var joinObserver7 = AsyncPlan<TResult>.CreateObserver<TSource7>(externalSubscriptions, this.Expression.Source7, onError);
+            var joinObserver8 = AsyncPlan<TResult>.CreateObserver<TSource8>(externalSubscriptions, this.Expression.Source8, onError);
+            var joinObserver9 = AsyncPlan<TResult>.CreateObserver<TSource9>(externalSubscriptions, this.Expression.Source9, onError);
+            var joinObserver10 = AsyncPlan<TResult>.CreateObserver<TSource10>(externalSubscriptions, this.Expression.Source10, onError);
+            var joinObserver11 = AsyncPlan<TResult>.CreateObserver<TSource11>(externalSubscriptions, this.Expression.Source11, onError);
+            var joinObserver12 = AsyncPlan<TResult>.CreateObserver<TSource12>(externalSubscriptions, this.Expression.Source12, onError);
+            var joinObserver13 = AsyncPlan<TResult>.CreateObserver<TSource13>(externalSubscriptions, this.Expression.Source13, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                joinObserver7,
+                joinObserver8,
+                joinObserver9,
+                joinObserver10,
+                joinObserver11,
+                joinObserver12,
+                joinObserver13,
+                async (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver7.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver8.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver9.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver10.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver11.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver12.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver13.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+            joinObserver7.AddActivePlan(activePlan);
+            joinObserver8.AddActivePlan(activePlan);
+            joinObserver9.AddActivePlan(activePlan);
+            joinObserver10.AddActivePlan(activePlan);
+            joinObserver11.AddActivePlan(activePlan);
+            joinObserver12.AddActivePlan(activePlan);
+            joinObserver13.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+            var joinObserver7 = AsyncPlan<TResult>.CreateObserver<TSource7>(externalSubscriptions, this.Expression.Source7, onError);
+            var joinObserver8 = AsyncPlan<TResult>.CreateObserver<TSource8>(externalSubscriptions, this.Expression.Source8, onError);
+            var joinObserver9 = AsyncPlan<TResult>.CreateObserver<TSource9>(externalSubscriptions, this.Expression.Source9, onError);
+            var joinObserver10 = AsyncPlan<TResult>.CreateObserver<TSource10>(externalSubscriptions, this.Expression.Source10, onError);
+            var joinObserver11 = AsyncPlan<TResult>.CreateObserver<TSource11>(externalSubscriptions, this.Expression.Source11, onError);
+            var joinObserver12 = AsyncPlan<TResult>.CreateObserver<TSource12>(externalSubscriptions, this.Expression.Source12, onError);
+            var joinObserver13 = AsyncPlan<TResult>.CreateObserver<TSource13>(externalSubscriptions, this.Expression.Source13, onError);
+            var joinObserver14 = AsyncPlan<TResult>.CreateObserver<TSource14>(externalSubscriptions, this.Expression.Source14, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                joinObserver7,
+                joinObserver8,
+                joinObserver9,
+                joinObserver10,
+                joinObserver11,
+                joinObserver12,
+                joinObserver13,
+                joinObserver14,
+                async (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver7.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver8.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver9.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver10.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver11.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver12.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver13.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver14.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+            joinObserver7.AddActivePlan(activePlan);
+            joinObserver8.AddActivePlan(activePlan);
+            joinObserver9.AddActivePlan(activePlan);
+            joinObserver10.AddActivePlan(activePlan);
+            joinObserver11.AddActivePlan(activePlan);
+            joinObserver12.AddActivePlan(activePlan);
+            joinObserver13.AddActivePlan(activePlan);
+            joinObserver14.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+            var joinObserver7 = AsyncPlan<TResult>.CreateObserver<TSource7>(externalSubscriptions, this.Expression.Source7, onError);
+            var joinObserver8 = AsyncPlan<TResult>.CreateObserver<TSource8>(externalSubscriptions, this.Expression.Source8, onError);
+            var joinObserver9 = AsyncPlan<TResult>.CreateObserver<TSource9>(externalSubscriptions, this.Expression.Source9, onError);
+            var joinObserver10 = AsyncPlan<TResult>.CreateObserver<TSource10>(externalSubscriptions, this.Expression.Source10, onError);
+            var joinObserver11 = AsyncPlan<TResult>.CreateObserver<TSource11>(externalSubscriptions, this.Expression.Source11, onError);
+            var joinObserver12 = AsyncPlan<TResult>.CreateObserver<TSource12>(externalSubscriptions, this.Expression.Source12, onError);
+            var joinObserver13 = AsyncPlan<TResult>.CreateObserver<TSource13>(externalSubscriptions, this.Expression.Source13, onError);
+            var joinObserver14 = AsyncPlan<TResult>.CreateObserver<TSource14>(externalSubscriptions, this.Expression.Source14, onError);
+            var joinObserver15 = AsyncPlan<TResult>.CreateObserver<TSource15>(externalSubscriptions, this.Expression.Source15, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                joinObserver7,
+                joinObserver8,
+                joinObserver9,
+                joinObserver10,
+                joinObserver11,
+                joinObserver12,
+                joinObserver13,
+                joinObserver14,
+                joinObserver15,
+                async (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver7.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver8.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver9.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver10.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver11.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver12.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver13.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver14.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver15.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+            joinObserver7.AddActivePlan(activePlan);
+            joinObserver8.AddActivePlan(activePlan);
+            joinObserver9.AddActivePlan(activePlan);
+            joinObserver10.AddActivePlan(activePlan);
+            joinObserver11.AddActivePlan(activePlan);
+            joinObserver12.AddActivePlan(activePlan);
+            joinObserver13.AddActivePlan(activePlan);
+            joinObserver14.AddActivePlan(activePlan);
+            joinObserver15.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+    public class AsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16> Expression { get; }
+
+        public Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16> expression, Func<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+            var joinObserver1 = AsyncPlan<TResult>.CreateObserver<TSource1>(externalSubscriptions, this.Expression.Source1, onError);
+            var joinObserver2 = AsyncPlan<TResult>.CreateObserver<TSource2>(externalSubscriptions, this.Expression.Source2, onError);
+            var joinObserver3 = AsyncPlan<TResult>.CreateObserver<TSource3>(externalSubscriptions, this.Expression.Source3, onError);
+            var joinObserver4 = AsyncPlan<TResult>.CreateObserver<TSource4>(externalSubscriptions, this.Expression.Source4, onError);
+            var joinObserver5 = AsyncPlan<TResult>.CreateObserver<TSource5>(externalSubscriptions, this.Expression.Source5, onError);
+            var joinObserver6 = AsyncPlan<TResult>.CreateObserver<TSource6>(externalSubscriptions, this.Expression.Source6, onError);
+            var joinObserver7 = AsyncPlan<TResult>.CreateObserver<TSource7>(externalSubscriptions, this.Expression.Source7, onError);
+            var joinObserver8 = AsyncPlan<TResult>.CreateObserver<TSource8>(externalSubscriptions, this.Expression.Source8, onError);
+            var joinObserver9 = AsyncPlan<TResult>.CreateObserver<TSource9>(externalSubscriptions, this.Expression.Source9, onError);
+            var joinObserver10 = AsyncPlan<TResult>.CreateObserver<TSource10>(externalSubscriptions, this.Expression.Source10, onError);
+            var joinObserver11 = AsyncPlan<TResult>.CreateObserver<TSource11>(externalSubscriptions, this.Expression.Source11, onError);
+            var joinObserver12 = AsyncPlan<TResult>.CreateObserver<TSource12>(externalSubscriptions, this.Expression.Source12, onError);
+            var joinObserver13 = AsyncPlan<TResult>.CreateObserver<TSource13>(externalSubscriptions, this.Expression.Source13, onError);
+            var joinObserver14 = AsyncPlan<TResult>.CreateObserver<TSource14>(externalSubscriptions, this.Expression.Source14, onError);
+            var joinObserver15 = AsyncPlan<TResult>.CreateObserver<TSource15>(externalSubscriptions, this.Expression.Source15, onError);
+            var joinObserver16 = AsyncPlan<TResult>.CreateObserver<TSource16>(externalSubscriptions, this.Expression.Source16, onError);
+
+            var activePlan = default(ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16>);
+
+            activePlan = new ActiveAsyncPlan<TSource1, TSource2, TSource3, TSource4, TSource5, TSource6, TSource7, TSource8, TSource9, TSource10, TSource11, TSource12, TSource13, TSource14, TSource15, TSource16>(
+                joinObserver1,
+                joinObserver2,
+                joinObserver3,
+                joinObserver4,
+                joinObserver5,
+                joinObserver6,
+                joinObserver7,
+                joinObserver8,
+                joinObserver9,
+                joinObserver10,
+                joinObserver11,
+                joinObserver12,
+                joinObserver13,
+                joinObserver14,
+                joinObserver15,
+                joinObserver16,
+                async (arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+                    await joinObserver1.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver2.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver3.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver4.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver5.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver6.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver7.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver8.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver9.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver10.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver11.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver12.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver13.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver14.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver15.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await joinObserver16.RemoveActivePlan(activePlan).ConfigureAwait(false);
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+            joinObserver1.AddActivePlan(activePlan);
+            joinObserver2.AddActivePlan(activePlan);
+            joinObserver3.AddActivePlan(activePlan);
+            joinObserver4.AddActivePlan(activePlan);
+            joinObserver5.AddActivePlan(activePlan);
+            joinObserver6.AddActivePlan(activePlan);
+            joinObserver7.AddActivePlan(activePlan);
+            joinObserver8.AddActivePlan(activePlan);
+            joinObserver9.AddActivePlan(activePlan);
+            joinObserver10.AddActivePlan(activePlan);
+            joinObserver11.AddActivePlan(activePlan);
+            joinObserver12.AddActivePlan(activePlan);
+            joinObserver13.AddActivePlan(activePlan);
+            joinObserver14.AddActivePlan(activePlan);
+            joinObserver15.AddActivePlan(activePlan);
+            joinObserver16.AddActivePlan(activePlan);
+
+            return activePlan;
+        }
+    }
+
+}

+ 105 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/AsyncPlan.Generated.tt

@@ -0,0 +1,105 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ import namespace="System.Linq" #>
+<#@ import namespace="System.Text" #>
+<#@ import namespace="System.Collections.Generic" #>
+<#@ output extension=".cs" #>
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Reactive.Joins
+{
+<#
+for (var i = 1; i <= 16; i++)
+{
+    var genArgs = string.Join(", ", Enumerable.Range(1, i).Select(j => "TSource" + j));
+    var args = string.Join(", ", Enumerable.Range(1, i).Select(j => "IObservable<TSource" + j + "> source" + j));
+    var pars = string.Join(", ", Enumerable.Range(1, i).Select(j => "arg" + j));
+#>
+    public class AsyncPlan<<#=genArgs#>, TResult> : AsyncPlan<TResult>
+    {
+        public AsyncPattern<<#=genArgs#>> Expression { get; }
+
+        public Func<<#=genArgs#>, TResult> Selector { get; }
+
+        internal AsyncPlan(AsyncPattern<<#=genArgs#>> expression, Func<<#=genArgs#>, TResult> selector)
+        {
+            Expression = expression;
+            Selector = selector;
+        }
+
+        internal override ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate)
+        {
+            var onError = new Func<Exception, Task>(observer.OnErrorAsync);
+
+<#
+for (var j = 1; j <= i; j++)
+{
+#>
+            var joinObserver<#=j#> = AsyncPlan<TResult>.CreateObserver<TSource<#=j#>>(externalSubscriptions, this.Expression.Source<#=j#>, onError);
+<#
+}
+#>
+
+            var activePlan = default(ActiveAsyncPlan<<#=genArgs#>>);
+
+            activePlan = new ActiveAsyncPlan<<#=genArgs#>>(
+<#
+for (var j = 1; j <= i; j++)
+{
+#>
+                joinObserver<#=j#>,
+<#
+}
+#>
+                async (<#=pars#>) =>
+                {
+                    var res = default(TResult);
+
+                    try
+                    {
+                        res = Selector(<#=pars#>);
+                    }
+                    catch (Exception ex)
+                    {
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                        return;
+                    }
+
+                    await observer.OnNextAsync(res).ConfigureAwait(false);
+                },
+                async () =>
+                {
+<#
+for (var j = 1; j <= i; j++)
+{
+#>
+                    await joinObserver<#=j#>.RemoveActivePlan(activePlan).ConfigureAwait(false);
+<#
+}
+#>
+                    await deactivate(activePlan).ConfigureAwait(false);
+                }
+            );
+
+<#
+for (var j = 1; j <= i; j++)
+{
+#>
+            joinObserver<#=j#>.AddActivePlan(activePlan);
+<#
+}
+#>
+
+            return activePlan;
+        }
+    }
+
+<#
+}
+#>
+}

+ 35 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/AsyncPlan.cs

@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace System.Reactive.Joins
+{
+    public abstract class AsyncPlan<TResult>
+    {
+        internal AsyncPlan()
+        {
+        }
+
+        internal abstract ActiveAsyncPlan Activate(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObserver<TResult> observer, Func<ActiveAsyncPlan, Task> deactivate);
+
+        internal static AsyncJoinObserver<TSource> CreateObserver<TSource>(Dictionary<object, IAsyncJoinObserver> externalSubscriptions, IAsyncObservable<TSource> observable, Func<Exception, Task> onError)
+        {
+            var res = default(AsyncJoinObserver<TSource>);
+
+            if (externalSubscriptions.TryGetValue(observable, out var joinObserver))
+            {
+                res = (AsyncJoinObserver<TSource>)joinObserver;
+            }
+            else
+            {
+                res = new AsyncJoinObserver<TSource>(observable, onError);
+                externalSubscriptions.Add(observable, res);
+            }
+
+            return res;
+        }
+    }
+}

+ 16 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Joins/IAsyncJoinObserver.cs

@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.Reactive.Joins
+{
+    internal interface IAsyncJoinObserver : IAsyncDisposable
+    {
+        Task SubscribeAsync(AsyncLock gate);
+
+        void Dequeue();
+    }
+}

+ 23 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Linq/Operators/And.cs

@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System.Reactive.Joins;
+
+namespace System.Reactive.Linq
+{
+    // REVIEW: Consider moving join patterns to a separate assembly.
+
+    partial class AsyncObservable
+    {
+        public static AsyncPattern<TLeft, TRight> And<TLeft, TRight>(this IAsyncObservable<TLeft> left, IAsyncObservable<TRight> right)
+        {
+            if (left == null)
+                throw new ArgumentNullException(nameof(left));
+            if (right == null)
+                throw new ArgumentNullException(nameof(right));
+
+            return new AsyncPattern<TLeft, TRight>(left, right);
+        }
+    }
+}

+ 25 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Linq/Operators/Then.cs

@@ -0,0 +1,25 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System.Reactive.Joins;
+
+namespace System.Reactive.Linq
+{
+    // REVIEW: Consider moving join patterns to a separate assembly.
+
+    partial class AsyncObservable
+    {
+        // REVIEW: Consider adding async support.
+
+        public static AsyncPlan<TResult> Then<TSource, TResult>(this IAsyncObservable<TSource> source, Func<TSource, TResult> selector)
+        {
+            if (source == null)
+                throw new ArgumentNullException(nameof(source));
+            if (selector == null)
+                throw new ArgumentNullException(nameof(selector));
+
+            return new AsyncPattern<TSource>(source).Then(selector);
+        }
+    }
+}

+ 75 - 0
AsyncRx.NET/System.Reactive.Async.Linq/System/Reactive/Linq/Operators/When.cs

@@ -0,0 +1,75 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the Apache 2.0 License.
+// See the LICENSE file in the project root for more information. 
+
+using System.Collections.Generic;
+using System.Reactive.Disposables;
+using System.Reactive.Joins;
+using System.Threading;
+
+namespace System.Reactive.Linq
+{
+    partial class AsyncObservable
+    {
+        public static IAsyncObservable<TResult> When<TResult>(IEnumerable<AsyncPlan<TResult>> plans)
+        {
+            if (plans == null)
+                throw new ArgumentNullException(nameof(plans));
+
+            return Create<TResult>(async observer =>
+            {
+                var externalSubscriptions = new Dictionary<object, IAsyncJoinObserver>();
+                var gate = new AsyncLock();
+                var activePlans = new List<ActiveAsyncPlan>();
+
+                var outputObserver = AsyncObserver.Create<TResult>(
+                    observer.OnNextAsync,
+                    async ex =>
+                    {
+                        foreach (var subscription in externalSubscriptions.Values)
+                        {
+                            await subscription.DisposeAsync().ConfigureAwait(false);
+                        }
+
+                        await observer.OnErrorAsync(ex).ConfigureAwait(false);
+                    },
+                    observer.OnCompletedAsync
+                );
+
+                try
+                {
+                    foreach (var plan in plans)
+                    {
+                        var activatedPlan = plan.Activate(externalSubscriptions, outputObserver, async activePlan =>
+                        {
+                            activePlans.Remove(activePlan);
+
+                            if (activePlans.Count == 0)
+                            {
+                                await outputObserver.OnCompletedAsync().ConfigureAwait(false);
+                            }
+                        });
+
+                        activePlans.Add(activatedPlan);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    return await Throw<TResult>(ex).SubscribeAsync(observer).ConfigureAwait(false);
+                }
+
+                var d = new CompositeAsyncDisposable();
+
+                foreach (var joinObserver in externalSubscriptions.Values)
+                {
+                    await joinObserver.SubscribeAsync(gate).ConfigureAwait(false);
+                    await d.AddAsync(joinObserver).ConfigureAwait(false);
+                }
+
+                return d;
+            });
+        }
+
+        public static IAsyncObservable<TResult> When<TResult>(params AsyncPlan<TResult>[] plans) => When((IEnumerable<AsyncPlan<TResult>>)plans);
+    }
+}