/// <summary>
        /// Gets the deployment tasks for the supplied deployment template.
        /// </summary>
        /// <param name="template">The deployment template.</param>
        /// <param name="scriptPath">The script path.</param>
        /// <param name="parameters">The deployment parameters.</param>
        /// <returns>Instance of <see cref="TaskExecutor"/> with tasks and task execution context.</returns>
        public TaskExecutor BuildTasks(DeploymentTemplate template, string scriptPath, IDictionary<string, string> parameters)
        {
            var sortedResources = ResourceDependencies.DependencySort(template.Resources).Reverse().ToList();

            // Extract the resources which already exist from the resource collection and create a task to load them.
            var existingResources = new List<Resource>();
            var resourcesWithExistingCaasId = sortedResources
                .Where(resource => !string.IsNullOrEmpty(resource.ExistingCaasId))
                .ToList();

            foreach (var resource in resourcesWithExistingCaasId)
            {
                var existingCaasId = ParametersMacro.SubstituteTokensInString(resource.ExistingCaasId, parameters, false);
                if (!string.IsNullOrEmpty(existingCaasId))
                {
                    sortedResources.Remove(resource);
                    existingResources.Add(resource);
                }
            }

            var tasks = new List<ITask>();

            if (existingResources.Count > 0)
            {
                tasks.Add(new LoadExistingResourcesTask(existingResources));

                foreach (var existingResource in existingResources)
                {
                    if ((existingResource.Scripts != null) && (existingResource.ResourceType == ResourceType.Server))
                    {
                        tasks.Add(new ExecuteScriptTask(existingResource, scriptPath));
                    }
                }
            }

            // Create the tasks to deploy new resources.
            foreach (var resource in sortedResources)
            {
                tasks.Add(new DeployResourceTask(resource));

                if ((resource.Scripts != null) && (resource.ResourceType == ResourceType.Server))
                {
                    tasks.Add(new ExecuteScriptTask(resource, scriptPath));
                }
            }

            if (template.Orchestration != null)
            {
                tasks.Add(new RunOrchestrationTask(template.Orchestration, sortedResources));
            }

            if (template.OutputParameters != null && template.OutputParameters.Properties().Any())
            {
                tasks.Add(new SetOutputParametersTask(template.OutputParameters));
            }

            // Create the task execution context.
            var context = new TaskContext
            {
                Parameters = parameters,
                ResourcesProperties = new Dictionary<string, JObject>(),
                Log = new DeploymentLog()
                {
                    DeploymentTime = DateTime.Now,
                    TemplateName = template.Metadata.TemplateName,
                    Resources = new List<ResourceLog>()
                }
            };

            return new TaskExecutor(template, tasks, context);
        }
 /// <summary>
 /// Gets the deployment tasks for the supplied deployment template.
 /// </summary>
 /// <param name="template">The deployment template.</param>
 /// <param name="scriptPath">The script path.</param>
 /// <returns>Instance of <see cref="TaskExecutor"/> with tasks and task execution context.</returns>
 public TaskExecutor BuildTasks(DeploymentTemplate template, string scriptPath)
 {
     return BuildTasks(template, scriptPath, new Dictionary<string, string>());
 }