private void process_results(PackageValidationResultMessage message)
        {
            var resultsMessage = new StringBuilder();

            var failedRequirements = message.ValidationResults.Where(r => r.Validated == false && r.ValidationLevel == ValidationLevelType.Requirement);
            if (failedRequirements.Count() != 0)
            {
                resultsMessage.Append("##### Requirements{0}".format_with(Environment.NewLine));
                resultsMessage.Append("When a package version has failed requirements, the package version requires fixing or response by the maintainer. If items are flagged correctly, they must be fixed before the package version can be approved. The exact same version should be uploaded during moderation review.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var failedRequirement in failedRequirements.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + failedRequirement.ValidationFailureMessage + Environment.NewLine);
            }

            var flaggedGuidelines = message.ValidationResults.Where(r => r.Validated == false && r.ValidationLevel == ValidationLevelType.Guideline);
            if (flaggedGuidelines.Count() != 0)
            {
                resultsMessage.Append("{0}##### Guidelines{1}".format_with(resultsMessage.Length ==0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Guidelines are strong suggestions that improve the quality of a package version. These are considered something to fix for next time to increase the quality of the package. Over time guidelines can become requirements. A package version can be approved without addressing guideline comments.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedGuideline in flaggedGuidelines.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedGuideline.ValidationFailureMessage + Environment.NewLine);
            }

            var flaggedSuggestions = message.ValidationResults.Where(r => r.Validated == false && (r.ValidationLevel == ValidationLevelType.Suggestion));
            if (flaggedSuggestions.Count() != 0)
            {
                resultsMessage.Append("{0}##### Suggestions{1}".format_with(resultsMessage.Length == 0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Suggestions are newly introduced items that should be considered. A package version can be approved without addressing suggestion comments.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedSuggestion in flaggedSuggestions.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedSuggestion.ValidationFailureMessage + Environment.NewLine);
            }

            var flaggedNotes = message.ValidationResults.Where(r => r.Validated == false && (r.ValidationLevel == ValidationLevelType.Note));
            if (flaggedNotes.Count() != 0)
            {
                resultsMessage.Append("{0}##### Notes{1}".format_with(resultsMessage.Length == 0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Notes typically flag things for both you and the reviewer.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedNote in flaggedNotes.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedNote.ValidationFailureMessage + Environment.NewLine);
            }

            var validationMessages = resultsMessage.ToString();
            if (!string.IsNullOrWhiteSpace(validationMessages))
            {
                var messageToSend = validationMessages;
                // send the message
            }

            //todo if you find any that failed validation, it's time to update the website
            //create a message for updating the website with the validation set
            //EventManager.publish(new PackageValidationResultMessage(message.PackageId, message.PackageVersion, validationResults, DateTime.UtcNow));
        }
        private void update_website(PackageValidationResultMessage message)
        {
            var failedRequired = message.ValidationResults.Any(r => r.Validated == false && r.ValidationLevel == ValidationLevelType.Requirement);

            this.Log().Info(() => "Updating website for {0} v{1} with results (package {2} requirements).".format_with(message.PackageId, message.PackageVersion, failedRequired ? "failed" : "passed"));

            try
            {
                var        url    = string.Join("/", SERVICE_ENDPOINT, message.PackageId, message.PackageVersion);
                HttpClient client = _nugetService.get_client(_configurationSettings.PackagesUrl, url, "POST", "application/x-www-form-urlencoded");

                StringBuilder postData = new StringBuilder();
                postData.Append("apikey=" + HttpUtility.UrlEncode(_configurationSettings.PackagesApiKey));
                //postData.Append("&success=" + HttpUtility.UrlEncode(message.Success.to_string().to_lower()));
                //postData.Append("&resultDetailsUrl=" + HttpUtility.UrlEncode(message.ResultDetailsUrl));
                var form = postData.ToString();
                var data = Encoding.ASCII.GetBytes(form);

                client.SendingRequest += (sender, e) =>
                {
                    SendingRequest(this, e);
                    var request = (HttpWebRequest)e.Request;
                    request.Timeout = 30000;
                    request.Headers.Add(_nugetService.ApiKeyHeader, _configurationSettings.PackagesApiKey);

                    request.ContentLength = data.Length;

                    using (var stream = request.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }
                };

                _nugetService.ensure_successful_response(client);
            }
            catch (Exception ex)
            {
                Bootstrap.handle_exception(ex);
            }
        }
        private void update_website(PackageValidationResultMessage message)
        {
            var failedRequired = message.ValidationResults.Any(r => r.Validated == false && r.ValidationLevel == ValidationLevelType.Requirement);
            
            this.Log().Info(() => "Updating website for {0} v{1} with results (package {2} requirements).".format_with(message.PackageId, message.PackageVersion, failedRequired ? "failed" : "passed"));

            try
            {
                var url = string.Join("/", SERVICE_ENDPOINT, message.PackageId, message.PackageVersion);
                HttpClient client = _nugetService.get_client(_configurationSettings.PackagesUrl, url, "POST", "application/x-www-form-urlencoded");

                StringBuilder postData = new StringBuilder();
                postData.Append("apikey=" + HttpUtility.UrlEncode(_configurationSettings.PackagesApiKey));
                //postData.Append("&success=" + HttpUtility.UrlEncode(message.Success.to_string().to_lower()));
                //postData.Append("&resultDetailsUrl=" + HttpUtility.UrlEncode(message.ResultDetailsUrl));
                var form = postData.ToString();
                var data = Encoding.ASCII.GetBytes(form);

                client.SendingRequest += (sender, e) =>
                {
                    SendingRequest(this, e);
                    var request = (HttpWebRequest)e.Request;
                    request.Timeout = 30000;
                    request.Headers.Add(_nugetService.ApiKeyHeader, _configurationSettings.PackagesApiKey);

                    request.ContentLength = data.Length;

                    using (var stream = request.GetRequestStream())
                    {
                        stream.Write(data, 0, data.Length);
                    }
                };

                _nugetService.ensure_successful_response(client);
            }
            catch (Exception ex)
            {
                Bootstrap.handle_exception(ex);
            }
        }
        private void process_results(PackageValidationResultMessage message)
        {
            var resultsMessage = new StringBuilder();

            var failedRequirements = message.ValidationResults.Where(r => r.Validated == false && r.ValidationLevel == ValidationLevelType.Requirement);

            if (failedRequirements.Count() != 0)
            {
                this.Log().Info("{0} v{1} FAILED validation.".format_with(message.PackageId, message.PackageVersion));
                resultsMessage.Append("##### Requirements{0}".format_with(Environment.NewLine));
                resultsMessage.Append("Requirements represent the minimum quality of a package that is acceptable. When a package version has failed requirements, the package version requires fixing and/or response by the maintainer. Provided a Requirement has flagged correctly, it ***must*** be fixed before the package version can be approved. The exact same version should be uploaded during moderation review.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var failedRequirement in failedRequirements.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + failedRequirement.ValidationFailureMessage + Environment.NewLine);
            }

            var flaggedGuidelines = message.ValidationResults.Where(r => r.Validated == false && r.ValidationLevel == ValidationLevelType.Guideline);

            if (flaggedGuidelines.Count() != 0)
            {
                resultsMessage.Append("{0}##### Guidelines{1}".format_with(resultsMessage.Length == 0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Guidelines are strong suggestions that improve the quality of a package version. These are considered something to fix for next time to increase the quality of the package. Over time Guidelines can become Requirements. A package version can be approved without addressing Guideline comments but will reduce the quality of the package.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedGuideline in flaggedGuidelines.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedGuideline.ValidationFailureMessage + Environment.NewLine);
            }

            var flaggedSuggestions = message.ValidationResults.Where(r => r.Validated == false && (r.ValidationLevel == ValidationLevelType.Suggestion));

            if (flaggedSuggestions.Count() != 0)
            {
                resultsMessage.Append("{0}##### Suggestions{1}".format_with(resultsMessage.Length == 0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Suggestions are either newly introduced items that will later become Guidelines or items that are don't carry enough weight to become a Guideline. Either way they should be considered. A package version can be approved without addressing Suggestion comments.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedSuggestion in flaggedSuggestions.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedSuggestion.ValidationFailureMessage + Environment.NewLine);
            }

            var flaggedNotes = message.ValidationResults.Where(r => r.Validated == false && (r.ValidationLevel == ValidationLevelType.Note));

            if (flaggedNotes.Count() != 0)
            {
                resultsMessage.Append("{0}##### Notes{1}".format_with(resultsMessage.Length == 0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Notes typically flag things for both you and the reviewer to go over. Sometimes this is the use of things that may or may not be necessary given the constraints of what you are trying to do and/or are harder for automation to flag for other reasons. Items found in Notes might be Requirements depending on the context. A package version can be approved without addressing Note comments.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedNote in flaggedNotes.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedNote.ValidationFailureMessage + Environment.NewLine);
            }


            var validationMessages = string.Empty;

            if (failedRequirements.Count() == 0)
            {
                this.Log().Info("{0} v{1} passed validation.".format_with(message.PackageId, message.PackageVersion));
                validationMessages = "**NOTE**: No [required changes](https://github.com/chocolatey/package-validator/wiki#requirements) that the validator checks have been flagged! It is appreciated if you fix other items, but only Requirements will hold up a package version from approval. A human review could still turn up issues a computer may not easily find.{0}{0}".format_with(Environment.NewLine);
            }

            validationMessages += resultsMessage.ToString();
            if (string.IsNullOrWhiteSpace(resultsMessage.ToString()))
            {
                this.Log().Info("{0} v{1} had no findings!".format_with(message.PackageId, message.PackageVersion));
                validationMessages = "Congratulations! This package passed automatic validation review without flagging on any issues the validator currently checks. A human review could still turn up issues a computer may not easily find.";
            }

            EventManager.publish(new FinalPackageValidationResultMessage(message.PackageId, message.PackageVersion, validationMessages, !failedRequirements.Any()));
        }
        private void process_results(PackageValidationResultMessage message)
        {
            var resultsMessage = new StringBuilder();

            var failedRequirements = message.ValidationResults.Where(r => r.Validated == false && r.ValidationLevel == ValidationLevelType.Requirement);

            if (failedRequirements.Count() != 0)
            {
                resultsMessage.Append("##### Requirements{0}".format_with(Environment.NewLine));
                resultsMessage.Append("When a package version has failed requirements, the package version requires fixing or response by the maintainer. If items are flagged correctly, they must be fixed before the package version can be approved. The exact same version should be uploaded during moderation review.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var failedRequirement in failedRequirements.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + failedRequirement.ValidationFailureMessage + Environment.NewLine);
            }

            var flaggedGuidelines = message.ValidationResults.Where(r => r.Validated == false && r.ValidationLevel == ValidationLevelType.Guideline);

            if (flaggedGuidelines.Count() != 0)
            {
                resultsMessage.Append("{0}##### Guidelines{1}".format_with(resultsMessage.Length == 0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Guidelines are strong suggestions that improve the quality of a package version. These are considered something to fix for next time to increase the quality of the package. Over time guidelines can become requirements. A package version can be approved without addressing guideline comments.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedGuideline in flaggedGuidelines.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedGuideline.ValidationFailureMessage + Environment.NewLine);
            }

            var flaggedSuggestions = message.ValidationResults.Where(r => r.Validated == false && (r.ValidationLevel == ValidationLevelType.Suggestion));

            if (flaggedSuggestions.Count() != 0)
            {
                resultsMessage.Append("{0}##### Suggestions{1}".format_with(resultsMessage.Length == 0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Suggestions are newly introduced items that should be considered. A package version can be approved without addressing suggestion comments.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedSuggestion in flaggedSuggestions.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedSuggestion.ValidationFailureMessage + Environment.NewLine);
            }

            var flaggedNotes = message.ValidationResults.Where(r => r.Validated == false && (r.ValidationLevel == ValidationLevelType.Note));

            if (flaggedNotes.Count() != 0)
            {
                resultsMessage.Append("{0}##### Notes{1}".format_with(resultsMessage.Length == 0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Notes typically flag things for both you and the reviewer.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedNote in flaggedNotes.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedNote.ValidationFailureMessage + Environment.NewLine);
            }

            var validationMessages = resultsMessage.ToString();

            if (!string.IsNullOrWhiteSpace(validationMessages))
            {
                var messageToSend = validationMessages;
                // send the message
            }

            //todo if you find any that failed validation, it's time to update the website
            //create a message for updating the website with the validation set
            //EventManager.publish(new PackageValidationResultMessage(message.PackageId, message.PackageVersion, validationResults, DateTime.UtcNow));
        }
        private void process_results(PackageValidationResultMessage message)
        {
            var resultsMessage = new StringBuilder();

            var failedRequirements = message.ValidationResults.Where(r => r.Validated == false && r.ValidationLevel == ValidationLevelType.Requirement);
            if (failedRequirements.Count() != 0)
            {
                this.Log().Info("{0} v{1} FAILED validation.".format_with(message.PackageId,message.PackageVersion));
                resultsMessage.Append("##### Requirements{0}".format_with(Environment.NewLine));
                resultsMessage.Append("Requirements represent the minimum quality of a package that is acceptable. When a package version has failed requirements, the package version requires fixing and/or response by the maintainer. Provided a Requirement has flagged correctly, it ***must*** be fixed before the package version can be approved. The exact same version should be uploaded during moderation review.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var failedRequirement in failedRequirements.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + failedRequirement.ValidationFailureMessage + Environment.NewLine);
            }

            var flaggedGuidelines = message.ValidationResults.Where(r => r.Validated == false && r.ValidationLevel == ValidationLevelType.Guideline);
            if (flaggedGuidelines.Count() != 0)
            {
                resultsMessage.Append("{0}##### Guidelines{1}".format_with(resultsMessage.Length ==0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Guidelines are strong suggestions that improve the quality of a package version. These are considered something to fix for next time to increase the quality of the package. Over time Guidelines can become Requirements. A package version can be approved without addressing Guideline comments but will reduce the quality of the package.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedGuideline in flaggedGuidelines.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedGuideline.ValidationFailureMessage + Environment.NewLine);
            }
            
            var flaggedSuggestions = message.ValidationResults.Where(r => r.Validated == false && (r.ValidationLevel == ValidationLevelType.Suggestion));
            if (flaggedSuggestions.Count() != 0)
            {
                resultsMessage.Append("{0}##### Suggestions{1}".format_with(resultsMessage.Length == 0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Suggestions are either newly introduced items that will later become Guidelines or items that are don't carry enough weight to become a Guideline. Either way they should be considered. A package version can be approved without addressing Suggestion comments.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedSuggestion in flaggedSuggestions.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedSuggestion.ValidationFailureMessage + Environment.NewLine);
            }
            
            var flaggedNotes = message.ValidationResults.Where(r => r.Validated == false && (r.ValidationLevel == ValidationLevelType.Note));
            if (flaggedNotes.Count() != 0)
            {
                resultsMessage.Append("{0}##### Notes{1}".format_with(resultsMessage.Length == 0 ? string.Empty : Environment.NewLine, Environment.NewLine));
                resultsMessage.Append("Notes typically flag things for both you and the reviewer to go over. Sometimes this is the use of things that may or may not be necessary given the constraints of what you are trying to do and/or are harder for automation to flag for other reasons. Items found in Notes might be Requirements depending on the context. A package version can be approved without addressing Note comments.{0}{0}".format_with(Environment.NewLine));
            }
            foreach (var flaggedNote in flaggedNotes.or_empty_list_if_null())
            {
                resultsMessage.Append("* " + flaggedNote.ValidationFailureMessage + Environment.NewLine);
            }


            var validationMessages = string.Empty;
            if (failedRequirements.Count() == 0)
            {
                this.Log().Info("{0} v{1} passed validation.".format_with(message.PackageId, message.PackageVersion));
                validationMessages = "**NOTE**: No [required changes](https://github.com/chocolatey/package-validator/wiki#requirements) that the validator checks have been flagged! It is appreciated if you fix other items, but only Requirements will hold up a package version from approval. A human review could still turn up issues a computer may not easily find.{0}{0}".format_with(Environment.NewLine);
            }

            validationMessages += resultsMessage.ToString();
            if (string.IsNullOrWhiteSpace(resultsMessage.ToString()))
            {
                this.Log().Info("{0} v{1} had no findings!".format_with(message.PackageId, message.PackageVersion));
                validationMessages = "Congratulations! This package passed automatic validation review without flagging on any issues the validator currently checks. A human review could still turn up issues a computer may not easily find.";
            }

            EventManager.publish(new FinalPackageValidationResultMessage(message.PackageId, message.PackageVersion, validationMessages, !failedRequirements.Any()));
        }