diff --git a/ConductorSharp.sln b/ConductorSharp.sln
index 94732eff..6bd45c55 100644
--- a/ConductorSharp.sln
+++ b/ConductorSharp.sln
@@ -26,6 +26,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
 		.editorconfig = .editorconfig
 	EndProjectSection
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConductorSharp.Patterns", "src\ConductorSharp.Patterns\ConductorSharp.Patterns.csproj", "{9A55F1CF-2553-4F44-A8BC-0063A402582F}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -64,6 +66,10 @@ Global
 		{7FC97985-07CE-4643-8415-C48BA2117D88}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{7FC97985-07CE-4643-8415-C48BA2117D88}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{7FC97985-07CE-4643-8415-C48BA2117D88}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9A55F1CF-2553-4F44-A8BC-0063A402582F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9A55F1CF-2553-4F44-A8BC-0063A402582F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9A55F1CF-2553-4F44-A8BC-0063A402582F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9A55F1CF-2553-4F44-A8BC-0063A402582F}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/examples/ConductorSharp.Definitions/ConductorModule.cs b/examples/ConductorSharp.Definitions/ConductorModule.cs
index 213e32c2..d5900942 100644
--- a/examples/ConductorSharp.Definitions/ConductorModule.cs
+++ b/examples/ConductorSharp.Definitions/ConductorModule.cs
@@ -11,6 +11,7 @@ protected override void Load(ContainerBuilder builder)
             base.Load(builder);
 
             builder.RegisterWorkflow<SendCustomerNotification>();
+            builder.RegisterWorkflow<HandleNotificationFailure>();
         }
     }
 }
diff --git a/examples/ConductorSharp.Definitions/ConductorSharp.Definitions.csproj b/examples/ConductorSharp.Definitions/ConductorSharp.Definitions.csproj
index 6b12bd4d..a99093b7 100644
--- a/examples/ConductorSharp.Definitions/ConductorSharp.Definitions.csproj
+++ b/examples/ConductorSharp.Definitions/ConductorSharp.Definitions.csproj
@@ -35,6 +35,7 @@
 
   <ItemGroup>
     <ProjectReference Include="..\..\src\ConductorSharp.Engine\ConductorSharp.Engine.csproj" />
+    <ProjectReference Include="..\..\src\ConductorSharp.Patterns\ConductorSharp.Patterns.csproj" />
   </ItemGroup>
 
 </Project>
diff --git a/examples/ConductorSharp.Definitions/Program.cs b/examples/ConductorSharp.Definitions/Program.cs
index 02c88e92..538f2fe2 100644
--- a/examples/ConductorSharp.Definitions/Program.cs
+++ b/examples/ConductorSharp.Definitions/Program.cs
@@ -3,6 +3,7 @@
 using ConductorSharp.Definitions;
 using ConductorSharp.Engine.Extensions;
 using ConductorSharp.Engine.Health;
+using ConductorSharp.Patterns.Extensions;
 using MediatR.Extensions.Autofac.DependencyInjection;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
@@ -40,6 +41,7 @@
                     longPollInterval: configuration.GetValue<int>("Conductor:LongPollInterval"),
                     domain: configuration.GetValue<string>("Conductor:WorkerDomain")
                 )
+                .AddConductorSharpPatterns()
                 .SetHealthCheckService<FileHealthService>()
                 .AddPipelines(pipelines =>
                 {
diff --git a/examples/ConductorSharp.Definitions/Workflows/HandleNotificationFailure.cs b/examples/ConductorSharp.Definitions/Workflows/HandleNotificationFailure.cs
new file mode 100644
index 00000000..6cc89c6c
--- /dev/null
+++ b/examples/ConductorSharp.Definitions/Workflows/HandleNotificationFailure.cs
@@ -0,0 +1,40 @@
+﻿using ConductorSharp.Client.Model.Common;
+using ConductorSharp.Engine.Builders;
+using ConductorSharp.Engine.Util;
+using ConductorSharp.Patterns.Tasks;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConductorSharp.Definitions.Workflows
+{
+    public class HandleNotificationFailureInput : WorkflowInput<HandleNotificationFailureOutput>
+    {
+        [JsonProperty("workflowId")]
+        public string? WorkflowId { get; set; }
+    }
+
+    public class HandleNotificationFailureOutput : WorkflowOutput { }
+
+    [OriginalName("NOTIFICATION_handle_failure")]
+    public class HandleNotificationFailure : Workflow<HandleNotificationFailureInput, HandleNotificationFailureOutput>
+    {
+        public ReadWorkflowTasks? ReadExecutedTasks { get; set; }
+
+        public override WorkflowDefinition GetDefinition()
+        {
+            var builder = new WorkflowDefinitionBuilder<HandleNotificationFailure>();
+
+            builder.AddTask(a => a.ReadExecutedTasks, b => new() { TaskNames = "dynamic_handler", WorkflowId = b.WorkflowInput.WorkflowId });
+
+            return builder.Build(options =>
+            {
+                options.Version = 1;
+                options.OwnerEmail = "example@example.local";
+            });
+        }
+    }
+}
diff --git a/examples/ConductorSharp.Definitions/Workflows/SendCustomerNotification.cs b/examples/ConductorSharp.Definitions/Workflows/SendCustomerNotification.cs
index 8350fdd9..74090ed2 100644
--- a/examples/ConductorSharp.Definitions/Workflows/SendCustomerNotification.cs
+++ b/examples/ConductorSharp.Definitions/Workflows/SendCustomerNotification.cs
@@ -3,6 +3,7 @@
 using ConductorSharp.Engine.Builders;
 using ConductorSharp.Engine.Model;
 using ConductorSharp.Engine.Util;
+using ConductorSharp.Patterns.Tasks;
 using MediatR;
 
 namespace ConductorSharp.Definitions.Workflows
@@ -28,6 +29,7 @@ public class SendCustomerNotification : Workflow<SendCustomerNotificationInput,
         public EmailPrepareV1? PrepareEmail { get; set; }
         public DynamicTaskModel<ExpectedDynamicInput, ExpectedDynamicOutput>? DynamicHandler { get; set; }
         public SendCustomerNotification? SendNotif { get; set; }
+        public WaitSeconds? WaitSeconds { get; set; }
 
         public override WorkflowDefinition GetDefinition()
         {
@@ -43,10 +45,13 @@ public override WorkflowDefinition GetDefinition()
                     }
             );
 
+            builder.AddTask(a => a.WaitSeconds, b => new() { Seconds = 10 });
+
             builder.AddTask(a => a.PrepareEmail, b => new() { Address = b.DynamicHandler!.Output.Address, Name = b.DynamicHandler!.Output.Name });
 
             return builder.Build(options =>
             {
+                options.FailureWorkflow = typeof(HandleNotificationFailure);
                 options.Version = 1;
                 options.OwnerEmail = "example@example.local";
             });
diff --git a/src/ConductorSharp.Engine/Builders/DecisionTaskBuilder.cs b/src/ConductorSharp.Engine/Builders/DecisionTaskBuilder.cs
index 977efb22..14b17db7 100644
--- a/src/ConductorSharp.Engine/Builders/DecisionTaskBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/DecisionTaskBuilder.cs
@@ -10,6 +10,28 @@
 
 namespace ConductorSharp.Engine.Builders
 {
+    public static class DecisionTaskExtensions
+    {
+        public static ITaskOptionsBuilder AddTask<TWorkflow>(
+            this WorkflowDefinitionBuilder<TWorkflow> builder,
+            Expression<Func<TWorkflow, DecisionTaskModel>> taskSelector,
+            Expression<Func<TWorkflow, DecisionTaskInput>> expression,
+            params (string, Action<DecisionTaskBuilder<TWorkflow>>)[] caseActions
+        ) where TWorkflow : ITypedWorkflow
+        {
+            var taskBbuilder = new DecisionTaskBuilder<TWorkflow>(taskSelector.Body, expression.Body);
+
+            foreach (var funcase in caseActions)
+            {
+                taskBbuilder.AddCase(funcase.Item1);
+                funcase.Item2.Invoke(taskBbuilder);
+            }
+
+            builder.Context.TaskBuilders.Add(taskBbuilder);
+            return taskBbuilder;
+        }
+    }
+
     public class DecisionTaskBuilder<TWorkflow> : BaseTaskBuilder<DecisionTaskInput, NoOutput> where TWorkflow : ITypedWorkflow
     {
         private Dictionary<string, List<ITaskBuilder>> _caseDictionary = new();
diff --git a/src/ConductorSharp.Engine/Builders/DynamicForkJoinTaskBuilder.cs b/src/ConductorSharp.Engine/Builders/DynamicForkJoinTaskBuilder.cs
index 1176905d..12f142a9 100644
--- a/src/ConductorSharp.Engine/Builders/DynamicForkJoinTaskBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/DynamicForkJoinTaskBuilder.cs
@@ -1,10 +1,26 @@
 ﻿using ConductorSharp.Client.Model.Common;
+using ConductorSharp.Engine.Interface;
 using ConductorSharp.Engine.Model;
 using Newtonsoft.Json.Linq;
+using System;
 using System.Linq.Expressions;
 
 namespace ConductorSharp.Engine.Builders
 {
+    public static class DynamicForkJoinTaskExtensions
+    {
+        public static ITaskOptionsBuilder AddTask<TWorkflow>(
+            this WorkflowDefinitionBuilder<TWorkflow> builder,
+            Expression<Func<TWorkflow, DynamicForkJoinTaskModel>> refference,
+            Expression<Func<TWorkflow, DynamicForkJoinInput>> input
+        ) where TWorkflow : ITypedWorkflow
+        {
+            var taskBuilder = new DynamicForkJoinTaskBuilder(refference.Body, input.Body);
+            builder.Context.TaskBuilders.Add(taskBuilder);
+            return taskBuilder;
+        }
+    }
+
     public class DynamicForkJoinTaskBuilder : BaseTaskBuilder<DynamicForkJoinInput, NoOutput>
     {
         public DynamicForkJoinTaskBuilder(Expression taskExpression, Expression inputExpression) : base(taskExpression, inputExpression) { }
diff --git a/src/ConductorSharp.Engine/Builders/DynamicTaskBuilder.cs b/src/ConductorSharp.Engine/Builders/DynamicTaskBuilder.cs
index e1bc67cf..ab2d015a 100644
--- a/src/ConductorSharp.Engine/Builders/DynamicTaskBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/DynamicTaskBuilder.cs
@@ -1,5 +1,7 @@
 ﻿using ConductorSharp.Client.Model.Common;
+using ConductorSharp.Engine.Interface;
 using ConductorSharp.Engine.Model;
+using MediatR;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 using System;
@@ -9,6 +11,20 @@
 
 namespace ConductorSharp.Engine.Builders
 {
+    public static class DynamicTaskExtensions
+    {
+        public static ITaskOptionsBuilder AddTask<TWorkflow, F, G>(
+            this WorkflowDefinitionBuilder<TWorkflow> builder,
+            Expression<Func<TWorkflow, DynamicTaskModel<F, G>>> reference,
+            Expression<Func<TWorkflow, DynamicTaskInput<F, G>>> input
+        ) where TWorkflow : ITypedWorkflow
+        {
+            var taskBuilder = new DynamicTaskBuilder<F, G>(reference.Body, input.Body);
+            builder.Context.TaskBuilders.Add(taskBuilder);
+            return taskBuilder;
+        }
+    }
+
     public class DynamicTaskBuilder<I, O> : BaseTaskBuilder<DynamicTaskInput<I, O>, O>
     {
         private const string TaskType = "DYNAMIC";
diff --git a/src/ConductorSharp.Engine/Builders/JsonJqTransformTaskBuilder.cs b/src/ConductorSharp.Engine/Builders/JsonJqTransformTaskBuilder.cs
index 3188ee33..c9b9d0c6 100644
--- a/src/ConductorSharp.Engine/Builders/JsonJqTransformTaskBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/JsonJqTransformTaskBuilder.cs
@@ -1,10 +1,28 @@
 ﻿using ConductorSharp.Client.Model.Common;
+using ConductorSharp.Engine.Interface;
+using ConductorSharp.Engine.Model;
 using MediatR;
 using System;
 using System.Linq.Expressions;
 
 namespace ConductorSharp.Engine.Builders
 {
+    public static class JsonJqTransformTaskExtensions
+    {
+        public static ITaskOptionsBuilder AddTask<TWorkflow, F, G>(
+            this WorkflowDefinitionBuilder<TWorkflow> builder,
+            Expression<Func<TWorkflow, JsonJqTransformTaskModel<F, G>>> refference,
+            Expression<Func<TWorkflow, F>> input
+        )
+            where TWorkflow : ITypedWorkflow
+            where F : IRequest<G>
+        {
+            var taskBuilder = new JsonJqTransformTaskBuilder<F, G>(refference.Body, input.Body);
+            builder.Context.TaskBuilders.Add(taskBuilder);
+            return taskBuilder;
+        }
+    }
+
     public class JsonJqTransformTaskBuilder<A, B> : BaseTaskBuilder<A, B> where A : IRequest<B>
     {
         public JsonJqTransformTaskBuilder(Expression taskExpression, Expression inputExpression) : base(taskExpression, inputExpression)
diff --git a/src/ConductorSharp.Engine/Builders/LambdaTaskBuilder.cs b/src/ConductorSharp.Engine/Builders/LambdaTaskBuilder.cs
index 588df4fc..2aeb9dde 100644
--- a/src/ConductorSharp.Engine/Builders/LambdaTaskBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/LambdaTaskBuilder.cs
@@ -1,10 +1,30 @@
 ﻿using ConductorSharp.Client.Model.Common;
+using ConductorSharp.Engine.Interface;
+using ConductorSharp.Engine.Model;
 using MediatR;
 using Newtonsoft.Json.Linq;
+using System;
 using System.Linq.Expressions;
 
 namespace ConductorSharp.Engine.Builders
 {
+    public static class LambdaTaskExtensions
+    {
+        public static ITaskOptionsBuilder AddTask<TWorkflow, F, G>(
+            this WorkflowDefinitionBuilder<TWorkflow> builder,
+            Expression<Func<TWorkflow, LambdaTaskModel<F, G>>> referrence,
+            Expression<Func<TWorkflow, F>> input,
+            string script
+        )
+            where TWorkflow : ITypedWorkflow
+            where F : IRequest<G>
+        {
+            var taskBuilder = new LambdaTaskBuilder<F, G>(script, referrence.Body, input.Body);
+            builder.Context.TaskBuilders.Add(taskBuilder);
+            return taskBuilder;
+        }
+    }
+
     public class LambdaTaskBuilder<A, B> : BaseTaskBuilder<A, B> where A : IRequest<B>
     {
         private readonly string _script;
diff --git a/src/ConductorSharp.Engine/Builders/PassThroughTaskBuilder.cs b/src/ConductorSharp.Engine/Builders/PassThroughTaskBuilder.cs
index 8075aa21..2ee73362 100644
--- a/src/ConductorSharp.Engine/Builders/PassThroughTaskBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/PassThroughTaskBuilder.cs
@@ -6,6 +6,12 @@
 
 namespace ConductorSharp.Engine.Builders
 {
+    public static class PassThroughTaskExtensions
+    {
+        public static void AddTasks<TWorkflow>(this WorkflowDefinitionBuilder<TWorkflow> builder, params WorkflowDefinition.Task[] taskDefinitions)
+            where TWorkflow : ITypedWorkflow => builder.Context.TaskBuilders.Add(new PassThroughTaskBuilder(taskDefinitions));
+    }
+
     public class PassThroughTaskBuilder : ITaskBuilder
     {
         private readonly WorkflowDefinition.Task[] _tasks;
diff --git a/src/ConductorSharp.Engine/Builders/SimpleTaskBuilder.cs b/src/ConductorSharp.Engine/Builders/SimpleTaskBuilder.cs
index 19e5f0c9..a3547944 100644
--- a/src/ConductorSharp.Engine/Builders/SimpleTaskBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/SimpleTaskBuilder.cs
@@ -1,11 +1,30 @@
 ﻿using ConductorSharp.Client.Model.Common;
+using ConductorSharp.Engine.Interface;
 using ConductorSharp.Engine.Model;
 using MediatR;
 using Newtonsoft.Json.Linq;
+using System;
 using System.Linq.Expressions;
 
 namespace ConductorSharp.Engine.Builders
 {
+    public static class SimpleTaskExtensions
+    {
+        public static ITaskOptionsBuilder AddTask<TWorkflow, F, G>(
+            this WorkflowDefinitionBuilder<TWorkflow> builder,
+            Expression<Func<TWorkflow, SimpleTaskModel<F, G>>> refference,
+            Expression<Func<TWorkflow, F>> input,
+            AdditionalTaskParameters additionalParameters = null
+        )
+            where TWorkflow : ITypedWorkflow
+            where F : IRequest<G>
+        {
+            var taskBuilder = new SimpleTaskBuilder<F, G>(refference.Body, input.Body, additionalParameters);
+            builder.Context.TaskBuilders.Add(taskBuilder);
+            return taskBuilder;
+        }
+    }
+
     public class SimpleTaskBuilder<A, B> : BaseTaskBuilder<A, B> where A : IRequest<B>
     {
         public SimpleTaskBuilder(Expression taskExpression, Expression inputExpression, AdditionalTaskParameters additionalParameters)
diff --git a/src/ConductorSharp.Engine/Builders/SubWorkflowTaskBuilder.cs b/src/ConductorSharp.Engine/Builders/SubWorkflowTaskBuilder.cs
index 43d53afc..3049f0f4 100644
--- a/src/ConductorSharp.Engine/Builders/SubWorkflowTaskBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/SubWorkflowTaskBuilder.cs
@@ -1,12 +1,31 @@
 ﻿using ConductorSharp.Client.Model.Common;
+using ConductorSharp.Engine.Interface;
+using ConductorSharp.Engine.Model;
 using ConductorSharp.Engine.Util;
 using MediatR;
 using Newtonsoft.Json.Linq;
+using System;
 using System.Linq.Expressions;
 using System.Reflection;
 
 namespace ConductorSharp.Engine.Builders
 {
+    public static class SubWorkflowTaskExtensions
+    {
+        public static ITaskOptionsBuilder AddTask<TWorkflow, F, G>(
+            this WorkflowDefinitionBuilder<TWorkflow> builder,
+            Expression<Func<TWorkflow, SubWorkflowTaskModel<F, G>>> referrence,
+            Expression<Func<TWorkflow, F>> input
+        )
+            where TWorkflow : ITypedWorkflow
+            where F : IRequest<G>
+        {
+            var taskBuilder = new SubWorkflowTaskBuilder<F, G>(referrence.Body, input.Body);
+            builder.Context.TaskBuilders.Add(taskBuilder);
+            return taskBuilder;
+        }
+    }
+
     public class SubWorkflowTaskBuilder<TInput, TOutput> : BaseTaskBuilder<TInput, TOutput> where TInput : IRequest<TOutput>
     {
         private readonly int _version;
diff --git a/src/ConductorSharp.Engine/Builders/SwitchTaskBuilder.cs b/src/ConductorSharp.Engine/Builders/SwitchTaskBuilder.cs
index 363ff098..2b039538 100644
--- a/src/ConductorSharp.Engine/Builders/SwitchTaskBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/SwitchTaskBuilder.cs
@@ -10,6 +10,28 @@
 
 namespace ConductorSharp.Engine.Builders
 {
+    public static class SwitchTaskExtensions
+    {
+        public static ITaskOptionsBuilder AddTask<TWorkflow>(
+            this WorkflowDefinitionBuilder<TWorkflow> builder,
+            Expression<Func<TWorkflow, SwitchTaskModel>> taskSelector,
+            Expression<Func<TWorkflow, SwitchTaskInput>> expression,
+            params (string, Action<SwitchTaskBuilder<TWorkflow>>)[] caseActions
+        ) where TWorkflow : ITypedWorkflow
+        {
+            var taskBuilder = new SwitchTaskBuilder<TWorkflow>(taskSelector.Body, expression.Body);
+
+            foreach (var funcase in caseActions)
+            {
+                taskBuilder.AddCase(funcase.Item1);
+                funcase.Item2.Invoke(taskBuilder);
+            }
+
+            builder.Context.TaskBuilders.Add(taskBuilder);
+            return taskBuilder;
+        }
+    }
+
     public class SwitchTaskBuilder<TWorkflow> : BaseTaskBuilder<SwitchTaskInput, NoOutput> where TWorkflow : ITypedWorkflow
     {
         private Dictionary<string, ICollection<ITaskBuilder>> _caseDictionary = new();
diff --git a/src/ConductorSharp.Engine/Builders/TerminateTaskBuilder.cs b/src/ConductorSharp.Engine/Builders/TerminateTaskBuilder.cs
index 45c8693f..f3ebd0d1 100644
--- a/src/ConductorSharp.Engine/Builders/TerminateTaskBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/TerminateTaskBuilder.cs
@@ -1,4 +1,5 @@
 ﻿using ConductorSharp.Client.Model.Common;
+using ConductorSharp.Engine.Interface;
 using ConductorSharp.Engine.Model;
 using Newtonsoft.Json.Linq;
 using System;
@@ -8,6 +9,20 @@
 
 namespace ConductorSharp.Engine.Builders
 {
+    public static class TerminateTaskExtensions
+    {
+        public static ITaskOptionsBuilder AddTask<TWorkflow>(
+            this WorkflowDefinitionBuilder<TWorkflow> builder,
+            Expression<Func<TWorkflow, TerminateTaskModel>> reference,
+            Expression<Func<TWorkflow, TerminateTaskInput>> input
+        ) where TWorkflow : ITypedWorkflow
+        {
+            var taskBuilder = new TerminateTaskBuilder(reference.Body, input.Body);
+            builder.Context.TaskBuilders.Add(taskBuilder);
+            return taskBuilder;
+        }
+    }
+
     internal class TerminateTaskBuilder : BaseTaskBuilder<TerminateTaskInput, NoOutput>
     {
         public TerminateTaskBuilder(Expression taskExpression, Expression memberExpression) : base(taskExpression, memberExpression) { }
diff --git a/src/ConductorSharp.Engine/Builders/WorkflowDefinitionBuilder.cs b/src/ConductorSharp.Engine/Builders/WorkflowDefinitionBuilder.cs
index f1d1f6d1..c8d3897c 100644
--- a/src/ConductorSharp.Engine/Builders/WorkflowDefinitionBuilder.cs
+++ b/src/ConductorSharp.Engine/Builders/WorkflowDefinitionBuilder.cs
@@ -14,19 +14,23 @@
 
 namespace ConductorSharp.Engine.Builders
 {
+    public class DefinitionContext
+    {
+        public WorkflowOptions WorkflowOptions { get; } = new();
+
+        public List<ITaskBuilder> TaskBuilders { get; } = new();
+    }
+
     public class WorkflowDefinitionBuilder<TWorkflow> where TWorkflow : ITypedWorkflow
     {
         private readonly Type _workflowType;
         private string _name;
         private JObject _inputs = new();
-        private WorkflowOptions _workflowOptions;
-
-        private List<ITaskBuilder> _taskBuilders = new();
+        public DefinitionContext Context { get; } = new();
 
         public WorkflowDefinitionBuilder()
         {
             _workflowType = typeof(TWorkflow);
-            _workflowOptions = new WorkflowOptions();
 
             XmlDocumentationReader.LoadXmlDocumentation(_workflowType.Assembly);
             _name = NamingUtil.DetermineRegistrationName(_workflowType);
@@ -36,19 +40,19 @@ public WorkflowDefinitionBuilder()
             var ownerEmail = _workflowType.GetDocSection("ownerEmail");
             var labels = _workflowType.GetDocSection("labels");
 
-            _workflowOptions.Version = 1;
+            Context.WorkflowOptions.Version = 1;
 
             if (!string.IsNullOrEmpty(summary))
-                _workflowOptions.Description = summary;
+                Context.WorkflowOptions.Description = summary;
 
             if (!string.IsNullOrEmpty(ownerApp))
-                _workflowOptions.OwnerApp = ownerApp;
+                Context.WorkflowOptions.OwnerApp = ownerApp;
 
             if (!string.IsNullOrEmpty(ownerEmail))
-                _workflowOptions.OwnerEmail = ownerEmail;
+                Context.WorkflowOptions.OwnerEmail = ownerEmail;
 
             if (!string.IsNullOrEmpty(labels))
-                _workflowOptions.Labels = labels.Split(",").Select(a => a.Trim()).ToArray();
+                Context.WorkflowOptions.Labels = labels.Split(",").Select(a => a.Trim()).ToArray();
 
             var input = _workflowType.BaseType.GenericTypeArguments[0];
             var props = input.GetProperties();
@@ -72,104 +76,25 @@ public WorkflowDefinitionBuilder()
 
         public WorkflowDefinition Build(Action<WorkflowOptions> adjustOptions)
         {
-            adjustOptions.Invoke(_workflowOptions);
+            adjustOptions.Invoke(Context.WorkflowOptions);
 
             return new WorkflowDefinition
             {
                 Name = _name,
-                Tasks = _taskBuilders.SelectMany(a => a.Build()).ToList(),
+                Tasks = Context.TaskBuilders.SelectMany(a => a.Build()).ToList(),
                 FailureWorkflow =
-                    _workflowOptions.FailureWorkflow != null ? NamingUtil.DetermineRegistrationName(_workflowOptions.FailureWorkflow) : null,
+                    Context.WorkflowOptions.FailureWorkflow != null
+                        ? NamingUtil.DetermineRegistrationName(Context.WorkflowOptions.FailureWorkflow)
+                        : null,
                 Description = new JObject()
                 {
-                    new JProperty("description", _workflowOptions.Description),
-                    new JProperty("labels", _workflowOptions.Labels)
+                    new JProperty("description", Context.WorkflowOptions.Description),
+                    new JProperty("labels", Context.WorkflowOptions.Labels)
                 }.ToString(Formatting.None),
                 InputParameters = _inputs,
-                OwnerApp = _workflowOptions.OwnerApp,
-                OwnerEmail = _workflowOptions.OwnerEmail,
+                OwnerApp = Context.WorkflowOptions.OwnerApp,
+                OwnerEmail = Context.WorkflowOptions.OwnerEmail,
             };
         }
-
-        public ITaskOptionsBuilder AddTask<F, G>(
-            Expression<Func<TWorkflow, LambdaTaskModel<F, G>>> referrence,
-            Expression<Func<TWorkflow, F>> input,
-            string script
-        ) where F : IRequest<G> => AddAndReturnBuilder(new LambdaTaskBuilder<F, G>(script, referrence.Body, input.Body));
-
-        public ITaskOptionsBuilder AddTask<F, G>(
-            Expression<Func<TWorkflow, SubWorkflowTaskModel<F, G>>> referrence,
-            Expression<Func<TWorkflow, F>> input
-        ) where F : IRequest<G> => AddAndReturnBuilder(new SubWorkflowTaskBuilder<F, G>(referrence.Body, input.Body));
-
-        public ITaskOptionsBuilder AddTask(
-            Expression<Func<TWorkflow, DynamicForkJoinTaskModel>> refference,
-            Expression<Func<TWorkflow, DynamicForkJoinInput>> input
-        ) => AddAndReturnBuilder(new DynamicForkJoinTaskBuilder(refference.Body, input.Body));
-
-        public void AddTasks(params WorkflowDefinition.Task[] taskDefinitions) => _taskBuilders.Add(new PassThroughTaskBuilder(taskDefinitions));
-
-        public ITaskOptionsBuilder AddTask<F, G>(
-            Expression<Func<TWorkflow, SimpleTaskModel<F, G>>> refference,
-            Expression<Func<TWorkflow, F>> input,
-            AdditionalTaskParameters additionalParameters = null
-        ) where F : IRequest<G> => AddAndReturnBuilder(new SimpleTaskBuilder<F, G>(refference.Body, input.Body, additionalParameters));
-
-        public ITaskOptionsBuilder AddTask(
-            Expression<Func<TWorkflow, DecisionTaskModel>> taskSelector,
-            Expression<Func<TWorkflow, DecisionTaskInput>> expression,
-            params (string, Action<DecisionTaskBuilder<TWorkflow>>)[] caseActions
-        )
-        {
-            var builder = new DecisionTaskBuilder<TWorkflow>(taskSelector.Body, expression.Body);
-
-            foreach (var funcase in caseActions)
-            {
-                builder.AddCase(funcase.Item1);
-                funcase.Item2.Invoke(builder);
-            }
-
-            _taskBuilders.Add(builder);
-            return builder;
-        }
-
-        public ITaskOptionsBuilder AddTask(
-            Expression<Func<TWorkflow, SwitchTaskModel>> taskSelector,
-            Expression<Func<TWorkflow, SwitchTaskInput>> expression,
-            params (string, Action<SwitchTaskBuilder<TWorkflow>>)[] caseActions
-        )
-        {
-            var builder = new SwitchTaskBuilder<TWorkflow>(taskSelector.Body, expression.Body);
-
-            foreach (var funcase in caseActions)
-            {
-                builder.AddCase(funcase.Item1);
-                funcase.Item2.Invoke(builder);
-            }
-
-            _taskBuilders.Add(builder);
-            return builder;
-        }
-
-        public ITaskOptionsBuilder AddTask<F, G>(
-            Expression<Func<TWorkflow, JsonJqTransformTaskModel<F, G>>> refference,
-            Expression<Func<TWorkflow, F>> input
-        ) where F : IRequest<G> => AddAndReturnBuilder(new JsonJqTransformTaskBuilder<F, G>(refference.Body, input.Body));
-
-        public ITaskOptionsBuilder AddTask<F, G>(
-            Expression<Func<TWorkflow, DynamicTaskModel<F, G>>> reference,
-            Expression<Func<TWorkflow, DynamicTaskInput<F, G>>> input
-        ) => AddAndReturnBuilder(new DynamicTaskBuilder<F, G>(reference.Body, input.Body));
-
-        public ITaskOptionsBuilder AddTask(
-            Expression<Func<TWorkflow, TerminateTaskModel>> reference,
-            Expression<Func<TWorkflow, TerminateTaskInput>> input
-        ) => AddAndReturnBuilder(new TerminateTaskBuilder(reference.Body, input.Body));
-
-        private ITaskOptionsBuilder AddAndReturnBuilder<T>(T builder) where T : ITaskOptionsBuilder, ITaskBuilder
-        {
-            _taskBuilders.Add(builder);
-            return builder;
-        }
     }
 }
diff --git a/src/ConductorSharp.Engine/Extensions/ConductorSharpBuilder.cs b/src/ConductorSharp.Engine/Extensions/ConductorSharpBuilder.cs
index 2bca4b78..e58ef7ab 100644
--- a/src/ConductorSharp.Engine/Extensions/ConductorSharpBuilder.cs
+++ b/src/ConductorSharp.Engine/Extensions/ConductorSharpBuilder.cs
@@ -15,9 +15,9 @@ namespace ConductorSharp.Engine.Extensions
 {
     public class ConductorSharpBuilder : IConductorSharpBuilder, IExecutionManagerBuilder, IPipelineBuilder
     {
-        private readonly ContainerBuilder _builder;
+        public ContainerBuilder Builder { get; set; }
 
-        public ConductorSharpBuilder(ContainerBuilder builder) => _builder = builder;
+        public ConductorSharpBuilder(ContainerBuilder builder) => Builder = builder;
 
         public IExecutionManagerBuilder AddExecutionManager(int maxConcurrentWorkers, int sleepInterval, int longPollInterval, string domain = null)
         {
@@ -29,23 +29,23 @@ public IExecutionManagerBuilder AddExecutionManager(int maxConcurrentWorkers, in
                 SleepInterval = sleepInterval
             };
 
-            _builder.RegisterInstance(workerConfig).SingleInstance();
+            Builder.RegisterInstance(workerConfig).SingleInstance();
 
-            _builder.RegisterType<WorkflowEngineBackgroundService>().As<IHostedService>();
+            Builder.RegisterType<WorkflowEngineBackgroundService>().As<IHostedService>();
 
-            _builder.RegisterType<DeploymentService>().As<IDeploymentService>();
+            Builder.RegisterType<DeploymentService>().As<IDeploymentService>();
 
-            _builder.RegisterType<ModuleDeployment>();
+            Builder.RegisterType<ModuleDeployment>();
 
-            _builder.RegisterType<ExecutionManager>().SingleInstance();
+            Builder.RegisterType<ExecutionManager>().SingleInstance();
 
-            _builder.RegisterType<ConductorSharpExecutionContext>().InstancePerLifetimeScope();
+            Builder.RegisterType<ConductorSharpExecutionContext>().InstancePerLifetimeScope();
 
-            _builder.RegisterType<InMemoryHealthService>().As<IConductorSharpHealthService>().SingleInstance();
+            Builder.RegisterType<InMemoryHealthService>().As<IConductorSharpHealthService>().SingleInstance();
 
-            _builder.RegisterType<InverseExponentialBackoff>().As<IPollTimingStrategy>();
+            Builder.RegisterType<InverseExponentialBackoff>().As<IPollTimingStrategy>();
 
-            _builder.RegisterType<RandomOrdering>().As<IPollOrderStrategy>();
+            Builder.RegisterType<RandomOrdering>().As<IPollOrderStrategy>();
 
             return this;
         }
@@ -57,15 +57,15 @@ public IExecutionManagerBuilder AddPipelines(Action<IPipelineBuilder> behaviorBu
         }
 
         public void AddRequestResponseLogging() =>
-            _builder.RegisterGeneric(typeof(RequestResponseLoggingBehavior<,>)).As(typeof(IPipelineBehavior<,>));
+            Builder.RegisterGeneric(typeof(RequestResponseLoggingBehavior<,>)).As(typeof(IPipelineBehavior<,>));
 
-        public void AddValidation() => _builder.RegisterGeneric(typeof(ValidationBehavior<,>)).As(typeof(IPipelineBehavior<,>));
+        public void AddValidation() => Builder.RegisterGeneric(typeof(ValidationBehavior<,>)).As(typeof(IPipelineBehavior<,>));
 
-        public void AddContextLogging() => _builder.RegisterGeneric(typeof(ContextLoggingBehavior<,>)).As(typeof(IPipelineBehavior<,>));
+        public void AddContextLogging() => Builder.RegisterGeneric(typeof(ContextLoggingBehavior<,>)).As(typeof(IPipelineBehavior<,>));
 
         public IExecutionManagerBuilder SetHealthCheckService<T>() where T : IConductorSharpHealthService
         {
-            _builder.RegisterType<T>().As<IConductorSharpHealthService>().SingleInstance();
+            Builder.RegisterType<T>().As<IConductorSharpHealthService>().SingleInstance();
             return this;
         }
     }
diff --git a/src/ConductorSharp.Engine/Extensions/IExecutionManagerBuilder.cs b/src/ConductorSharp.Engine/Extensions/IExecutionManagerBuilder.cs
index f758aff4..9d7fc588 100644
--- a/src/ConductorSharp.Engine/Extensions/IExecutionManagerBuilder.cs
+++ b/src/ConductorSharp.Engine/Extensions/IExecutionManagerBuilder.cs
@@ -1,4 +1,5 @@
-﻿using ConductorSharp.Engine.Health;
+﻿using Autofac;
+using ConductorSharp.Engine.Health;
 using System;
 using System.Collections.Generic;
 using System.Text;
@@ -7,6 +8,7 @@ namespace ConductorSharp.Engine.Extensions
 {
     public interface IExecutionManagerBuilder
     {
+        ContainerBuilder Builder { get; set; }
         IExecutionManagerBuilder AddPipelines(Action<IPipelineBuilder> pipelines);
         IExecutionManagerBuilder SetHealthCheckService<T>() where T : IConductorSharpHealthService;
     }
diff --git a/src/ConductorSharp.Patterns/ConductorSharp.Patterns.csproj b/src/ConductorSharp.Patterns/ConductorSharp.Patterns.csproj
new file mode 100644
index 00000000..7cfa0d0b
--- /dev/null
+++ b/src/ConductorSharp.Patterns/ConductorSharp.Patterns.csproj
@@ -0,0 +1,18 @@
+﻿<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netstandard2.1</TargetFramework>
+    <Nullable>disable</Nullable>
+  </PropertyGroup>
+
+	<ItemGroup>
+		<PackageReference Include="Autofac" Version="6.3.0" />
+		<PackageReference Include="MediatR" Version="10.0.1" />
+		<PackageReference Include="MediatR.Extensions.Autofac.DependencyInjection" Version="8.0.1" />
+	</ItemGroup>
+
+	<ItemGroup>
+	  <ProjectReference Include="..\ConductorSharp.Engine\ConductorSharp.Engine.csproj" />
+	</ItemGroup>
+
+</Project>
diff --git a/src/ConductorSharp.Patterns/Constants.cs b/src/ConductorSharp.Patterns/Constants.cs
new file mode 100644
index 00000000..3924daf2
--- /dev/null
+++ b/src/ConductorSharp.Patterns/Constants.cs
@@ -0,0 +1,11 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ConductorSharp.Patterns
+{
+    public static class Constants
+    {
+        public const string TaskNamePrefix = "CSH_PATTERNS";
+    }
+}
diff --git a/src/ConductorSharp.Patterns/Extensions/ContainerBuilderExtensions.cs b/src/ConductorSharp.Patterns/Extensions/ContainerBuilderExtensions.cs
new file mode 100644
index 00000000..0900dd02
--- /dev/null
+++ b/src/ConductorSharp.Patterns/Extensions/ContainerBuilderExtensions.cs
@@ -0,0 +1,21 @@
+﻿using ConductorSharp.Engine.Extensions;
+using ConductorSharp.Patterns.Tasks;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MediatR.Extensions.Autofac.DependencyInjection;
+
+namespace ConductorSharp.Patterns.Extensions
+{
+    public static class ContainerBuilderExtensions
+    {
+        public static IExecutionManagerBuilder AddConductorSharpPatterns(this IExecutionManagerBuilder executionManagerBuilder)
+        {
+            executionManagerBuilder.Builder.RegisterWorkerTask<ReadWorkflowTasks>();
+            executionManagerBuilder.Builder.RegisterWorkerTask<WaitSeconds>();
+            executionManagerBuilder.Builder.RegisterMediatR(typeof(WaitSeconds).Assembly);
+
+            return executionManagerBuilder;
+        }
+    }
+}
diff --git a/src/ConductorSharp.Patterns/Tasks/ReadWorkflowTasks.cs b/src/ConductorSharp.Patterns/Tasks/ReadWorkflowTasks.cs
new file mode 100644
index 00000000..d3613005
--- /dev/null
+++ b/src/ConductorSharp.Patterns/Tasks/ReadWorkflowTasks.cs
@@ -0,0 +1,102 @@
+﻿using ConductorSharp.Client.Service;
+using ConductorSharp.Engine;
+using ConductorSharp.Engine.Util;
+using MediatR;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ConductorSharp.Patterns.Tasks
+{
+    #region models
+    public class ReadWorkflowTasksRequest : IRequest<ReadWorkflowTasksResponse>
+    {
+        /// <summary>
+        /// Comma separated list of task reference names to be read from specified workflow
+        /// </summary>
+        [Required]
+        public string TaskNames { get; set; }
+
+        /// <summary>
+        /// Id of the workflow to read tasks from
+        /// </summary>
+        [Required]
+        public string WorkflowId { get; set; }
+    }
+
+    public class ReadWorkflowTasksResponse
+    {
+        public Dictionary<string, TaskExecutionDetails> Tasks { get; set; }
+        public WorkflowDetails Workflow { get; set; }
+    }
+
+    public class WorkflowDetails
+    {
+        public JObject InputData { get; set; }
+    }
+
+    public class TaskExecutionDetails
+    {
+        [JsonProperty("inputData")]
+        public JObject InputData { get; set; } = new JObject();
+
+        [JsonProperty("outputData")]
+        public JObject OutputData { get; set; } = new JObject();
+
+        [JsonProperty("referenceTaskName")]
+        public string ReferenceTaskName { get; set; }
+
+        [JsonProperty("status")]
+        public string Status { get; set; } = "NOT_FOUND";
+    }
+    #endregion
+    /// <summary>
+    /// Uses the Conductor API to read the input/output and status of the specified tasks for the specified workflow.
+    /// </summary>
+    [OriginalName(Constants.TaskNamePrefix + "_read_tasks")]
+    public class ReadWorkflowTasks : TaskRequestHandler<ReadWorkflowTasksRequest, ReadWorkflowTasksResponse>
+    {
+        private readonly ILogger<ReadWorkflowTasks> _logger;
+        private readonly IWorkflowService _workflowService;
+
+        public ReadWorkflowTasks(ILogger<ReadWorkflowTasks> logger, IWorkflowService workflowService)
+        {
+            _logger = logger;
+            _workflowService = workflowService;
+        }
+
+        public async override Task<ReadWorkflowTasksResponse> Handle(ReadWorkflowTasksRequest input, CancellationToken cancellationToken)
+        {
+            if (string.IsNullOrEmpty(input.TaskNames))
+                throw new Exception("No task names provided. Comma separated list of reference names expected");
+
+            var tasknames = input.TaskNames.Split(",").Where(a => !string.IsNullOrEmpty(a)).ToList();
+
+            var starterWorkflow = await _workflowService.GetWorkflowStatus(input.WorkflowId);
+
+            if (starterWorkflow == null)
+                throw new Exception($"Could not find starter workflow by id {input.WorkflowId}");
+
+            var taskData = starterWorkflow.SelectToken("tasks").ToObject<List<TaskExecutionDetails>>();
+
+            var output = new ReadWorkflowTasksResponse
+            {
+                Workflow = new WorkflowDetails { InputData = starterWorkflow.SelectToken("input") as JObject },
+                Tasks = new Dictionary<string, TaskExecutionDetails>()
+            };
+
+            foreach (var task in tasknames)
+            {
+                output.Tasks.Add(task, taskData.FirstOrDefault(a => a.ReferenceTaskName == task) ?? new TaskExecutionDetails());
+            }
+
+            return output;
+        }
+    }
+}
diff --git a/src/ConductorSharp.Patterns/Tasks/WaitSeconds.cs b/src/ConductorSharp.Patterns/Tasks/WaitSeconds.cs
new file mode 100644
index 00000000..e4b8cb20
--- /dev/null
+++ b/src/ConductorSharp.Patterns/Tasks/WaitSeconds.cs
@@ -0,0 +1,41 @@
+﻿using ConductorSharp.Engine;
+using ConductorSharp.Engine.Model;
+using ConductorSharp.Engine.Util;
+using MediatR;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace ConductorSharp.Patterns.Tasks
+{
+    public class WaitSecondsRequest : IRequest<NoOutput>
+    {
+        /// <summary>
+        /// Time to wait in seconds
+        /// </summary>
+        [Required]
+        [Range(1, int.MaxValue)]
+        public int Seconds { get; set; }
+    }
+
+    /// <summary>
+    /// Executes `await Task.Delay(input.Seconds * 1000)` to wait for a given amount of seconds
+    /// </summary>
+    [OriginalName(Constants.TaskNamePrefix + "_wait_seconds")]
+    public class WaitSeconds : TaskRequestHandler<WaitSecondsRequest, NoOutput>
+    {
+        private readonly ILogger<WaitSeconds> _logger;
+
+        public WaitSeconds(ILogger<WaitSeconds> logger) => _logger = logger;
+
+        public async override Task<NoOutput> Handle(WaitSecondsRequest input, CancellationToken cancellationToken)
+        {
+            await Task.Delay(input.Seconds * 1000);
+            return new NoOutput();
+        }
+    }
+}
diff --git a/test/ConductorSharp.Engine.Tests/ConductorSharp.Engine.Tests.csproj b/test/ConductorSharp.Engine.Tests/ConductorSharp.Engine.Tests.csproj
index 09c8ee6f..abadcacd 100644
--- a/test/ConductorSharp.Engine.Tests/ConductorSharp.Engine.Tests.csproj
+++ b/test/ConductorSharp.Engine.Tests/ConductorSharp.Engine.Tests.csproj
@@ -15,6 +15,7 @@
     <None Remove="Samples\Workflows\DynamicTask.json" />
     <None Remove="Samples\Workflows\NestedObjects.json" />
     <None Remove="Samples\Workflows\OptionalTaskWorkflow.json" />
+    <None Remove="Samples\Workflows\PatternTasks.json" />
     <None Remove="Samples\Workflows\ScaffoldedWorkflows.json" />
     <None Remove="Samples\Workflows\SendCustomerNotification.json" />
     <None Remove="Samples\Workflows\StringInterpolation.json" />
@@ -31,6 +32,7 @@
     <EmbeddedResource Include="Samples\Tasks\EmailPrepare.json" />
     <EmbeddedResource Include="Samples\Workflows\Arrays.json" />
     <EmbeddedResource Include="Samples\Workflows\DynamicTask.json" />
+    <EmbeddedResource Include="Samples\Workflows\PatternTasks.json" />
     <EmbeddedResource Include="Samples\Workflows\ScaffoldedWorkflows.json" />
     <EmbeddedResource Include="Samples\Workflows\OptionalTaskWorkflow.json" />
     <EmbeddedResource Include="Samples\Workflows\NestedObjects.json" />
@@ -55,6 +57,7 @@
 
   <ItemGroup>
     <ProjectReference Include="..\..\src\ConductorSharp.Engine\ConductorSharp.Engine.csproj" />
+    <ProjectReference Include="..\..\src\ConductorSharp.Patterns\ConductorSharp.Patterns.csproj" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/test/ConductorSharp.Engine.Tests/Integration/WorkflowBuilderTests.cs b/test/ConductorSharp.Engine.Tests/Integration/WorkflowBuilderTests.cs
index a724a325..3c095244 100644
--- a/test/ConductorSharp.Engine.Tests/Integration/WorkflowBuilderTests.cs
+++ b/test/ConductorSharp.Engine.Tests/Integration/WorkflowBuilderTests.cs
@@ -114,5 +114,14 @@ public void BuilderReturnsCorrectDefinitionSubworkflowVersionAttribute()
 
             Assert.Equal(expectedDefinition, definition);
         }
+
+        [Fact]
+        public void BuilderReturnsCorrectDefinitionPatternTasks()
+        {
+            var definition = SerializationUtil.SerializeObject(new PatternTasks().GetDefinition());
+            var expectedDefinition = EmbeddedFileHelper.GetLinesFromEmbeddedFile("~/Samples/Workflows/PatternTasks.json");
+
+            Assert.Equal(expectedDefinition, definition);
+        }
     }
 }
diff --git a/test/ConductorSharp.Engine.Tests/Samples/Workflows/PatternTasks.cs b/test/ConductorSharp.Engine.Tests/Samples/Workflows/PatternTasks.cs
new file mode 100644
index 00000000..828629ac
--- /dev/null
+++ b/test/ConductorSharp.Engine.Tests/Samples/Workflows/PatternTasks.cs
@@ -0,0 +1,34 @@
+﻿using ConductorSharp.Patterns.Tasks;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ConductorSharp.Engine.Tests.Samples.Workflows
+{
+    public class PatternTasksInput : WorkflowInput<PatternTasksOutput>
+    {
+        public int Seconds { get; set; }
+        public string WorkflowId { get; set; }
+    }
+
+    public class PatternTasksOutput : WorkflowOutput { }
+
+    public class PatternTasks : Workflow<PatternTasksInput, PatternTasksOutput>
+    {
+        public WaitSeconds WaitSeconds { get; set; }
+        public ReadWorkflowTasks ReadWorkflowTasks { get; set; }
+
+        public override WorkflowDefinition GetDefinition()
+        {
+            var builder = new WorkflowDefinitionBuilder<PatternTasks>();
+
+            builder.AddTask(wf => wf.ReadWorkflowTasks, wf => new() { TaskNames = "task1,task2", WorkflowId = wf.WorkflowInput.WorkflowId });
+
+            builder.AddTask(wf => wf.WaitSeconds, wf => new() { Seconds = wf.WorkflowInput.Seconds });
+
+            return builder.Build(opts => opts.Version = 1);
+        }
+    }
+}
diff --git a/test/ConductorSharp.Engine.Tests/Samples/Workflows/PatternTasks.json b/test/ConductorSharp.Engine.Tests/Samples/Workflows/PatternTasks.json
new file mode 100644
index 00000000..c8edf93f
--- /dev/null
+++ b/test/ConductorSharp.Engine.Tests/Samples/Workflows/PatternTasks.json
@@ -0,0 +1,91 @@
+{
+  "ownerApp": null,
+  "createTime": 0,
+  "updateTime": 0,
+  "createdBy": null,
+  "updatedBy": null,
+  "name": "pattern_tasks",
+  "description": "{\"description\":null,\"labels\":null}",
+  "version": 1,
+  "tasks": [
+    {
+      "queryExpression": null,
+      "name": "CSH_PATTERNS_read_tasks",
+      "taskReferenceName": "read_workflow_tasks",
+      "description": "{\"description\":null}",
+      "inputParameters": {
+        "task_names": "task1,task2",
+        "workflow_id": "${workflow.input.workflow_id}"
+      },
+      "type": "SIMPLE",
+      "dynamicTaskNameParam": null,
+      "caseValueParam": null,
+      "caseExpression": null,
+      "expression": null,
+      "evaluatorType": null,
+      "scriptExpression": null,
+      "decisionCases": null,
+      "dynamicForkJoinTasksParam": null,
+      "dynamicForkTasksParam": null,
+      "dynamicForkTasksInputParamName": null,
+      "defaultCase": null,
+      "forkTasks": null,
+      "startDelay": 0,
+      "subWorkflowParam": null,
+      "joinOn": null,
+      "sink": null,
+      "optional": false,
+      "taskDefinition": null,
+      "rateLimited": false,
+      "defaultExclusiveJoinTask": null,
+      "asyncComplete": false,
+      "loopCondition": null,
+      "loopOver": null
+    },
+    {
+      "queryExpression": null,
+      "name": "CSH_PATTERNS_wait_seconds",
+      "taskReferenceName": "wait_seconds",
+      "description": "{\"description\":null}",
+      "inputParameters": {
+        "seconds": "${workflow.input.seconds}"
+      },
+      "type": "SIMPLE",
+      "dynamicTaskNameParam": null,
+      "caseValueParam": null,
+      "caseExpression": null,
+      "expression": null,
+      "evaluatorType": null,
+      "scriptExpression": null,
+      "decisionCases": null,
+      "dynamicForkJoinTasksParam": null,
+      "dynamicForkTasksParam": null,
+      "dynamicForkTasksInputParamName": null,
+      "defaultCase": null,
+      "forkTasks": null,
+      "startDelay": 0,
+      "subWorkflowParam": null,
+      "joinOn": null,
+      "sink": null,
+      "optional": false,
+      "taskDefinition": null,
+      "rateLimited": false,
+      "defaultExclusiveJoinTask": null,
+      "asyncComplete": false,
+      "loopCondition": null,
+      "loopOver": null
+    }
+  ],
+  "inputParameters": [
+    "{\"seconds\":{\"value\":\"\",\"description\":\" (optional)\"},\"workflow_id\":{\"value\":\"\",\"description\":\" (optional)\"}}"
+  ],
+  "outputParameters": null,
+  "failureWorkflow": null,
+  "schemaVersion": 2,
+  "restartable": true,
+  "workflowStatusListenerEnabled": true,
+  "ownerEmail": null,
+  "timeoutPolicy": null,
+  "timeoutSeconds": 0,
+  "variables": null
+}
\ No newline at end of file
diff --git a/test/ConductorSharp.Engine.Tests/Util/EmbeddedFileHelper.cs b/test/ConductorSharp.Engine.Tests/Util/EmbeddedFileHelper.cs
index a937117f..83c8a821 100644
--- a/test/ConductorSharp.Engine.Tests/Util/EmbeddedFileHelper.cs
+++ b/test/ConductorSharp.Engine.Tests/Util/EmbeddedFileHelper.cs
@@ -5,7 +5,7 @@
 using System.Text;
 using System.Threading.Tasks;
 
-namespace ConductorSharp.Engine.Util
+namespace ConductorSharp.Engine.Tests.Util
 {
     internal static class EmbeddedFileHelper
     {
