public Recipe ParseRecipe(string recipeText)
        {
            var recipe = new Recipe();

            try {
                var recipeSteps = new List<RecipeStep>();
                TextReader textReader = new StringReader(recipeText);
                var recipeTree = XElement.Load(textReader, LoadOptions.PreserveWhitespace);
                textReader.Close();

                foreach (var element in recipeTree.Elements()) {
                    // Recipe mETaDaTA
                    if (element.Name.LocalName == "Recipe") {
                        foreach (var metadataElement in element.Elements()) {
                            switch (metadataElement.Name.LocalName) {
                                case "Name":
                                    recipe.Name = metadataElement.Value;
                                    break;
                                case "Description":
                                    recipe.Description = metadataElement.Value;
                                    break;
                                case "Author":
                                    recipe.Author = metadataElement.Value;
                                    break;
                                case "WebSite":
                                    recipe.WebSite = metadataElement.Value;
                                    break;
                                case "Version":
                                    recipe.Version = metadataElement.Value;
                                    break;
                                case "ExportUtc":
                                    recipe.ExportUtc = !string.IsNullOrEmpty(metadataElement.Value) ? (DateTime?)XmlConvert.ToDateTime(metadataElement.Value, XmlDateTimeSerializationMode.Utc) : null;
                                    break;
                                case "Tags":
                                    recipe.Tags = metadataElement.Value;
                                    break;
                                default:
                                    Logger.Error("Unrecognized recipe metadata element {0} encountered. Skipping.", metadataElement.Name.LocalName);
                                    break;
                            }
                        }
                    }
                    // Recipe step
                    else {
                        var recipeStep = new RecipeStep { Name = element.Name.LocalName, Step = element };
                        recipeSteps.Add(recipeStep);
                    }
                }
                recipe.RecipeSteps = recipeSteps;
            }
            catch (Exception exception) {
                Logger.Error(exception, "Parsing recipe failed. Recipe text was: {0}.", recipeText);
                throw;
            }

            return recipe;
        }
        public string Execute(Recipe recipe)
        {
            if (recipe == null)
                return null;

            var executionId = Guid.NewGuid().ToString("n");
            _recipeJournal.ExecutionStart(executionId);
            _recipeExecuteEventHandler.ExecutionStart(executionId, recipe);

            foreach (var recipeStep in recipe.RecipeSteps) {
                _recipeStepQueue.Enqueue(executionId, recipeStep);
            }
            _recipeScheduler.ScheduleWork(executionId);

            return executionId;
        }