From cf0ba16850c34a052825fd8fd72b62175f80f67c Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Fri, 12 Aug 2022 13:53:14 +0200
Subject: [PATCH 01/37] Add CommandLinerParser package

---
 src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj b/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj
index bdc8bcc6..ef267054 100644
--- a/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj
+++ b/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj
@@ -25,6 +25,7 @@
 
   <ItemGroup>
     <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
+    <PackageReference Include="CommandLineParser" Version="2.9.1" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
     <PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
   </ItemGroup>

From 2f25eee7aed7744b7820b650e469949b42c4f1b3 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sat, 13 Aug 2022 22:09:38 +0200
Subject: [PATCH 02/37] Rename class

---
 src/ConductorSharp.Toolkit/Commands/Command.cs                  | 2 +-
 src/ConductorSharp.Toolkit/Commands/ScaffoldCommand.cs          | 2 +-
 .../Models/{CommandInput.cs => Configuration.cs}                | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
 rename src/ConductorSharp.Toolkit/Models/{CommandInput.cs => Configuration.cs} (89%)

diff --git a/src/ConductorSharp.Toolkit/Commands/Command.cs b/src/ConductorSharp.Toolkit/Commands/Command.cs
index 165f6e79..d05dc612 100644
--- a/src/ConductorSharp.Toolkit/Commands/Command.cs
+++ b/src/ConductorSharp.Toolkit/Commands/Command.cs
@@ -5,6 +5,6 @@ namespace ConductorSharp.Toolkit.Commands
     public interface Command
     {
         public string GetName();
-        public Task Execute(CommandInput input);
+        public Task Execute(Configuration input);
     }
 }
diff --git a/src/ConductorSharp.Toolkit/Commands/ScaffoldCommand.cs b/src/ConductorSharp.Toolkit/Commands/ScaffoldCommand.cs
index 39159cde..7e20f868 100644
--- a/src/ConductorSharp.Toolkit/Commands/ScaffoldCommand.cs
+++ b/src/ConductorSharp.Toolkit/Commands/ScaffoldCommand.cs
@@ -14,7 +14,7 @@ public ScaffoldCommand(IScaffoldingService scaffoldingService)
 
         public string GetName() => "scaffold";
 
-        public async Task Execute(CommandInput input)
+        public async Task Execute(Configuration input)
         {
             await _scaffoldingService.Scaffold();
         }
diff --git a/src/ConductorSharp.Toolkit/Models/CommandInput.cs b/src/ConductorSharp.Toolkit/Models/Configuration.cs
similarity index 89%
rename from src/ConductorSharp.Toolkit/Models/CommandInput.cs
rename to src/ConductorSharp.Toolkit/Models/Configuration.cs
index 19b2d75d..8e3fc3ae 100644
--- a/src/ConductorSharp.Toolkit/Models/CommandInput.cs
+++ b/src/ConductorSharp.Toolkit/Models/Configuration.cs
@@ -1,6 +1,6 @@
 ﻿namespace ConductorSharp.Toolkit.Models
 {
-    public class CommandInput
+    public class Configuration
     {
         public string Api { get; set; }
         public string Namespace { get; set; }

From 4936d04a62f188dd51348acf0a1988bfa30dc4c5 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sat, 13 Aug 2022 22:20:02 +0200
Subject: [PATCH 03/37] Add YamlDotNet package

---
 src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj b/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj
index ef267054..e94e30a4 100644
--- a/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj
+++ b/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj
@@ -28,6 +28,7 @@
     <PackageReference Include="CommandLineParser" Version="2.9.1" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
     <PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
+    <PackageReference Include="YamlDotNet" Version="12.0.0" />
   </ItemGroup>
 
   <ItemGroup>

From 297ec15c05ec8fec767215901c448a03fa412aa1 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sat, 13 Aug 2022 22:20:25 +0200
Subject: [PATCH 04/37] Integrate command line parser library

---
 .../Models/ToolkitOptions.cs                  | 10 +++
 src/ConductorSharp.Toolkit/Program.cs         | 68 +++++++++++++++----
 2 files changed, 64 insertions(+), 14 deletions(-)
 create mode 100644 src/ConductorSharp.Toolkit/Models/ToolkitOptions.cs

diff --git a/src/ConductorSharp.Toolkit/Models/ToolkitOptions.cs b/src/ConductorSharp.Toolkit/Models/ToolkitOptions.cs
new file mode 100644
index 00000000..7ec10c4f
--- /dev/null
+++ b/src/ConductorSharp.Toolkit/Models/ToolkitOptions.cs
@@ -0,0 +1,10 @@
+﻿using CommandLine;
+
+namespace ConductorSharp.Toolkit.Models
+{
+    public class ToolkitOptions
+    {
+        [Option('f', "file", HelpText = "Configuration file", Default = "conductorsharp.yaml")]
+        public string ConfiugrationFilePath { get; set; }
+    }
+}
diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index f5ddbf01..6f297297 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -4,6 +4,11 @@
 using ConductorSharp.Engine.Extensions;
 using ConductorSharp.Toolkit.Commands;
 using ConductorSharp.Toolkit.Models;
+using CommandLine;
+using CommandLine.Text;
+using System.Reflection;
+using YamlDotNet.Serialization;
+using YamlDotNet.Serialization.NamingConventions;
 
 namespace ConductorSharp.Toolkit
 {
@@ -11,29 +16,64 @@ class Program
     {
         public async static Task Main(string[] args)
         {
-            try
+            var parseResult = new Parser(opts => opts.HelpWriter = null).ParseArguments<ToolkitOptions>(args);
+            var withParsed = await parseResult.WithParsedAsync(Scaffold);
+            withParsed.WithNotParsed(err =>
             {
-                var action = args[0];
+                var versionText = new HeadingInfo("conductorsharp", GetVersionString());
+                var writer = err.IsHelp() || err.IsVersion() ? Console.Out : Console.Error;
+                string textToWrite;
+                if (err.IsVersion())
+                    textToWrite = versionText;
+                else
+                {
+                    textToWrite = HelpText.AutoBuild(
+                        parseResult,
+                        help =>
+                        {
+                            help.AddPreOptionsLine("Usage: dotnet conductorsharp [options]");
+                            help.Heading = versionText;
+                            return help;
+                        }
+                    );
+                }
 
-                var input = ParseInput(args);
+                writer.WriteLine(textToWrite);
+            });
+        }
 
-                var container = BuildContainer(input);
+        private static string GetVersionString()
+        {
+            var version = Assembly.GetExecutingAssembly().GetName().Version;
 
-                var commandRegistry = container.Resolve<CommandRegistry>();
+            return $"version {version.Major}.{version.Minor}.{version.Build}";
+        }
 
-                var command = commandRegistry.Get(action);
+        private static async Task Scaffold(ToolkitOptions options)
+        {
+            Console.WriteLine(options.ConfiugrationFilePath);
 
-                await command.Execute(input);
-            }
-            catch (Exception exc)
+            if (!File.Exists(options.ConfiugrationFilePath))
             {
-                PrintHelp();
+                Console.Error.WriteLine($"Configuration file {options.ConfiugrationFilePath} does not exists");
+                return;
             }
+
+            var config = await ParseConfigurationFile(options.ConfiugrationFilePath);
+            var container = BuildContainer(config);
+            var commandRegistry = container.Resolve<CommandRegistry>();
+            // Currently only scaffolding is supported
+            var command = commandRegistry.Get("scaffold");
+            await command.Execute(config);
         }
 
-        private static void PrintHelp() => Console.WriteLine("PLACEHOLDER HELP");
+        private static async Task<Configuration> ParseConfigurationFile(string configFilePath) =>
+            new DeserializerBuilder()
+                .WithNamingConvention(CamelCaseNamingConvention.Instance)
+                .Build()
+                .Deserialize<Configuration>(await File.ReadAllTextAsync(configFilePath));
 
-        private static IContainer BuildContainer(CommandInput input)
+        private static IContainer BuildContainer(Configuration input)
         {
             var serviceCollection = new ServiceCollection();
 
@@ -57,12 +97,12 @@ private static IContainer BuildContainer(CommandInput input)
             return builder.Build();
         }
 
-        private static CommandInput ParseInput(string[] args)
+        private static Configuration ParseInput(string[] args)
         {
             var action = args[0];
             var inputParameters = args.Skip(1).Select(a => new KeyValuePair<string, string>(a.Split("=")[0], a.Split("=")[1])).ToList();
 
-            return new CommandInput
+            return new Configuration
             {
                 Api = inputParameters.Where(a => a.Key == "path").Select(a => a.Value).FirstOrDefault(),
                 Namespace = inputParameters.Where(a => a.Key == "namespace").Select(a => a.Value).FirstOrDefault(),

From e24abc69697aed03f9da0ed164021490cf184ba7 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sat, 13 Aug 2022 22:20:58 +0200
Subject: [PATCH 05/37] Rename method

---
 src/ConductorSharp.Toolkit/Program.cs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index 6f297297..d9567267 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -17,7 +17,7 @@ class Program
         public async static Task Main(string[] args)
         {
             var parseResult = new Parser(opts => opts.HelpWriter = null).ParseArguments<ToolkitOptions>(args);
-            var withParsed = await parseResult.WithParsedAsync(Scaffold);
+            var withParsed = await parseResult.WithParsedAsync(RunToolkit);
             withParsed.WithNotParsed(err =>
             {
                 var versionText = new HeadingInfo("conductorsharp", GetVersionString());
@@ -49,7 +49,7 @@ private static string GetVersionString()
             return $"version {version.Major}.{version.Minor}.{version.Build}";
         }
 
-        private static async Task Scaffold(ToolkitOptions options)
+        private static async Task RunToolkit(ToolkitOptions options)
         {
             Console.WriteLine(options.ConfiugrationFilePath);
 

From d17e52373abbf98904e16846f90629e87d454fd6 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sat, 13 Aug 2022 22:21:15 +0200
Subject: [PATCH 06/37] Remove unnecessary function

---
 src/ConductorSharp.Toolkit/Program.cs | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index d9567267..ffea96d0 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -96,20 +96,5 @@ private static IContainer BuildContainer(Configuration input)
 
             return builder.Build();
         }
-
-        private static Configuration ParseInput(string[] args)
-        {
-            var action = args[0];
-            var inputParameters = args.Skip(1).Select(a => new KeyValuePair<string, string>(a.Split("=")[0], a.Split("=")[1])).ToList();
-
-            return new Configuration
-            {
-                Api = inputParameters.Where(a => a.Key == "path").Select(a => a.Value).FirstOrDefault(),
-                Namespace = inputParameters.Where(a => a.Key == "namespace").Select(a => a.Value).FirstOrDefault(),
-                Host = inputParameters.Where(a => a.Key == "host").Select(a => a.Value).FirstOrDefault(),
-                Dryrun = inputParameters.Where(a => a.Key == "dryrun").Select(a => bool.Parse(a.Value)).FirstOrDefault(),
-                Destination = inputParameters.Where(a => a.Key == "destination").Select(a => a.Value).FirstOrDefault()
-            };
-        }
     }
 }

From 6072a95e74396ca61908fd4103c623953d9df6a7 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sat, 13 Aug 2022 22:24:15 +0200
Subject: [PATCH 07/37] Rename properties

---
 src/ConductorSharp.Toolkit/Models/Configuration.cs | 4 ++--
 src/ConductorSharp.Toolkit/Program.cs              | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Models/Configuration.cs b/src/ConductorSharp.Toolkit/Models/Configuration.cs
index 8e3fc3ae..dac5ddc0 100644
--- a/src/ConductorSharp.Toolkit/Models/Configuration.cs
+++ b/src/ConductorSharp.Toolkit/Models/Configuration.cs
@@ -2,9 +2,9 @@
 {
     public class Configuration
     {
-        public string Api { get; set; }
+        public string ApiPath { get; set; }
         public string Namespace { get; set; }
-        public string Host { get; set; }
+        public string BaseUrl { get; set; }
         public bool Dryrun { get; set; }
         public string Destination { get; set; }
     }
diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index ffea96d0..e8000ad6 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -83,15 +83,15 @@ private static IContainer BuildContainer(Configuration input)
 
             serviceCollection.Configure<ScaffoldingConfig>(config =>
             {
-                config.ApiUrl = input.Api;
-                config.BaseUrl = input.Host;
+                config.ApiUrl = input.ApiPath;
+                config.BaseUrl = input.BaseUrl;
                 config.BaseNamespace = input.Namespace;
                 config.Dryrun = input.Dryrun;
                 config.Destination = input.Destination;
             });
 
             builder.Populate(serviceCollection);
-            builder.AddWorkflowEngine(input.Host, input.Api);
+            builder.AddWorkflowEngine(input.BaseUrl, input.ApiPath);
             builder.RegisterModule(new ToolkitModule());
 
             return builder.Build();

From 9206b5da0deb2ff590a91c5beac6a71fab6c28a5 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sat, 13 Aug 2022 22:29:17 +0200
Subject: [PATCH 08/37] Remove unnecessary property

---
 src/ConductorSharp.Toolkit/Models/Configuration.cs | 8 +++++++-
 src/ConductorSharp.Toolkit/Program.cs              | 1 -
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Models/Configuration.cs b/src/ConductorSharp.Toolkit/Models/Configuration.cs
index dac5ddc0..1ec0615f 100644
--- a/src/ConductorSharp.Toolkit/Models/Configuration.cs
+++ b/src/ConductorSharp.Toolkit/Models/Configuration.cs
@@ -2,10 +2,16 @@
 {
     public class Configuration
     {
+        public class Header
+        {
+            public string Name { get; set; }
+            public string Value { get; set; }
+        }
+
         public string ApiPath { get; set; }
         public string Namespace { get; set; }
         public string BaseUrl { get; set; }
-        public bool Dryrun { get; set; }
         public string Destination { get; set; }
+        public Header[] Headers { get; set; }
     }
 }
diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index e8000ad6..55b75471 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -86,7 +86,6 @@ private static IContainer BuildContainer(Configuration input)
                 config.ApiUrl = input.ApiPath;
                 config.BaseUrl = input.BaseUrl;
                 config.BaseNamespace = input.Namespace;
-                config.Dryrun = input.Dryrun;
                 config.Destination = input.Destination;
             });
 

From 0e4429a202493ea52fccf3a315e0b47eaa2470e1 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sat, 13 Aug 2022 22:42:06 +0200
Subject: [PATCH 09/37] Remove unnecessary class

---
 src/ConductorSharp.Toolkit/Models/Configuration.cs | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Models/Configuration.cs b/src/ConductorSharp.Toolkit/Models/Configuration.cs
index 1ec0615f..04a4380b 100644
--- a/src/ConductorSharp.Toolkit/Models/Configuration.cs
+++ b/src/ConductorSharp.Toolkit/Models/Configuration.cs
@@ -2,16 +2,10 @@
 {
     public class Configuration
     {
-        public class Header
-        {
-            public string Name { get; set; }
-            public string Value { get; set; }
-        }
-
         public string ApiPath { get; set; }
         public string Namespace { get; set; }
         public string BaseUrl { get; set; }
         public string Destination { get; set; }
-        public Header[] Headers { get; set; }
+        public Dictionary<string, string> Headers { get; set; } = new Dictionary<string, string>();
     }
 }

From 8957a71ffa52899fc2a97f0da25220e035f5e58b Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sat, 13 Aug 2022 22:53:14 +0200
Subject: [PATCH 10/37] Pass headers to client

---
 src/ConductorSharp.Toolkit/Program.cs | 28 ++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index 55b75471..bbfc1a49 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -9,6 +9,8 @@
 using System.Reflection;
 using YamlDotNet.Serialization;
 using YamlDotNet.Serialization.NamingConventions;
+using RestSharp;
+using RestSharp.Serializers.NewtonsoftJson;
 
 namespace ConductorSharp.Toolkit
 {
@@ -51,8 +53,6 @@ private static string GetVersionString()
 
         private static async Task RunToolkit(ToolkitOptions options)
         {
-            Console.WriteLine(options.ConfiugrationFilePath);
-
             if (!File.Exists(options.ConfiugrationFilePath))
             {
                 Console.Error.WriteLine($"Configuration file {options.ConfiugrationFilePath} does not exists");
@@ -73,7 +73,7 @@ private static async Task<Configuration> ParseConfigurationFile(string configFil
                 .Build()
                 .Deserialize<Configuration>(await File.ReadAllTextAsync(configFilePath));
 
-        private static IContainer BuildContainer(Configuration input)
+        private static IContainer BuildContainer(Configuration config)
         {
             var serviceCollection = new ServiceCollection();
 
@@ -81,16 +81,26 @@ private static IContainer BuildContainer(Configuration input)
 
             var builder = new ContainerBuilder();
 
-            serviceCollection.Configure<ScaffoldingConfig>(config =>
+            serviceCollection.Configure<ScaffoldingConfig>(scaffoldingConfig =>
             {
-                config.ApiUrl = input.ApiPath;
-                config.BaseUrl = input.BaseUrl;
-                config.BaseNamespace = input.Namespace;
-                config.Destination = input.Destination;
+                scaffoldingConfig.ApiUrl = config.ApiPath;
+                scaffoldingConfig.BaseUrl = config.BaseUrl;
+                scaffoldingConfig.BaseNamespace = config.Namespace;
+                scaffoldingConfig.Destination = config.Destination;
             });
 
             builder.Populate(serviceCollection);
-            builder.AddWorkflowEngine(input.BaseUrl, input.ApiPath);
+            builder.AddWorkflowEngine(
+                config.BaseUrl,
+                config.ApiPath,
+                createClient: () =>
+                {
+                    var client = new RestClient();
+                    client.UseNewtonsoftJson();
+                    client.AddDefaultHeaders(config.Headers);
+                    return client;
+                }
+            );
             builder.RegisterModule(new ToolkitModule());
 
             return builder.Build();

From d67e84220c5babd09954309709081a27111dd61a Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sun, 14 Aug 2022 00:40:45 +0200
Subject: [PATCH 11/37] Remove unnecessary newline

---
 src/ConductorSharp.Toolkit/Program.cs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index bbfc1a49..9f4476a8 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -47,7 +47,6 @@ public async static Task Main(string[] args)
         private static string GetVersionString()
         {
             var version = Assembly.GetExecutingAssembly().GetName().Version;
-
             return $"version {version.Major}.{version.Minor}.{version.Build}";
         }
 

From edc0c785fa8197b2367cfb17ef51568f3e5935e8 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sun, 14 Aug 2022 00:44:03 +0200
Subject: [PATCH 12/37] Add exception handling

---
 src/ConductorSharp.Toolkit/Program.cs | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index 9f4476a8..04d72dbe 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -52,18 +52,25 @@ private static string GetVersionString()
 
         private static async Task RunToolkit(ToolkitOptions options)
         {
-            if (!File.Exists(options.ConfiugrationFilePath))
+            try
             {
-                Console.Error.WriteLine($"Configuration file {options.ConfiugrationFilePath} does not exists");
-                return;
-            }
+                if (!File.Exists(options.ConfiugrationFilePath))
+                {
+                    Console.Error.WriteLine($"Configuration file {options.ConfiugrationFilePath} does not exists");
+                    return;
+                }
 
-            var config = await ParseConfigurationFile(options.ConfiugrationFilePath);
-            var container = BuildContainer(config);
-            var commandRegistry = container.Resolve<CommandRegistry>();
-            // Currently only scaffolding is supported
-            var command = commandRegistry.Get("scaffold");
-            await command.Execute(config);
+                var config = await ParseConfigurationFile(options.ConfiugrationFilePath);
+                var container = BuildContainer(config);
+                var commandRegistry = container.Resolve<CommandRegistry>();
+                // Currently only scaffolding is supported
+                var command = commandRegistry.Get("scaffold");
+                await command.Execute(config);
+            }
+            catch (Exception ex)
+            {
+                Console.Error.WriteLine($"Exception occured with message: {ex.Message}");
+            }
         }
 
         private static async Task<Configuration> ParseConfigurationFile(string configFilePath) =>

From ba74c50da127e54ecd51e0d6f4baba9d03e6d501 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sun, 14 Aug 2022 00:44:54 +0200
Subject: [PATCH 13/37] Rename option

---
 src/ConductorSharp.Toolkit/Models/ToolkitOptions.cs | 2 +-
 src/ConductorSharp.Toolkit/Program.cs               | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Models/ToolkitOptions.cs b/src/ConductorSharp.Toolkit/Models/ToolkitOptions.cs
index 7ec10c4f..25a6634e 100644
--- a/src/ConductorSharp.Toolkit/Models/ToolkitOptions.cs
+++ b/src/ConductorSharp.Toolkit/Models/ToolkitOptions.cs
@@ -5,6 +5,6 @@ namespace ConductorSharp.Toolkit.Models
     public class ToolkitOptions
     {
         [Option('f', "file", HelpText = "Configuration file", Default = "conductorsharp.yaml")]
-        public string ConfiugrationFilePath { get; set; }
+        public string ConfigurationFilePath { get; set; }
     }
 }
diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index 04d72dbe..079cc20d 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -54,13 +54,13 @@ private static async Task RunToolkit(ToolkitOptions options)
         {
             try
             {
-                if (!File.Exists(options.ConfiugrationFilePath))
+                if (!File.Exists(options.ConfigurationFilePath))
                 {
-                    Console.Error.WriteLine($"Configuration file {options.ConfiugrationFilePath} does not exists");
+                    Console.Error.WriteLine($"Configuration file {options.ConfigurationFilePath} does not exists");
                     return;
                 }
 
-                var config = await ParseConfigurationFile(options.ConfiugrationFilePath);
+                var config = await ParseConfigurationFile(options.ConfigurationFilePath);
                 var container = BuildContainer(config);
                 var commandRegistry = container.Resolve<CommandRegistry>();
                 // Currently only scaffolding is supported

From ddc9d2e2e7e919fc9d10563f5a5e4f92060f04f6 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sun, 14 Aug 2022 00:49:14 +0200
Subject: [PATCH 14/37] Specify default value for api path

---
 src/ConductorSharp.Toolkit/Models/Configuration.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ConductorSharp.Toolkit/Models/Configuration.cs b/src/ConductorSharp.Toolkit/Models/Configuration.cs
index 04a4380b..9caafdb3 100644
--- a/src/ConductorSharp.Toolkit/Models/Configuration.cs
+++ b/src/ConductorSharp.Toolkit/Models/Configuration.cs
@@ -2,7 +2,7 @@
 {
     public class Configuration
     {
-        public string ApiPath { get; set; }
+        public string ApiPath { get; set; } = "api";
         public string Namespace { get; set; }
         public string BaseUrl { get; set; }
         public string Destination { get; set; }

From c9456ce60303952d9e4424f27cb82a3781e94cee Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sun, 14 Aug 2022 00:49:23 +0200
Subject: [PATCH 15/37] Validate configuration

---
 src/ConductorSharp.Toolkit/Program.cs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index 079cc20d..8f2ea394 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -61,6 +61,9 @@ private static async Task RunToolkit(ToolkitOptions options)
                 }
 
                 var config = await ParseConfigurationFile(options.ConfigurationFilePath);
+                if (!ValidateConfiguration(config))
+                    return;
+
                 var container = BuildContainer(config);
                 var commandRegistry = container.Resolve<CommandRegistry>();
                 // Currently only scaffolding is supported
@@ -79,6 +82,18 @@ private static async Task<Configuration> ParseConfigurationFile(string configFil
                 .Build()
                 .Deserialize<Configuration>(await File.ReadAllTextAsync(configFilePath));
 
+        private static bool ValidateConfiguration(Configuration config)
+        {
+            if (config.BaseUrl == null)
+                Console.Error.WriteLine("baseUrl property missing in configuration");
+            if (config.Namespace == null)
+                Console.Error.WriteLine("namespace property missing in configuration");
+            if (config.Destination == null)
+                Console.Error.WriteLine("destination property missing in configuration");
+
+            return config.BaseUrl != null && config.Destination != null && config.Namespace != null;
+        }
+
         private static IContainer BuildContainer(Configuration config)
         {
             var serviceCollection = new ServiceCollection();

From 2980d0e040eb1996d99f643f772ec06aa1e2e50a Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Sun, 14 Aug 2022 23:20:38 +0200
Subject: [PATCH 16/37] Add comment

---
 src/ConductorSharp.Toolkit/Program.cs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index 8f2ea394..06417c33 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -70,6 +70,7 @@ private static async Task RunToolkit(ToolkitOptions options)
                 var command = commandRegistry.Get("scaffold");
                 await command.Execute(config);
             }
+            // TODO: Improve error handling
             catch (Exception ex)
             {
                 Console.Error.WriteLine($"Exception occured with message: {ex.Message}");

From bbd3c14e49106c56cc3f8a5e9fc112090098ff64 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 15 Aug 2022 00:39:24 +0200
Subject: [PATCH 17/37] Make method sync

---
 src/ConductorSharp.Toolkit/Program.cs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index 06417c33..cda3d84c 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -60,7 +60,7 @@ private static async Task RunToolkit(ToolkitOptions options)
                     return;
                 }
 
-                var config = await ParseConfigurationFile(options.ConfigurationFilePath);
+                var config = ParseConfigurationFile(options.ConfigurationFilePath);
                 if (!ValidateConfiguration(config))
                     return;
 
@@ -77,11 +77,11 @@ private static async Task RunToolkit(ToolkitOptions options)
             }
         }
 
-        private static async Task<Configuration> ParseConfigurationFile(string configFilePath) =>
+        private static Configuration ParseConfigurationFile(string configFilePath) =>
             new DeserializerBuilder()
                 .WithNamingConvention(CamelCaseNamingConvention.Instance)
                 .Build()
-                .Deserialize<Configuration>(await File.ReadAllTextAsync(configFilePath));
+                .Deserialize<Configuration>(File.ReadAllText(configFilePath));
 
         private static bool ValidateConfiguration(Configuration config)
         {

From 8e00de7c16cf4bba3856708011aa56d78b465714 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 15 Aug 2022 09:19:38 +0200
Subject: [PATCH 18/37] Change copyright line

---
 src/ConductorSharp.Toolkit/Program.cs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index cda3d84c..ada2e1fa 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -33,6 +33,7 @@ public async static Task Main(string[] args)
                         parseResult,
                         help =>
                         {
+                            help.Copyright = new CopyrightInfo("Codaxy", 2022);
                             help.AddPreOptionsLine("Usage: dotnet conductorsharp [options]");
                             help.Heading = versionText;
                             return help;

From d17b1fb39d2018822691ae3d18a0d8350f582d94 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 15 Aug 2022 10:13:05 +0200
Subject: [PATCH 19/37] Read version from constant string

---
 src/ConductorSharp.Toolkit/Program.cs | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index ada2e1fa..b5773cc9 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -16,13 +16,15 @@ namespace ConductorSharp.Toolkit
 {
     class Program
     {
+        public const string Version = "0.0.1";
+
         public async static Task Main(string[] args)
         {
             var parseResult = new Parser(opts => opts.HelpWriter = null).ParseArguments<ToolkitOptions>(args);
             var withParsed = await parseResult.WithParsedAsync(RunToolkit);
             withParsed.WithNotParsed(err =>
             {
-                var versionText = new HeadingInfo("conductorsharp", GetVersionString());
+                var versionText = new HeadingInfo("conductorsharp", Version);
                 var writer = err.IsHelp() || err.IsVersion() ? Console.Out : Console.Error;
                 string textToWrite;
                 if (err.IsVersion())
@@ -45,12 +47,6 @@ public async static Task Main(string[] args)
             });
         }
 
-        private static string GetVersionString()
-        {
-            var version = Assembly.GetExecutingAssembly().GetName().Version;
-            return $"version {version.Major}.{version.Minor}.{version.Build}";
-        }
-
         private static async Task RunToolkit(ToolkitOptions options)
         {
             try

From fc1e20ca790ca77171ab7f9c4ebe0a53436642e3 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 15 Aug 2022 12:05:29 +0200
Subject: [PATCH 20/37] Perform IsNullOrEmpty check instead of null check only

---
 src/ConductorSharp.Toolkit/Program.cs | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index b5773cc9..fed52eff 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -82,14 +82,24 @@ private static Configuration ParseConfigurationFile(string configFilePath) =>
 
         private static bool ValidateConfiguration(Configuration config)
         {
-            if (config.BaseUrl == null)
+            bool validConfiguration = true;
+            if (string.IsNullOrEmpty(config.BaseUrl))
+            {
                 Console.Error.WriteLine("baseUrl property missing in configuration");
-            if (config.Namespace == null)
+                validConfiguration = false;
+            }
+            if (string.IsNullOrEmpty(config.Namespace))
+            {
                 Console.Error.WriteLine("namespace property missing in configuration");
-            if (config.Destination == null)
+                validConfiguration = false;
+            }
+            if (string.IsNullOrEmpty(config.Destination))
+            {
                 Console.Error.WriteLine("destination property missing in configuration");
+                validConfiguration = false;
+            }
 
-            return config.BaseUrl != null && config.Destination != null && config.Namespace != null;
+            return validConfiguration;
         }
 
         private static IContainer BuildContainer(Configuration config)

From ac4bc26f9f9357b1f74826e2a86b9f62196dd664 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 15 Aug 2022 12:51:11 +0200
Subject: [PATCH 21/37] Add package used for code generation

---
 src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj b/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj
index e94e30a4..519a0fad 100644
--- a/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj
+++ b/src/ConductorSharp.Toolkit/ConductorSharp.Toolkit.csproj
@@ -26,6 +26,7 @@
   <ItemGroup>
     <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="8.0.0" />
     <PackageReference Include="CommandLineParser" Version="2.9.1" />
+    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
     <PackageReference Include="Serilog.Extensions.Logging" Version="3.1.0" />
     <PackageReference Include="YamlDotNet" Version="12.0.0" />

From 27eca6fa9585f05de8e572f807073e3a9a951b2d Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 15 Aug 2022 14:56:11 +0200
Subject: [PATCH 22/37] Add class for generating task models

---
 .../Util/TaskModelGenerator.cs                | 189 ++++++++++++++++++
 1 file changed, 189 insertions(+)
 create mode 100644 src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs

diff --git a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
new file mode 100644
index 00000000..b7f098f1
--- /dev/null
+++ b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
@@ -0,0 +1,189 @@
+﻿using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+
+namespace ConductorSharp.Toolkit.Util
+{
+    public class TaskModelGenerator
+    {
+        public enum ModelType
+        {
+            Task,
+            Workflow
+        };
+
+        public class PropertyData
+        {
+            public string Name { get; set; }
+            public string OriginalName { get; set; }
+            public string Type { get; set; }
+        }
+
+        public string Namespace { get; set; }
+        public string ClassName { get; set; }
+        public string OriginalName { get; set; }
+        public string OwnerApp { get; set; }
+        public string OwnerEmail { get; set; }
+        public string Summary { get; set; }
+        public string Note { get; private set; } = string.Empty;
+
+        protected CompilationUnitSyntax _compilationUnit = SyntaxFactory.CompilationUnit();
+        private readonly ModelType _modelType;
+        private List<PropertyData> _inputProperties = new();
+        private List<PropertyData> _outputProperties = new();
+
+        public TaskModelGenerator(string @namespace, string className, ModelType modelType)
+        {
+            Namespace = @namespace;
+            ClassName = className;
+            _modelType = modelType;
+        }
+
+        public void AppendNote(string note) => Note += note;
+
+        public void AddInputProperty(string propName, string originalName, string type)
+        {
+            _inputProperties.Add(
+                new PropertyData
+                {
+                    Name = propName,
+                    OriginalName = originalName,
+                    Type = type
+                }
+            );
+        }
+
+        public void AddOutputProperty(string propName, string originalName, string type)
+        {
+            _inputProperties.Add(
+                new PropertyData
+                {
+                    Name = propName,
+                    OriginalName = originalName,
+                    Type = type
+                }
+            );
+        }
+
+        public string Build()
+        {
+            _compilationUnit = _compilationUnit.AddUsings(
+                CreateUsings("ConductorSharp.Engine.Model", "ConductorSharp.Engine.Util", "MediatR", "Newtonsoft.Json")
+            );
+            var namespaceDeclaration = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(Namespace));
+            namespaceDeclaration = namespaceDeclaration.AddMembers(CreateInputClass(), CreateOutputClass(), CreateModelClass());
+            _compilationUnit = _compilationUnit.AddMembers(namespaceDeclaration);
+            return _compilationUnit.NormalizeWhitespace().ToFullString();
+        }
+
+        private SyntaxTriviaList GenerateAutoGeneratedComment()
+        {
+            // This comment is written:
+
+            // <autogenerated>
+            //     This code was generated by a tool.
+            //
+            //     Changes to this file may cause incorrect behavior and will be lost if
+            //     the code is regenerated.
+            // </autogenerated>
+
+            var list = SyntaxFactory.TriviaList();
+            list.Add(SyntaxFactory.Comment("// <autogenerated>"));
+            list.Add(SyntaxFactory.Comment("//     This code was generated by a tool."));
+            list.Add(SyntaxFactory.Comment("//     Changes to this file may cause incorrect behavior and will be lost if"));
+            list.Add(SyntaxFactory.Comment("//     the code is regenerated."));
+            list.Add(SyntaxFactory.Comment("// </autogenerated>"));
+
+            return list;
+        }
+
+        private UsingDirectiveSyntax[] CreateUsings(params string[] namespaces)
+        {
+            var usings = namespaces.Select(@namespace => SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(@namespace))).ToArray();
+            usings[0] = usings[0].WithUsingKeyword(
+                SyntaxFactory.Token(GenerateAutoGeneratedComment(), SyntaxKind.UsingKeyword, SyntaxFactory.TriviaList())
+            );
+            return usings;
+        }
+
+        private AttributeSyntax CreateInputPropertyAttribute(string originalName)
+        {
+            var attribute = SyntaxFactory
+                .Attribute(SyntaxFactory.ParseName("JsonProperty"))
+                .AddArgumentListArguments(
+                    SyntaxFactory.AttributeArgument(
+                        SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(originalName))
+                    )
+                );
+            return attribute;
+        }
+
+        private PropertyDeclarationSyntax CreateInputProperty(PropertyData inputData)
+        {
+            var propertyDeclaration = SyntaxFactory
+                .PropertyDeclaration(SyntaxFactory.ParseTypeName(inputData.Type), inputData.Name)
+                .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword))
+                .AddAccessorListAccessors(
+                    SyntaxFactory
+                        .AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
+                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)),
+                    SyntaxFactory
+                        .AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
+                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
+                );
+
+            var attributeList = SyntaxFactory.AttributeList(
+                SyntaxFactory.SingletonSeparatedList(CreateInputPropertyAttribute(inputData.OriginalName))
+            );
+            propertyDeclaration = propertyDeclaration.AddAttributeLists(attributeList);
+            return propertyDeclaration;
+        }
+
+        private ClassDeclarationSyntax CreateInputClass()
+        {
+            var typeArgumentList = SyntaxFactory.TypeArgumentList(
+                SyntaxFactory.SingletonSeparatedList<TypeSyntax>(SyntaxFactory.ParseTypeName($"{ClassName}Output"))
+            );
+            var baseType = SyntaxFactory.SimpleBaseType(SyntaxFactory.GenericName("IRequest").WithTypeArgumentList(typeArgumentList));
+            var baseList = SyntaxFactory.BaseList(SyntaxFactory.SingletonSeparatedList<BaseTypeSyntax>(baseType));
+            var classDeclaration = SyntaxFactory
+                .ClassDeclaration($"{ClassName}Input")
+                .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.PartialKeyword))
+                .WithBaseList(baseList)
+                .AddMembers(_inputProperties.Select(CreateInputProperty).ToArray());
+
+            return classDeclaration;
+        }
+
+        private ClassDeclarationSyntax CreateOutputClass()
+        {
+            var classDeclaration = SyntaxFactory
+                .ClassDeclaration($"{ClassName}Output")
+                .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.PartialKeyword))
+                .AddMembers(_outputProperties.Select(CreateInputProperty).ToArray());
+
+            return classDeclaration;
+        }
+
+        private ClassDeclarationSyntax CreateModelClass()
+        {
+            var typeArgumentList = SyntaxFactory.TypeArgumentList(
+                SyntaxFactory.SeparatedList(
+                    new List<TypeSyntax> { SyntaxFactory.ParseTypeName($"{ClassName}Input"), SyntaxFactory.ParseTypeName($"{ClassName}Output") }
+                )
+            );
+            var baseType = SyntaxFactory.SimpleBaseType(
+                SyntaxFactory
+                    .GenericName(_modelType == ModelType.Task ? "SimpleTaskModel" : "SubWorkflowTaskModel")
+                    .WithTypeArgumentList(typeArgumentList)
+            );
+            var baseList = SyntaxFactory.BaseList(SyntaxFactory.SingletonSeparatedList<BaseTypeSyntax>(baseType));
+            var classDeclaration = SyntaxFactory
+                .ClassDeclaration(ClassName)
+                .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.PartialKeyword))
+                .WithBaseList(baseList);
+
+            return classDeclaration;
+        }
+    }
+}

From 095e1ad9235a8c7e68b1fee25def87fb82e66c0c Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 15 Aug 2022 15:01:22 +0200
Subject: [PATCH 23/37] Change the way note is build

---
 src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
index b7f098f1..f4387af7 100644
--- a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
+++ b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
@@ -1,6 +1,7 @@
 ﻿using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis.CSharp;
 using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System.Text;
 
 namespace ConductorSharp.Toolkit.Util
 {
@@ -25,12 +26,12 @@ public class PropertyData
         public string OwnerApp { get; set; }
         public string OwnerEmail { get; set; }
         public string Summary { get; set; }
-        public string Note { get; private set; } = string.Empty;
 
         protected CompilationUnitSyntax _compilationUnit = SyntaxFactory.CompilationUnit();
         private readonly ModelType _modelType;
         private List<PropertyData> _inputProperties = new();
         private List<PropertyData> _outputProperties = new();
+        private StringBuilder _noteBuilder = new StringBuilder();
 
         public TaskModelGenerator(string @namespace, string className, ModelType modelType)
         {
@@ -39,7 +40,7 @@ public TaskModelGenerator(string @namespace, string className, ModelType modelTy
             _modelType = modelType;
         }
 
-        public void AppendNote(string note) => Note += note;
+        public void AppendNoteLine(string note) => _noteBuilder.AppendLine(note);
 
         public void AddInputProperty(string propName, string originalName, string type)
         {

From 480a759184845126990bbdd3ceebdf22c072f5dd Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Tue, 16 Aug 2022 08:59:50 +0200
Subject: [PATCH 24/37] Change the way properties are added, fix comment
 generation

---
 .../Util/TaskModelGenerator.cs                | 43 ++++++-------------
 1 file changed, 14 insertions(+), 29 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
index f4387af7..c6c7b476 100644
--- a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
+++ b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
@@ -18,6 +18,7 @@ public class PropertyData
             public string Name { get; set; }
             public string OriginalName { get; set; }
             public string Type { get; set; }
+            public Dictionary<string, string> XmlComments { get; } = new();
         }
 
         public string Namespace { get; set; }
@@ -42,28 +43,14 @@ public TaskModelGenerator(string @namespace, string className, ModelType modelTy
 
         public void AppendNoteLine(string note) => _noteBuilder.AppendLine(note);
 
-        public void AddInputProperty(string propName, string originalName, string type)
+        public void AddInputProperty(PropertyData propData)
         {
-            _inputProperties.Add(
-                new PropertyData
-                {
-                    Name = propName,
-                    OriginalName = originalName,
-                    Type = type
-                }
-            );
+            _inputProperties.Add(propData);
         }
 
-        public void AddOutputProperty(string propName, string originalName, string type)
+        public void AddOutputProperty(PropertyData propData)
         {
-            _inputProperties.Add(
-                new PropertyData
-                {
-                    Name = propName,
-                    OriginalName = originalName,
-                    Type = type
-                }
-            );
+            _outputProperties.Add(propData);
         }
 
         public string Build()
@@ -89,11 +76,11 @@ private SyntaxTriviaList GenerateAutoGeneratedComment()
             // </autogenerated>
 
             var list = SyntaxFactory.TriviaList();
-            list.Add(SyntaxFactory.Comment("// <autogenerated>"));
-            list.Add(SyntaxFactory.Comment("//     This code was generated by a tool."));
-            list.Add(SyntaxFactory.Comment("//     Changes to this file may cause incorrect behavior and will be lost if"));
-            list.Add(SyntaxFactory.Comment("//     the code is regenerated."));
-            list.Add(SyntaxFactory.Comment("// </autogenerated>"));
+            list = list.Add(SyntaxFactory.Comment("// <autogenerated>"));
+            list = list.Add(SyntaxFactory.Comment("//     This code was generated by a tool."));
+            list = list.Add(SyntaxFactory.Comment("//     Changes to this file may cause incorrect behavior and will be lost if"));
+            list = list.Add(SyntaxFactory.Comment("//     the code is regenerated."));
+            list = list.Add(SyntaxFactory.Comment("// </autogenerated>"));
 
             return list;
         }
@@ -101,9 +88,7 @@ private SyntaxTriviaList GenerateAutoGeneratedComment()
         private UsingDirectiveSyntax[] CreateUsings(params string[] namespaces)
         {
             var usings = namespaces.Select(@namespace => SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(@namespace))).ToArray();
-            usings[0] = usings[0].WithUsingKeyword(
-                SyntaxFactory.Token(GenerateAutoGeneratedComment(), SyntaxKind.UsingKeyword, SyntaxFactory.TriviaList())
-            );
+            usings[0] = usings[0].WithLeadingTrivia(GenerateAutoGeneratedComment());
             return usings;
         }
 
@@ -119,7 +104,7 @@ private AttributeSyntax CreateInputPropertyAttribute(string originalName)
             return attribute;
         }
 
-        private PropertyDeclarationSyntax CreateInputProperty(PropertyData inputData)
+        private PropertyDeclarationSyntax CreateProperty(PropertyData inputData)
         {
             var propertyDeclaration = SyntaxFactory
                 .PropertyDeclaration(SyntaxFactory.ParseTypeName(inputData.Type), inputData.Name)
@@ -151,7 +136,7 @@ private ClassDeclarationSyntax CreateInputClass()
                 .ClassDeclaration($"{ClassName}Input")
                 .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.PartialKeyword))
                 .WithBaseList(baseList)
-                .AddMembers(_inputProperties.Select(CreateInputProperty).ToArray());
+                .AddMembers(_inputProperties.Select(CreateProperty).ToArray());
 
             return classDeclaration;
         }
@@ -161,7 +146,7 @@ private ClassDeclarationSyntax CreateOutputClass()
             var classDeclaration = SyntaxFactory
                 .ClassDeclaration($"{ClassName}Output")
                 .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.PartialKeyword))
-                .AddMembers(_outputProperties.Select(CreateInputProperty).ToArray());
+                .AddMembers(_outputProperties.Select(CreateProperty).ToArray());
 
             return classDeclaration;
         }

From 4afdb46b65b236953a79258cc13bab2abd2486ec Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Tue, 16 Aug 2022 11:52:23 +0200
Subject: [PATCH 25/37] Implement new way of scaffolding for workflows

---
 .../Service/ScaffoldingService.cs             | 47 +++++++++++--------
 .../Util/TaskModelGenerator.cs                | 27 ++++++++---
 2 files changed, 49 insertions(+), 25 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
index 2647a610..e7f21c8f 100644
--- a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
+++ b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
@@ -69,8 +69,6 @@ public async Task Scaffold()
 
         public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
         {
-            var lines = EmbeddedFileHelper.GetLinesFromEmbeddedFile("~/Templates/WorkflowTemplate.default");
-
             string name = SnakeCaseUtil.ToPascalCase($"{workflowDefinition.Name}_V{workflowDefinition.Version}").Trim();
             string note = null;
             if (LangUtils.MakeValidMemberName(name, "A", out name))
@@ -78,6 +76,7 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
                 note = "The autogenerated name has been changed because it is invalid C# member name";
             }
 
+            var modelGenerator = new TaskModelGenerator(_config.BaseNamespace + ".Tasks", name, TaskModelGenerator.ModelType.Workflow);
             string workflowDescription = workflowDefinition.Description;
             string[] labels;
 
@@ -97,13 +96,14 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
                 _logger.LogWarning("Unable to parse description for workflow {0}", workflowDefinition.Name);
             }
 
-            var inputLinesBuilder = new StringBuilder();
             try
             {
                 var inputParameters = JObject.Parse(workflowDefinition.InputParametersJSON[0]);
 
                 foreach (var param in inputParameters)
                 {
+                    var inputPropData = new TaskModelGenerator.PropertyData();
+
                     var value = param.Value.SelectToken("value")?.ToString(Newtonsoft.Json.Formatting.None);
                     var type = param.Value.SelectToken("type")?.Value<string>();
                     var description = param.Value.SelectToken("description")?.Value<string>();
@@ -111,10 +111,10 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
                     if (type == null)
                         type = "string";
 
-                    AppendXmlComment(inputLinesBuilder, "originalName", param.Key);
+                    inputPropData.XmlComments["originalName"] = param.Key;
 
                     if (!string.IsNullOrEmpty(description))
-                        AppendXmlComment(inputLinesBuilder, "summary", value);
+                        inputPropData.XmlComments["summary"] = description;
 
                     switch (type)
                     {
@@ -122,12 +122,13 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
                         case "integer":
                             if (!string.IsNullOrEmpty(value))
                             {
-                                AppendXmlComment(inputLinesBuilder, "remark", $"Example: {value}");
+                                inputPropData.XmlComments["remark"] = $"Example: {value}";
                             }
-                            AppendClassProperty(inputLinesBuilder, "dynamic", param.Key);
+                            DefinePropertyParams(inputPropData, "dynamic", param.Key);
+
                             break;
                         case "toggle":
-                            AppendClassProperty(inputLinesBuilder, "dynamic", param.Key);
+                            DefinePropertyParams(inputPropData, "dynamic", param.Key);
                             break;
                         case "select":
                             var optionsToken = param.Value.SelectToken("options");
@@ -139,13 +140,15 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
                                 options = optionsArray.ToObject<string[]>();
                             }
                             if (options != null && options.Length > 0)
-                                AppendXmlComment(inputLinesBuilder, "remark", $"Options: {string.Join(',', options)}");
+                                inputPropData.XmlComments["remark"] = $"Options: {string.Join(',', options)}";
 
-                            AppendClassProperty(inputLinesBuilder, "dynamic", param.Key);
+                            DefinePropertyParams(inputPropData, "dynamic", param.Key);
                             break;
                         default:
                             break;
                     }
+
+                    modelGenerator.AddInputProperty(inputPropData);
                 }
             }
             catch (Exception)
@@ -164,19 +167,17 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
             if (string.IsNullOrEmpty(workflowDefinition.OwnerApp))
                 _logger.LogWarning($"No owner app defined for task {workflowDefinition.Name}");
 
-            lines = lines.Replace("{{inputProperties}}", inputLinesBuilder.ToString());
-            lines = lines.Replace("{{workflowName}}", name);
-            lines = lines.Replace("{{note}}", note);
-            lines = lines.Replace("{{ownerEmail}}", $"{workflowDefinition.OwnerEmail}");
-            lines = lines.Replace("{{ownerApp}}", $"{workflowDefinition.OwnerApp}");
-            lines = lines.Replace("{{originalName}}", $"{workflowDefinition.Name}");
-            lines = lines.Replace("{{description}}", workflowDescription);
-            lines = lines.Replace("{{commentDescription}}", workflowDescription?.Replace('\n', ','));
+            //modelGenerator.OwnerApp = workflowDefinition.OwnerApp;
+            modelGenerator.AddXmlComment("summary", workflowDescription?.Replace('\n', ','));
+            modelGenerator.AddXmlComment("originalName", workflowDefinition.Name);
+            modelGenerator.AddXmlComment("ownerApp", workflowDefinition.OwnerApp);
+            modelGenerator.AddXmlComment("ownerEmail", workflowDefinition.OwnerEmail);
+            modelGenerator.AddXmlComment("note", note);
 
             if (_config.Dryrun)
                 return null;
 
-            return lines;
+            return modelGenerator.Build();
         }
 
         private void AppendClassProperty(StringBuilder linesBuilder, string type, string name)
@@ -186,6 +187,14 @@ private void AppendClassProperty(StringBuilder linesBuilder, string type, string
             linesBuilder.AppendLine($"        public {type} {propertyName} {{ get; set; }}");
         }
 
+        private void DefinePropertyParams(TaskModelGenerator.PropertyData propData, string type, string originalName)
+        {
+            LangUtils.MakeValidMemberName(SnakeCaseUtil.ToPascalCase(originalName), "A", out var propertyName);
+            propData.OriginalName = originalName;
+            propData.Name = propertyName;
+            propData.Type = type;
+        }
+
         private void AppendXmlComment(StringBuilder linesBuilder, string tag, string value)
         {
             linesBuilder.AppendLine($"        /// <{tag}>");
diff --git a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
index c6c7b476..93543b59 100644
--- a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
+++ b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
@@ -24,15 +24,13 @@ public class PropertyData
         public string Namespace { get; set; }
         public string ClassName { get; set; }
         public string OriginalName { get; set; }
-        public string OwnerApp { get; set; }
-        public string OwnerEmail { get; set; }
         public string Summary { get; set; }
 
         protected CompilationUnitSyntax _compilationUnit = SyntaxFactory.CompilationUnit();
         private readonly ModelType _modelType;
         private List<PropertyData> _inputProperties = new();
         private List<PropertyData> _outputProperties = new();
-        private StringBuilder _noteBuilder = new StringBuilder();
+        private readonly Dictionary<string, string> _xmlComments = new();
 
         public TaskModelGenerator(string @namespace, string className, ModelType modelType)
         {
@@ -41,8 +39,6 @@ public TaskModelGenerator(string @namespace, string className, ModelType modelTy
             _modelType = modelType;
         }
 
-        public void AppendNoteLine(string note) => _noteBuilder.AppendLine(note);
-
         public void AddInputProperty(PropertyData propData)
         {
             _inputProperties.Add(propData);
@@ -53,6 +49,8 @@ public void AddOutputProperty(PropertyData propData)
             _outputProperties.Add(propData);
         }
 
+        public void AddXmlComment(string tag, string value) => _xmlComments[tag] = value;
+
         public string Build()
         {
             _compilationUnit = _compilationUnit.AddUsings(
@@ -122,9 +120,25 @@ private PropertyDeclarationSyntax CreateProperty(PropertyData inputData)
                 SyntaxFactory.SingletonSeparatedList(CreateInputPropertyAttribute(inputData.OriginalName))
             );
             propertyDeclaration = propertyDeclaration.AddAttributeLists(attributeList);
+            propertyDeclaration = propertyDeclaration.WithLeadingTrivia(GenerateXmlDocComment(inputData.XmlComments));
+
             return propertyDeclaration;
         }
 
+        private SyntaxTriviaList GenerateXmlDocComment(Dictionary<string, string> xmlComments)
+        {
+            var list = new SyntaxTriviaList();
+
+            foreach (var elem in xmlComments)
+            {
+                list = list.Add(SyntaxFactory.Comment($"/// <{elem.Key}>"));
+                list = list.Add(SyntaxFactory.Comment($"/// {elem.Value}"));
+                list = list.Add(SyntaxFactory.Comment($"/// </{elem.Key}>"));
+            }
+
+            return list;
+        }
+
         private ClassDeclarationSyntax CreateInputClass()
         {
             var typeArgumentList = SyntaxFactory.TypeArgumentList(
@@ -167,7 +181,8 @@ private ClassDeclarationSyntax CreateModelClass()
             var classDeclaration = SyntaxFactory
                 .ClassDeclaration(ClassName)
                 .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.PartialKeyword))
-                .WithBaseList(baseList);
+                .WithBaseList(baseList)
+                .WithLeadingTrivia(GenerateXmlDocComment(_xmlComments));
 
             return classDeclaration;
         }

From f80cf3a644ac3b328221bf8374ec537e2c50b601 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Tue, 16 Aug 2022 12:52:06 +0200
Subject: [PATCH 26/37] Add using

---
 src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
index 93543b59..fe51e7b1 100644
--- a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
+++ b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
@@ -54,7 +54,13 @@ public void AddOutputProperty(PropertyData propData)
         public string Build()
         {
             _compilationUnit = _compilationUnit.AddUsings(
-                CreateUsings("ConductorSharp.Engine.Model", "ConductorSharp.Engine.Util", "MediatR", "Newtonsoft.Json")
+                CreateUsings(
+                    "ConductorSharp.Engine.Model",
+                    "ConductorSharp.Engine.Util",
+                    "MediatR",
+                    "Newtonsoft.Json",
+                    "ConductorSharp.Engine.Builders"
+                )
             );
             var namespaceDeclaration = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(Namespace));
             namespaceDeclaration = namespaceDeclaration.AddMembers(CreateInputClass(), CreateOutputClass(), CreateModelClass());

From f8e6ca7f1ac6df44eefb9538d5df6462f877d2bf Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Tue, 16 Aug 2022 12:52:36 +0200
Subject: [PATCH 27/37] Implement scaffolding using roslyn

---
 .../Service/ScaffoldingService.cs             | 114 ++++++++----------
 1 file changed, 51 insertions(+), 63 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
index e7f21c8f..052eb879 100644
--- a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
+++ b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
@@ -27,47 +27,54 @@ public async Task Scaffold()
         {
             var workflowDefinitions = await _metadataService.GetAllWorkflowDefinitions();
             var workflowCollectionBuilder = new StringBuilder();
+            var workflowDirectory = Path.Combine(_config.Destination, "Workflows");
             foreach (var workflowDefinition in workflowDefinitions)
             {
-                var workflowClass = CreateWorkflowClass(workflowDefinition);
+                (var contents, var modelClassName) = CreateWorkflowClass(workflowDefinition);
 
-                if (workflowClass != null)
-                    workflowCollectionBuilder.Append(workflowClass);
+                if (contents != null)
+                {
+                    var filePath = Path.Combine(workflowDirectory, $"{modelClassName}.scaff.cs");
+                    File.WriteAllText(filePath, contents);
+                }
             }
 
             var taskDefinitions = await _metadataService.GetAllTaskDefinitions();
-
             var taskCollectionBuilder = new StringBuilder();
+            var tasksDirectory = Path.Combine(_config.Destination, "Tasks");
             foreach (var taskDefinition in taskDefinitions)
             {
-                var taskClass = CreateTaskClass(taskDefinition);
+                (var contents, var modelClassName) = CreateTaskClass(taskDefinition);
 
-                if (taskClass != null)
-                    taskCollectionBuilder.Append(taskClass);
+                if (contents != null)
+                {
+                    var filePath = Path.Combine(tasksDirectory, $"{modelClassName}.scaff.cs");
+                    File.WriteAllText(filePath, contents);
+                }
             }
 
-            var taskTemplate = EmbeddedFileHelper.GetLinesFromEmbeddedFile("~/Templates/TaskCollectionTemplate.default");
-            var taskCollection = taskCollectionBuilder.ToString();
-            taskTemplate = taskTemplate.Replace("{{namespace}}", _config.BaseNamespace + ".Tasks");
-            taskTemplate = taskTemplate.Replace("{{taskCollection}}", taskCollection);
-            var dir = _config.Destination + Path.DirectorySeparatorChar + "Tasks";
+            //var taskTemplate = EmbeddedFileHelper.GetLinesFromEmbeddedFile("~/Templates/TaskCollectionTemplate.default");
+            //var taskCollection = taskCollectionBuilder.ToString();
+            //taskTemplate = taskTemplate.Replace("{{namespace}}", _config.BaseNamespace + ".Tasks");
+            //taskTemplate = taskTemplate.Replace("{{taskCollection}}", taskCollection);
+            //var dir = _config.Destination + Path.DirectorySeparatorChar + "Tasks";
 
-            Directory.CreateDirectory(dir);
+            //Directory.CreateDirectory(dir);
 
-            File.WriteAllText(dir + Path.DirectorySeparatorChar + "Tasks.scaff.cs", taskTemplate);
+            //File.WriteAllText(dir + Path.DirectorySeparatorChar + "Tasks.scaff.cs", taskTemplate);
 
-            var workflowTemplate = EmbeddedFileHelper.GetLinesFromEmbeddedFile("~/Templates/WorkflowCollectionTemplate.default");
-            var workflowCollection = workflowCollectionBuilder.ToString();
-            workflowTemplate = workflowTemplate.Replace("{{namespace}}", _config.BaseNamespace + ".Workflows");
-            workflowTemplate = workflowTemplate.Replace("{{workflowCollection}}", workflowCollection);
-            var workflowDir = _config.Destination + Path.DirectorySeparatorChar + "Workflows";
+            //var workflowTemplate = EmbeddedFileHelper.GetLinesFromEmbeddedFile("~/Templates/WorkflowCollectionTemplate.default");
+            //var workflowCollection = workflowCollectionBuilder.ToString();
+            //workflowTemplate = workflowTemplate.Replace("{{namespace}}", _config.BaseNamespace + ".Workflows");
+            //workflowTemplate = workflowTemplate.Replace("{{workflowCollection}}", workflowCollection);
+            //var workflowDir = _config.Destination + Path.DirectorySeparatorChar + "Workflows";
 
-            Directory.CreateDirectory(workflowDir);
+            //Directory.CreateDirectory(workflowDir);
 
-            File.WriteAllText(workflowDir + Path.DirectorySeparatorChar + "Workflows.scaff.cs", workflowTemplate);
+            //File.WriteAllText(workflowDir + Path.DirectorySeparatorChar + "Workflows.scaff.cs", workflowTemplate);
         }
 
-        public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
+        public (string contents, string modelClassName) CreateWorkflowClass(WorkflowDefinition workflowDefinition)
         {
             string name = SnakeCaseUtil.ToPascalCase($"{workflowDefinition.Name}_V{workflowDefinition.Version}").Trim();
             string note = null;
@@ -76,7 +83,7 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
                 note = "The autogenerated name has been changed because it is invalid C# member name";
             }
 
-            var modelGenerator = new TaskModelGenerator(_config.BaseNamespace + ".Tasks", name, TaskModelGenerator.ModelType.Workflow);
+            var modelGenerator = new TaskModelGenerator(_config.BaseNamespace + ".Workflows", name, TaskModelGenerator.ModelType.Workflow);
             string workflowDescription = workflowDefinition.Description;
             string[] labels;
 
@@ -125,10 +132,12 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
                                 inputPropData.XmlComments["remark"] = $"Example: {value}";
                             }
                             DefinePropertyParams(inputPropData, "dynamic", param.Key);
+                            modelGenerator.AddInputProperty(inputPropData);
 
                             break;
                         case "toggle":
                             DefinePropertyParams(inputPropData, "dynamic", param.Key);
+                            modelGenerator.AddInputProperty(inputPropData);
                             break;
                         case "select":
                             var optionsToken = param.Value.SelectToken("options");
@@ -143,12 +152,11 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
                                 inputPropData.XmlComments["remark"] = $"Options: {string.Join(',', options)}";
 
                             DefinePropertyParams(inputPropData, "dynamic", param.Key);
+                            modelGenerator.AddInputProperty(inputPropData);
                             break;
                         default:
                             break;
                     }
-
-                    modelGenerator.AddInputProperty(inputPropData);
                 }
             }
             catch (Exception)
@@ -167,7 +175,6 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
             if (string.IsNullOrEmpty(workflowDefinition.OwnerApp))
                 _logger.LogWarning($"No owner app defined for task {workflowDefinition.Name}");
 
-            //modelGenerator.OwnerApp = workflowDefinition.OwnerApp;
             modelGenerator.AddXmlComment("summary", workflowDescription?.Replace('\n', ','));
             modelGenerator.AddXmlComment("originalName", workflowDefinition.Name);
             modelGenerator.AddXmlComment("ownerApp", workflowDefinition.OwnerApp);
@@ -175,9 +182,9 @@ public string CreateWorkflowClass(WorkflowDefinition workflowDefinition)
             modelGenerator.AddXmlComment("note", note);
 
             if (_config.Dryrun)
-                return null;
+                return (null, null);
 
-            return modelGenerator.Build();
+            return (modelGenerator.Build(), name);
         }
 
         private void AppendClassProperty(StringBuilder linesBuilder, string type, string name)
@@ -202,21 +209,8 @@ private void AppendXmlComment(StringBuilder linesBuilder, string tag, string val
             linesBuilder.AppendLine($"        /// </{tag}>");
         }
 
-        public string CreateTaskClass(TaskDefinition taskDefinition)
+        public (string contents, string modelClassName) CreateTaskClass(TaskDefinition taskDefinition)
         {
-            var lines = EmbeddedFileHelper.GetLinesFromEmbeddedFile("~/Templates/WorkerTemplate.default");
-
-            var namespaceRegex = new Regex("(^[^_]+)_.+");
-
-            var matches = namespaceRegex.Match(taskDefinition.Name).Groups;
-
-            string naspace = "";
-            if (matches.Count > 1)
-            {
-                naspace = matches[1].Value.ToLowerInvariant();
-                naspace = char.ToUpperInvariant(naspace[0]) + naspace[1..];
-            }
-
             string name = SnakeCaseUtil.ToPascalCase(taskDefinition.Name).Trim();
             string note = null;
             if (LangUtils.MakeValidMemberName(name, "A", out name))
@@ -224,30 +218,26 @@ public string CreateTaskClass(TaskDefinition taskDefinition)
                 note = "The autogenerated name has been prepended because it starts with a digit character.";
             }
 
-            var inputLinesBuilder = new StringBuilder();
+            var modelGenerator = new TaskModelGenerator(_config.BaseNamespace + ".Tasks", name, TaskModelGenerator.ModelType.Task);
             foreach (var property in taskDefinition.InputKeys)
             {
-                AppendXmlComment(inputLinesBuilder, "originalName", property);
-                AppendClassProperty(inputLinesBuilder, "dynamic", property);
+                var inputPropData = new TaskModelGenerator.PropertyData();
+                DefinePropertyParams(inputPropData, "dynamic", property);
+                inputPropData.XmlComments["originalName"] = property;
+                modelGenerator.AddInputProperty(inputPropData);
             }
 
-            var outputLinesBuilder = new StringBuilder();
             foreach (var property in taskDefinition.OutputKeys)
             {
-                AppendXmlComment(outputLinesBuilder, "originalName", property);
-                AppendClassProperty(outputLinesBuilder, "dynamic", property);
+                var inputPropData = new TaskModelGenerator.PropertyData();
+                DefinePropertyParams(inputPropData, "dynamic", property);
+                inputPropData.XmlComments["originalName"] = property;
+                modelGenerator.AddOutputProperty(inputPropData);
             }
 
-            var generatedNamespace = _config.BaseNamespace + ".Tasks" + (!string.IsNullOrEmpty(naspace) ? $".{naspace}" : "");
-
-            lines = lines.Replace("{{workerName}}", name);
-            lines = lines.Replace("{{note}}", note);
-            lines = lines.Replace("{{inputProperties}}", inputLinesBuilder.ToString());
-            lines = lines.Replace("{{outputProperties}}", outputLinesBuilder.ToString());
-            lines = lines.Replace("{{namespace}}", $"{generatedNamespace}");
-            lines = lines.Replace("{{ownerEmail}}", $"{taskDefinition.OwnerEmail}");
-            lines = lines.Replace("{{ownerApp}}", $"{taskDefinition.OwnerApp}");
-            lines = lines.Replace("{{originalName}}", $"{taskDefinition.Name}");
+            modelGenerator.AddXmlComment("originalName", taskDefinition.Name);
+            modelGenerator.AddXmlComment("ownerEmail", taskDefinition.OwnerEmail);
+            modelGenerator.AddXmlComment("node", note);
 
             var description = "";
             try
@@ -268,13 +258,11 @@ public string CreateTaskClass(TaskDefinition taskDefinition)
             if (string.IsNullOrEmpty(ownerApp))
                 _logger.LogWarning($"No owner app defined for task {taskDefinition.Name}");
 
-            lines = lines.Replace("{{description}}", description);
-            lines = lines.Replace("{{commentDescription}}", description.Replace('\n', ','));
-
+            modelGenerator.AddXmlComment("summary", description.Replace('\n', ','));
             if (_config.Dryrun)
-                return null;
+                return (null, null);
 
-            return lines;
+            return (modelGenerator.Build(), name);
         }
     }
 }

From 4fbda2cb77c6ee5cdef35c88e25c8a74f200a7e8 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Tue, 16 Aug 2022 12:54:46 +0200
Subject: [PATCH 28/37] Remve unnecessary property

---
 src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
index fe51e7b1..34b0e811 100644
--- a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
+++ b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
@@ -24,7 +24,6 @@ public class PropertyData
         public string Namespace { get; set; }
         public string ClassName { get; set; }
         public string OriginalName { get; set; }
-        public string Summary { get; set; }
 
         protected CompilationUnitSyntax _compilationUnit = SyntaxFactory.CompilationUnit();
         private readonly ModelType _modelType;

From 28210b59c628834ab9a9b475e329f08edd5fd17b Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Tue, 16 Aug 2022 13:04:23 +0200
Subject: [PATCH 29/37] Create directory sctructure if it does not exists

---
 .../Service/ScaffoldingService.cs             | 22 ++-----------------
 1 file changed, 2 insertions(+), 20 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
index 052eb879..00f897a9 100644
--- a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
+++ b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
@@ -28,6 +28,7 @@ public async Task Scaffold()
             var workflowDefinitions = await _metadataService.GetAllWorkflowDefinitions();
             var workflowCollectionBuilder = new StringBuilder();
             var workflowDirectory = Path.Combine(_config.Destination, "Workflows");
+            Directory.CreateDirectory(workflowDirectory);
             foreach (var workflowDefinition in workflowDefinitions)
             {
                 (var contents, var modelClassName) = CreateWorkflowClass(workflowDefinition);
@@ -42,6 +43,7 @@ public async Task Scaffold()
             var taskDefinitions = await _metadataService.GetAllTaskDefinitions();
             var taskCollectionBuilder = new StringBuilder();
             var tasksDirectory = Path.Combine(_config.Destination, "Tasks");
+            Directory.CreateDirectory(tasksDirectory);
             foreach (var taskDefinition in taskDefinitions)
             {
                 (var contents, var modelClassName) = CreateTaskClass(taskDefinition);
@@ -52,26 +54,6 @@ public async Task Scaffold()
                     File.WriteAllText(filePath, contents);
                 }
             }
-
-            //var taskTemplate = EmbeddedFileHelper.GetLinesFromEmbeddedFile("~/Templates/TaskCollectionTemplate.default");
-            //var taskCollection = taskCollectionBuilder.ToString();
-            //taskTemplate = taskTemplate.Replace("{{namespace}}", _config.BaseNamespace + ".Tasks");
-            //taskTemplate = taskTemplate.Replace("{{taskCollection}}", taskCollection);
-            //var dir = _config.Destination + Path.DirectorySeparatorChar + "Tasks";
-
-            //Directory.CreateDirectory(dir);
-
-            //File.WriteAllText(dir + Path.DirectorySeparatorChar + "Tasks.scaff.cs", taskTemplate);
-
-            //var workflowTemplate = EmbeddedFileHelper.GetLinesFromEmbeddedFile("~/Templates/WorkflowCollectionTemplate.default");
-            //var workflowCollection = workflowCollectionBuilder.ToString();
-            //workflowTemplate = workflowTemplate.Replace("{{namespace}}", _config.BaseNamespace + ".Workflows");
-            //workflowTemplate = workflowTemplate.Replace("{{workflowCollection}}", workflowCollection);
-            //var workflowDir = _config.Destination + Path.DirectorySeparatorChar + "Workflows";
-
-            //Directory.CreateDirectory(workflowDir);
-
-            //File.WriteAllText(workflowDir + Path.DirectorySeparatorChar + "Workflows.scaff.cs", workflowTemplate);
         }
 
         public (string contents, string modelClassName) CreateWorkflowClass(WorkflowDefinition workflowDefinition)

From c5b07488e1e81425ee8e3907062986fbdb86c00e Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Tue, 16 Aug 2022 13:04:58 +0200
Subject: [PATCH 30/37] Remove unnecessary lines

---
 src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
index 00f897a9..cc1bc8a2 100644
--- a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
+++ b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
@@ -26,7 +26,6 @@ public ScaffoldingService(IMetadataService metadataService, IOptions<Scaffolding
         public async Task Scaffold()
         {
             var workflowDefinitions = await _metadataService.GetAllWorkflowDefinitions();
-            var workflowCollectionBuilder = new StringBuilder();
             var workflowDirectory = Path.Combine(_config.Destination, "Workflows");
             Directory.CreateDirectory(workflowDirectory);
             foreach (var workflowDefinition in workflowDefinitions)
@@ -41,7 +40,6 @@ public async Task Scaffold()
             }
 
             var taskDefinitions = await _metadataService.GetAllTaskDefinitions();
-            var taskCollectionBuilder = new StringBuilder();
             var tasksDirectory = Path.Combine(_config.Destination, "Tasks");
             Directory.CreateDirectory(tasksDirectory);
             foreach (var taskDefinition in taskDefinitions)

From 63e96e83ca085425aa41490826f3d764d7664ed3 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Tue, 16 Aug 2022 13:17:36 +0200
Subject: [PATCH 31/37] Remove unnecessary comment

---
 src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
index 34b0e811..d3e08219 100644
--- a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
+++ b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
@@ -69,15 +69,6 @@ public string Build()
 
         private SyntaxTriviaList GenerateAutoGeneratedComment()
         {
-            // This comment is written:
-
-            // <autogenerated>
-            //     This code was generated by a tool.
-            //
-            //     Changes to this file may cause incorrect behavior and will be lost if
-            //     the code is regenerated.
-            // </autogenerated>
-
             var list = SyntaxFactory.TriviaList();
             list = list.Add(SyntaxFactory.Comment("// <autogenerated>"));
             list = list.Add(SyntaxFactory.Comment("//     This code was generated by a tool."));

From a9926c72b1d57fb9e85d9cc0cdb86ec9d98f8f32 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Tue, 16 Aug 2022 13:19:19 +0200
Subject: [PATCH 32/37] Add stack trace

---
 src/ConductorSharp.Toolkit/Program.cs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/ConductorSharp.Toolkit/Program.cs b/src/ConductorSharp.Toolkit/Program.cs
index fed52eff..f25f91bb 100644
--- a/src/ConductorSharp.Toolkit/Program.cs
+++ b/src/ConductorSharp.Toolkit/Program.cs
@@ -71,6 +71,8 @@ private static async Task RunToolkit(ToolkitOptions options)
             catch (Exception ex)
             {
                 Console.Error.WriteLine($"Exception occured with message: {ex.Message}");
+                Console.Error.WriteLine("Stack trace:");
+                Console.Error.WriteLine(ex.StackTrace);
             }
         }
 

From 004f9645b0d84cf02bb6483b7fdbb33de6b5ffdf Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 22 Aug 2022 13:19:16 +0200
Subject: [PATCH 33/37] Generate OriginalName attribute

---
 .../Util/TaskModelGenerator.cs                    | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
index d3e08219..93de7e7a 100644
--- a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
+++ b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
@@ -98,6 +98,18 @@ private AttributeSyntax CreateInputPropertyAttribute(string originalName)
             return attribute;
         }
 
+        private AttributeSyntax CreateOriginalNameAttribute(string originalName)
+        {
+            var attribute = SyntaxFactory
+                .Attribute(SyntaxFactory.ParseName("OriginalName"))
+                .AddArgumentListArguments(
+                    SyntaxFactory.AttributeArgument(
+                        SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(originalName))
+                    )
+                );
+            return attribute;
+        }
+
         private PropertyDeclarationSyntax CreateProperty(PropertyData inputData)
         {
             var propertyDeclaration = SyntaxFactory
@@ -174,9 +186,12 @@ private ClassDeclarationSyntax CreateModelClass()
                     .WithTypeArgumentList(typeArgumentList)
             );
             var baseList = SyntaxFactory.BaseList(SyntaxFactory.SingletonSeparatedList<BaseTypeSyntax>(baseType));
+
+            var attributeList = SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(CreateOriginalNameAttribute(OriginalName)));
             var classDeclaration = SyntaxFactory
                 .ClassDeclaration(ClassName)
                 .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.PartialKeyword))
+                .AddAttributeLists(attributeList)
                 .WithBaseList(baseList)
                 .WithLeadingTrivia(GenerateXmlDocComment(_xmlComments));
 

From 8092cea3eddbaf653e7e4fb3d64a447dfed7a9ac Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 22 Aug 2022 13:19:38 +0200
Subject: [PATCH 34/37] Specify OriginalName for task and classes

---
 .../Service/ScaffoldingService.cs                     | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
index cc1bc8a2..201fe3aa 100644
--- a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
+++ b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
@@ -63,7 +63,10 @@ public async Task Scaffold()
                 note = "The autogenerated name has been changed because it is invalid C# member name";
             }
 
-            var modelGenerator = new TaskModelGenerator(_config.BaseNamespace + ".Workflows", name, TaskModelGenerator.ModelType.Workflow);
+            var modelGenerator = new TaskModelGenerator(_config.BaseNamespace + ".Workflows", name, TaskModelGenerator.ModelType.Workflow)
+            {
+                OriginalName = workflowDefinition.Name
+            };
             string workflowDescription = workflowDefinition.Description;
             string[] labels;
 
@@ -198,7 +201,11 @@ private void AppendXmlComment(StringBuilder linesBuilder, string tag, string val
                 note = "The autogenerated name has been prepended because it starts with a digit character.";
             }
 
-            var modelGenerator = new TaskModelGenerator(_config.BaseNamespace + ".Tasks", name, TaskModelGenerator.ModelType.Task);
+            var modelGenerator = new TaskModelGenerator(_config.BaseNamespace + ".Tasks", name, TaskModelGenerator.ModelType.Task)
+            {
+                OriginalName = taskDefinition.Name
+            };
+
             foreach (var property in taskDefinition.InputKeys)
             {
                 var inputPropData = new TaskModelGenerator.PropertyData();

From 787b9d27e1b3ad7c48a0e14f665748955ff2161c Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 22 Aug 2022 13:26:53 +0200
Subject: [PATCH 35/37] Add MemberNamePrefix constant

---
 .../Service/ScaffoldingService.cs             | 23 +++++--------------
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
index 201fe3aa..36240c95 100644
--- a/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
+++ b/src/ConductorSharp.Toolkit/Service/ScaffoldingService.cs
@@ -16,6 +16,9 @@ public class ScaffoldingService : IScaffoldingService
         private readonly ILogger<ScaffoldingService> _logger;
         private readonly ScaffoldingConfig _config;
 
+        // Prefix prepended if member name is invalid
+        private const string MemberNamePrefix = "A";
+
         public ScaffoldingService(IMetadataService metadataService, IOptions<ScaffoldingConfig> options, ILogger<ScaffoldingService> logger)
         {
             _metadataService = metadataService;
@@ -58,7 +61,7 @@ public async Task Scaffold()
         {
             string name = SnakeCaseUtil.ToPascalCase($"{workflowDefinition.Name}_V{workflowDefinition.Version}").Trim();
             string note = null;
-            if (LangUtils.MakeValidMemberName(name, "A", out name))
+            if (LangUtils.MakeValidMemberName(name, MemberNamePrefix, out name))
             {
                 note = "The autogenerated name has been changed because it is invalid C# member name";
             }
@@ -170,33 +173,19 @@ public async Task Scaffold()
             return (modelGenerator.Build(), name);
         }
 
-        private void AppendClassProperty(StringBuilder linesBuilder, string type, string name)
-        {
-            linesBuilder.AppendLine($"        [JsonProperty(\"{name}\")]");
-            LangUtils.MakeValidMemberName(SnakeCaseUtil.ToPascalCase(name), "A", out var propertyName);
-            linesBuilder.AppendLine($"        public {type} {propertyName} {{ get; set; }}");
-        }
-
         private void DefinePropertyParams(TaskModelGenerator.PropertyData propData, string type, string originalName)
         {
-            LangUtils.MakeValidMemberName(SnakeCaseUtil.ToPascalCase(originalName), "A", out var propertyName);
+            LangUtils.MakeValidMemberName(SnakeCaseUtil.ToPascalCase(originalName), MemberNamePrefix, out var propertyName);
             propData.OriginalName = originalName;
             propData.Name = propertyName;
             propData.Type = type;
         }
 
-        private void AppendXmlComment(StringBuilder linesBuilder, string tag, string value)
-        {
-            linesBuilder.AppendLine($"        /// <{tag}>");
-            linesBuilder.AppendLine($"        /// {value}");
-            linesBuilder.AppendLine($"        /// </{tag}>");
-        }
-
         public (string contents, string modelClassName) CreateTaskClass(TaskDefinition taskDefinition)
         {
             string name = SnakeCaseUtil.ToPascalCase(taskDefinition.Name).Trim();
             string note = null;
-            if (LangUtils.MakeValidMemberName(name, "A", out name))
+            if (LangUtils.MakeValidMemberName(name, MemberNamePrefix, out name))
             {
                 note = "The autogenerated name has been prepended because it starts with a digit character.";
             }

From 9168268565813d92f7fae8a8b7660a049366e8d2 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 22 Aug 2022 13:37:24 +0200
Subject: [PATCH 36/37] Add readonly modifier, use arrow syntax for some
 methods

---
 .../Util/TaskModelGenerator.cs                 | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
index 93de7e7a..530b0196 100644
--- a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
+++ b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
@@ -25,10 +25,10 @@ public class PropertyData
         public string ClassName { get; set; }
         public string OriginalName { get; set; }
 
-        protected CompilationUnitSyntax _compilationUnit = SyntaxFactory.CompilationUnit();
+        private CompilationUnitSyntax _compilationUnit = SyntaxFactory.CompilationUnit();
         private readonly ModelType _modelType;
-        private List<PropertyData> _inputProperties = new();
-        private List<PropertyData> _outputProperties = new();
+        private readonly List<PropertyData> _inputProperties = new();
+        private readonly List<PropertyData> _outputProperties = new();
         private readonly Dictionary<string, string> _xmlComments = new();
 
         public TaskModelGenerator(string @namespace, string className, ModelType modelType)
@@ -38,15 +38,9 @@ public TaskModelGenerator(string @namespace, string className, ModelType modelTy
             _modelType = modelType;
         }
 
-        public void AddInputProperty(PropertyData propData)
-        {
-            _inputProperties.Add(propData);
-        }
+        public void AddInputProperty(PropertyData propData) => _inputProperties.Add(propData);
 
-        public void AddOutputProperty(PropertyData propData)
-        {
-            _outputProperties.Add(propData);
-        }
+        public void AddOutputProperty(PropertyData propData) => _outputProperties.Add(propData);
 
         public void AddXmlComment(string tag, string value) => _xmlComments[tag] = value;
 
@@ -150,7 +144,7 @@ private SyntaxTriviaList GenerateXmlDocComment(Dictionary<string, string> xmlCom
         private ClassDeclarationSyntax CreateInputClass()
         {
             var typeArgumentList = SyntaxFactory.TypeArgumentList(
-                SyntaxFactory.SingletonSeparatedList<TypeSyntax>(SyntaxFactory.ParseTypeName($"{ClassName}Output"))
+                SyntaxFactory.SingletonSeparatedList(SyntaxFactory.ParseTypeName($"{ClassName}Output"))
             );
             var baseType = SyntaxFactory.SimpleBaseType(SyntaxFactory.GenericName("IRequest").WithTypeArgumentList(typeArgumentList));
             var baseList = SyntaxFactory.BaseList(SyntaxFactory.SingletonSeparatedList<BaseTypeSyntax>(baseType));

From 18107e87179db815c8854c3a9f43e96f47b05765 Mon Sep 17 00:00:00 2001
From: "bojan.malinic" <bojan.malinic@codaxy.com>
Date: Mon, 22 Aug 2022 13:39:38 +0200
Subject: [PATCH 37/37] Remove unnecessary newline

---
 src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
index 530b0196..2e19150c 100644
--- a/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
+++ b/src/ConductorSharp.Toolkit/Util/TaskModelGenerator.cs
@@ -69,7 +69,6 @@ private SyntaxTriviaList GenerateAutoGeneratedComment()
             list = list.Add(SyntaxFactory.Comment("//     Changes to this file may cause incorrect behavior and will be lost if"));
             list = list.Add(SyntaxFactory.Comment("//     the code is regenerated."));
             list = list.Add(SyntaxFactory.Comment("// </autogenerated>"));
-
             return list;
         }
 
