public RecipeStep Dequeue(string executionId)
        {
            if (!_appDataFolder.DirectoryExists(Path.Combine(_recipeQueueFolder, executionId))) {
                return null;
            }
            RecipeStep recipeStep = null;
            int stepIndex = GetFirstStepIndex(executionId);
            if (stepIndex >= 0) {
                var stepPath = Path.Combine(_recipeQueueFolder, executionId + Path.DirectorySeparatorChar + stepIndex);
                // string to xelement
                var stepElement = XElement.Parse(_appDataFolder.ReadFile(stepPath));
                var stepName = stepElement.Element("Name").Value;
                recipeStep = new RecipeStep {
                    Name = stepName,
                    Step = stepElement.Element(stepName)
                };
                _appDataFolder.DeleteFile(stepPath);
            }

            if (stepIndex < 1) {
                _appDataFolder.DeleteFile(Path.Combine(_recipeQueueFolder, executionId));
            }

            return recipeStep;
        }
        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 void Enqueue(string executionId, RecipeStep step)
        {
            var recipeStepElement = new XElement("RecipeStep");
            recipeStepElement.Add(new XElement("Name", step.Name));
            recipeStepElement.Add(step.Step);

            if (_appDataFolder.DirectoryExists(Path.Combine(_recipeQueueFolder, executionId))) {
                int stepIndex = GetLastStepIndex(executionId) + 1;
                _appDataFolder.CreateFile(Path.Combine(_recipeQueueFolder, executionId + Path.DirectorySeparatorChar + stepIndex),
                                          recipeStepElement.ToString());
            }
            else {
                _appDataFolder.CreateFile(
                    Path.Combine(_recipeQueueFolder, executionId + Path.DirectorySeparatorChar + "0"),
                    recipeStepElement.ToString());
            }
        }