public void Execute()
    {
        /* Replace keywords */
        _presetObj.AutomationUpdates.AutomationUpdatesPath = _keyReplace.Replace(_presetObj.AutomationUpdates.AutomationUpdatesPath);
        if (string.IsNullOrEmpty(_presetObj.AutomationUpdates.AutomationUpdatesPath))
        {
            return;
        }

        for (int i = 0; i < _presetObj.AutomationUpdates.AutomationUpdatesArgs.Count; i++)
        {
            var arg = _presetObj.AutomationUpdates.AutomationUpdatesArgs.ElementAt(i);
            _presetObj.AutomationUpdates.AutomationUpdatesArgs[arg.Key] = _keyReplace.Replace(arg.Value).Replace(' ', '_');
        }

        _logger.LogDebug("AutomationToolkit path: " + _presetObj.AutomationUpdates.AutomationUpdatesPath);
        _logger.LogDebug("AutomationToolkit args: " + string.Join(' ', _presetObj.AutomationUpdates.AutomationUpdatesArgs.Select(p => p.Value).ToArray()));

        /* Run AutomationToolkitUpdates */
        try
        {
            _process = new Process();
            _process.EnableRaisingEvents = true;
            _process.OutputDataReceived += process_OutputDataReceived;
            _process.ErrorDataReceived  += process_ErrorDataReceived;
            _process.Exited += process_Exited;

            _process.StartInfo.FileName               = _presetObj.AutomationUpdates.AutomationUpdatesPath;
            _process.StartInfo.Arguments              = string.Join(' ', _presetObj.AutomationUpdates.AutomationUpdatesArgs.Select(p => p.Value).ToArray());
            _process.StartInfo.UseShellExecute        = false;
            _process.StartInfo.RedirectStandardError  = true;
            _process.StartInfo.RedirectStandardOutput = true;

            _logger.LogDebug("[AutomationToolkitUpdates process]=> ");

            _process.Start();
            _process.BeginErrorReadLine();
            _process.BeginOutputReadLine();

            _process.WaitForExit();
        }
        catch (Exception ex)
        {
            //_messages.Add("AutomationToolkit path: " + _presetObj.AutomationUpdates.AutomationUpdatesPath);
            //_messages.Add("AutomationToolkit args: " + string.Join(' ', _presetObj.AutomationUpdates.AutomationUpdatesArgs.Select(p => p.Value).ToArray()));
            //_messages.Add("AutomationToolkit error:");
            _logger.LogError(ex.ToString());
        }
    }
    public async Task Generate(Preset value)
    {
        _logger.LogDebug("Post GenerateProjects");

        _keywordReplace.AddKeywords(value.Keywords);
        _keywordReplace.ReplaceAll();
        _logger.LogDebug("Replaced keywords");

        /* Copy Project structure from template */
        if (!Path.IsPathRooted(value.TemplateOrigin))
        {
            value.TemplateOrigin = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, value.TemplateOrigin);
        }
        var templateOriginInfo = new DirectoryInfo(value.TemplateOrigin);

        if (!templateOriginInfo.Exists)
        {
            throw new ArgumentException("Invalid template origin path");
        }

        var copiedFolders        = new List <DirectoryInfo>();
        var outputFolderPathInfo = new DirectoryInfo(_keywordReplace.Replace(value.OutputFolderPath));

        DirectoryCopy(templateOriginInfo.FullName, outputFolderPathInfo.FullName, true, outputFolderPathInfo.FullName, copiedFolders);

        /* Replace keywords in files matching search pattern */
        await ReplaceKeywordsInFiles(value.FileKeywordTypesExtensions, copiedFolders);

        _logger.LogDebug("Replaced keywords in files");

        if (value.AddToSourceControl)
        {
            var tfPath = await _appSettingsService.TFPath();

            var tf = new TFImpl(tfPath);
            foreach (var dirInfo in copiedFolders)
            {
                /* Add to Source Control */
                _logger.LogDebug("Adding project to Source Control");
                tf.RunTFCommand(dirInfo.FullName, new[] { "add", "*.*", "/recursive" });

                /* Update main solution with new project (Glx/Crm build convention)*/
                var buildSolutionDirInfo = dirInfo.Parent.GetDirectories($"Build_*");
                if (buildSolutionDirInfo.Length > 0)
                {
                    var buildSolutionPath = buildSolutionDirInfo[0].GetFiles("*.sln");
                    if (buildSolutionPath.Length > 0)
                    {
                        _logger.LogDebug("Update main build solution");
                        tf.RunTFCommand(dirInfo.FullName, new[] { "checkout", buildSolutionPath[0].FullName });

                        var slnObj = new SolutionParser(buildSolutionPath[0].FullName);
                        slnObj.AddProject(dirInfo.Name);
                    }
                }
            }
        }

        if (value.AutomationUpdates.UseAutomationUpdates)
        {
            _logger.LogDebug("Executing automation toolkit updates");
            var handler = new AutomationUpdatesHandler(_logger, value, _keywordReplace);
            handler.Execute();
        }
    }