/// <summary>
        /// Created a new menu owned by the current user.
        /// </summary>
        /// <param name="menu">A menu to create.</param>
        /// <param name="recipeIds">Zero or more recipes to add to the newly created menu.</param>
        /// <returns>A result indicating the new menu ID.</returns>
        public MenuResult CreateMenu(Menu menu, params Guid[] recipeIds)
        {
            menu.Title = menu.Title.Trim();
            var ret = new MenuResult();

            Menus databaseMenu;
            var dupes = this.store.Menus
               .Where(p => p.UserId == this.Identity.UserId)
               .Any(p => p.Title == menu.Title);

            if (dupes)
            {
                throw new MenuAlreadyExistsException();
            }

            this.store.Menus.Add(databaseMenu = new Provisioning.DTO.Menus
            {
                MenuId = Guid.NewGuid(),
                UserId = this.Identity.UserId,
                Title = menu.Title,
                CreatedDate = DateTime.Now,
            });

            foreach (var rid in recipeIds.NeverNull())
            {
                var fav = new Favorites
                {
                    FavoriteId = Guid.NewGuid(),
                    UserId = this.Identity.UserId,
                    RecipeId = rid,
                    MenuId = databaseMenu.MenuId
                };

                this.store.Favorites.Add(fav);
            }

            ret.MenuCreated = true;
            ret.NewMenuId = databaseMenu.MenuId;

            return ret;
        }
        /// <summary>
        /// Updates a specified menu owned by the current user.
        /// </summary>
        /// <param name="menuId">The Menu ID to update, or null to update the Favorites menu.</param>
        /// <param name="recipesAdd">A list of recipe IDs to add to the menu.  Duplicates will be ignored.</param>
        /// <param name="recipesRemove">A list of recipe IDs to remove from the menu.</param>
        /// <param name="recipesMove">A list of items to move from this menu to another menu.</param>
        /// <param name="clear">If true, all recipes will be removed from this menu.</param>
        /// <param name="newName">An optional new name for this menu.  Note, the favorites menu cannot be renamed.</param>
        /// <returns></returns>
        public MenuResult UpdateMenu(
            Guid? menuId,
            Guid[] recipesAdd,
            Guid[] recipesRemove,
            MenuMove[] recipesMove,
            bool clear,
            string newName = null)
        {
            var ret = new MenuResult();
            ret.MenuUpdated = true; // TODO: Verify actual changes were made before setting MenuUpdated to true

            Menus databaseMenu = null;
            if (menuId.HasValue)
            {
                databaseMenu = this.store.Menus.SingleOrDefault(p => p.MenuId == menuId);
                if (databaseMenu == null)
                {
                    throw new MenuNotFoundException();
                }

                if (databaseMenu.UserId != this.Identity.UserId)
                {
                    // User does not have access to modify this menu
                    throw new UserDoesNotOwnMenuException();
                }
            }

            var databaseFavorites = this.store.Favorites
               .Where(p => p.MenuId == menuId)
               .ToList();

            if (!string.IsNullOrWhiteSpace(newName) && databaseMenu != null)
            {
                // Rename menu
                databaseMenu.Title = newName.Trim();
            }

            if (recipesAdd.Any())
            {
                // Add recipes to menu
                var existing = databaseFavorites.Select(f => f.RecipeId);
                recipesAdd = recipesAdd.Except(existing).ToArray(); // Remove dupes

                foreach (var rid in recipesAdd)
                {
                    var fav = new Favorites
                    {
                        FavoriteId = Guid.NewGuid(),
                        UserId = this.Identity.UserId,
                        RecipeId = rid,
                        MenuId = menuId
                    };

                    this.store.Favorites.Add(fav);
                }
            }

            if (recipesRemove.Any())
            {
                // Remove recipes from menu
                var toDelete = from r in databaseFavorites where recipesRemove.Contains(r.RecipeId) select r;
                toDelete.ForEach(r => this.store.Favorites.Remove(r));
            }

            if (clear)
            {
                // Remove every recipe from menu
                this.store.Favorites.RemoveAll(databaseFavorites.Contains);
            }

            if (recipesMove.Any())
            {
                // Move items to another menu
                foreach (var moveAction in recipesMove)
                {
                    Menus databaseTarget = null;
                    if (moveAction.TargetMenu.HasValue)
                    {
                        databaseTarget = this.store.Menus
                           .Where(p => p.UserId == this.Identity.UserId)
                           .SingleOrDefault(p => p.MenuId == moveAction.TargetMenu);

                        if (databaseTarget == null)
                        {
                            throw new MenuNotFoundException(moveAction.TargetMenu.Value);
                        }
                    }

                    var action = moveAction;
                    var readyToMove = moveAction.MoveAll
                       ? databaseFavorites
                       : databaseFavorites.Where(r => action.RecipesToMove.Contains(r.RecipeId));

                    readyToMove.ForEach(a => a.MenuId = databaseTarget != null ? (Guid?)databaseTarget.MenuId : null);
                }
            }

            return ret;
        }