/// <summary>
 /// Parses any commands contained in the Comment, which must begin with the prefix specified in the constructor.
 /// For each command detected, if any, the relevant Parse method is called,
 /// and then the relevant method of <paramref name="Callback"/> is called with the results.
 /// </summary>
 /// <param name="HostComment">The Imgur Comment to parse for commands</param>
 /// <param name="Callback">An object that handles execution of any commands found</param>
 public Task ProcessCommandsUnconditionally(IComment HostComment, ImgurCommandHandler Callback)
 {
     return(ProcessCommands(HostComment, Callback, false));
 }
        protected async Task <bool> ProcessCommands(IComment HostComment, ImgurCommandHandler Callback, bool CheckForReplies)
        {
            ICollection <Match> ParsedCommands = Pattern_Command.Matches(HostComment.CommentText);

            Log.Imgur_.LogVerbose("Parsing Comment made by '{1}' at {2:u} on Gallery Item '{3}' [#{0:D}] for commands; total commands found - {4}", HostComment.Id, HostComment.Author, HostComment.DateTime, HostComment.ImageId, ParsedCommands.Count);
            bool CommandsFound = false;

            foreach (Match ParsedCommand in ParsedCommands)
            {
                if (CheckForReplies)
                {
                    //Only need to check once per Comment
                    CheckForReplies = false;
                    //Skip Comments that have already been replied to by this application; otherwise Comments will be re-processed
                    Log.Imgur_.LogVerbose("Checking if Comment #{0:D} has already been processed", HostComment.Id);
                    if (!await ShouldProcess(HostComment))
                    {
                        Log.Imgur_.LogVerbose("Comment #{0:D} already processed; skipping", HostComment.Id);
                        continue;
                    }
                }
                string Command = ParsedCommand.Groups[1].Value
                                 .Normalize(NormalizationForm.FormKD)
                                 .ToUpperInvariant()
                ;
                Log.Imgur_.LogVerbose("Found Imgur Comment command '{1}' in Comment #{0:D}", HostComment.Id, Command);
                switch (Command)
                {
                case Command_Tag:
                default:
                    Log.Imgur_.LogVerbose("Parsing 'tag' command in Comment #{0:D}", HostComment.Id);
                    if (ParseTagCommand(
                            HostComment.CommentText,
                            ParsedCommand.Index,
                            HostComment.Id,
                            //The ImageId property will also be set if the Comment is on an Album, in which case it will be the Album ID
                            HostComment.ImageId,
                            HostComment.OnAlbum,
                            out TagCommandParameters CommandParameter
                            ))
                    {
                        CommandsFound = true;
                        Log.Imgur_.LogVerbose(
                            "'tag' command in Comment #{0:D} parsed successfully: Taglist - '{1}', Rating - {2}, Total Categoties - {3}",
                            HostComment.Id,
                            CommandParameter.TaglistName, CommandParameter.Rating, CommandParameter.Categories.Count
                            );
                        await Callback.ProcessTagCommand(CommandParameter);
                    }
                    else
                    {
                        Log.Imgur_.LogWarning(
                            "The following Tag command on the Imgur Gallery item '{0}' by User '{1}' could not be parsed: {2}",
                            HostComment.ImageId, HostComment.Author, HostComment.CommentText.Substring(ParsedCommand.Index)
                            );
                    }
                    break;
                }
            }
            return(CommandsFound);
        }
 /// <summary>
 /// As for <see cref="ProcessCommandsUnconditionally"/>, except <see cref="ShouldProcess"/> is called for the Comment,
 /// to determine if it has already been processed.
 /// For efficiency, it is called only if needed, to preserve Imgur API bandwidth.
 /// Returns true if at least one command in the Comment was identified and submitted for processing, false otherwise.
 /// </summary>
 public Task <bool> ProcessCommands(IComment HostComment, ImgurCommandHandler Callback)
 {
     return(ProcessCommands(HostComment, Callback, true));
 }