/// <summary>
        /// Determines whether the violation matches the given expected violation.
        /// </summary>
        /// <param name="expectedViolation">The expected violation.</param>
        /// <param name="actualViolation">The actual violation.</param>
        /// <returns>Returns true if there is a match.</returns>
        private static bool MatchesExpectedViolation(ViolationInfo expectedViolation, ViolationInfo actualViolation)
        {
            Debug.Assert(expectedViolation != null, "The parameter must not be null");
            Debug.Assert(actualViolation != null, "The parameter must not be null");

            // Compare the line numbers.
            if (expectedViolation.LineNumber >= 0)
            {
                if (actualViolation.LineNumber != expectedViolation.LineNumber)
                {
                    return false;
                }
            }

            if (expectedViolation.StartLineNumber >= 0)
            {
                if (actualViolation.StartLineNumber != expectedViolation.StartLineNumber)
                {
                    return false;
                }
            }

            if (expectedViolation.StartColumnNumber >= 0)
            {
                if (actualViolation.StartColumnNumber != expectedViolation.StartColumnNumber)
                {
                    return false;
                }
            }

            if (expectedViolation.EndLineNumber >= 0)
            {
                if (actualViolation.EndLineNumber != expectedViolation.EndLineNumber)
                {
                    return false;
                }
            }

            if (expectedViolation.EndColumnNumber >= 0)
            {
                if (actualViolation.EndColumnNumber != expectedViolation.EndColumnNumber)
                {
                    return false;
                }
            }

            // Compare the rule names.
            if (expectedViolation.RuleName != null)
            {
                if (actualViolation.RuleName == null || !string.Equals(expectedViolation.RuleName, actualViolation.RuleName, StringComparison.Ordinal))
                {
                    return false;
                }
            }

            // Compare the rule namespaces.
            if (expectedViolation.RuleNamespace != null)
            {
                if (actualViolation.RuleNamespace == null || !string.Equals(expectedViolation.RuleNamespace, actualViolation.RuleNamespace, StringComparison.Ordinal))
                {
                    return false;
                }
            }

            // Compare the sections.
            if (expectedViolation.Section != null)
            {
                if (actualViolation.Section == null || !string.Equals(expectedViolation.Section, actualViolation.Section, StringComparison.Ordinal))
                {
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        /// Writes information about the given violation to the log node.
        /// </summary>
        /// <param name="violationInfo">The violation information.</param>
        /// <param name="root">The log node to write the information into.</param>
        private static void WriteViolationDetailToLog(ViolationInfo violationInfo, XmlNode root)
        {
            Debug.Assert(violationInfo != null, "The parameter must not be null");
            Debug.Assert(root != null, "The parameter must not be null");

            XmlElement violation = root.OwnerDocument.CreateElement("Violation");

            if (!string.IsNullOrEmpty(violationInfo.Section))
            {
                XmlAttribute section = root.OwnerDocument.CreateAttribute("Section");
                section.Value = violationInfo.Section;
                violation.Attributes.Append(section);
            }

            if (violationInfo.LineNumber >= 0)
            {
                XmlAttribute lineNumber = root.OwnerDocument.CreateAttribute("LineNumber");
                lineNumber.Value = violationInfo.LineNumber.ToString(CultureInfo.CurrentCulture);
                violation.Attributes.Append(lineNumber);
            }

            if (violationInfo.StartLineNumber >= 0)
            {
                XmlAttribute startLineNumber = root.OwnerDocument.CreateAttribute("StartLine");
                startLineNumber.Value = violationInfo.StartLineNumber.ToString(CultureInfo.CurrentCulture);
                violation.Attributes.Append(startLineNumber);
            }

            if (violationInfo.StartColumnNumber >= 0)
            {
                XmlAttribute startColumnNumber = root.OwnerDocument.CreateAttribute("StartColumn");
                startColumnNumber.Value = violationInfo.StartColumnNumber.ToString(CultureInfo.CurrentCulture);
                violation.Attributes.Append(startColumnNumber);
            }

            if (violationInfo.EndLineNumber >= 0)
            {
                XmlAttribute endLineNumber = root.OwnerDocument.CreateAttribute("EndLine");
                endLineNumber.Value = violationInfo.EndLineNumber.ToString(CultureInfo.CurrentCulture);
                violation.Attributes.Append(endLineNumber);
            }

            if (violationInfo.EndColumnNumber >= 0)
            {
                XmlAttribute endColumnNumber = root.OwnerDocument.CreateAttribute("EndColumn");
                endColumnNumber.Value = violationInfo.EndColumnNumber.ToString(CultureInfo.CurrentCulture);
                violation.Attributes.Append(endColumnNumber);
            }

            if (!string.IsNullOrEmpty(violationInfo.RuleNamespace))
            {
                XmlAttribute ruleNamespace = root.OwnerDocument.CreateAttribute("RuleNamespace");
                ruleNamespace.Value = violationInfo.RuleNamespace;
                violation.Attributes.Append(ruleNamespace);
            }

            if (!string.IsNullOrEmpty(violationInfo.RuleName))
            {
                XmlAttribute ruleName = root.OwnerDocument.CreateAttribute("Rule");
                ruleName.Value = violationInfo.RuleName;
                violation.Attributes.Append(ruleName);
            }

            root.AppendChild(violation);
        }
        /// <summary>
        /// Extracts information about a violation from the given node.
        /// </summary>
        /// <param name="violationNode">The violation node.</param>
        /// <returns>Returns the violation information.</returns>
        private static ViolationInfo ExtractViolationInfo(XmlNode violationNode)
        {
            // Load the section.
            string section = null;
            XmlAttribute attribute = violationNode.Attributes["Section"];
            if (attribute != null)
            {
                section = attribute.Value;
            }

            // Load the rule name.
            string ruleName = null;
            attribute = violationNode.Attributes["Rule"];
            if (attribute != null)
            {
                ruleName = attribute.Value;
            }

            // Load the rule namespace.
            string ruleNamespace = null;
            attribute = violationNode.Attributes["RuleNamespace"];
            if (attribute != null)
            {
                ruleNamespace = attribute.Value;
            }

            // Load the line number.
            int lineNumber = -1;
            attribute = violationNode.Attributes["LineNumber"];
            if (attribute != null)
            {
                int temp;
                if (int.TryParse(attribute.Value, out temp))
                {
                    lineNumber = temp;
                }
            }

            // Load the start line number.
            int startLineNumber = -1;
            attribute = violationNode.Attributes["StartLine"];
            if (attribute != null)
            {
                int temp;
                if (int.TryParse(attribute.Value, out temp))
                {
                    startLineNumber = temp;
                }
            }

            // Load the end line number.
            int endLineNumber = -1;
            attribute = violationNode.Attributes["EndLine"];
            if (attribute != null)
            {
                int temp;
                if (int.TryParse(attribute.Value, out temp))
                {
                    endLineNumber = temp;
                }
            }

            // Load the start column number.
            int startColumnNumber = -1;
            attribute = violationNode.Attributes["StartColumn"];
            if (attribute != null)
            {
                int temp;
                if (int.TryParse(attribute.Value, out temp))
                {
                    startColumnNumber = temp;
                }
            }

            // Load the end column number.
            int endColumnNumber = -1;
            attribute = violationNode.Attributes["EndColumn"];
            if (attribute != null)
            {
                int temp;
                if (int.TryParse(attribute.Value, out temp))
                {
                    endColumnNumber = temp;
                }
            }
            
            ViolationInfo violation = new ViolationInfo(section, lineNumber, startLineNumber, startColumnNumber, endLineNumber, endColumnNumber, ruleNamespace, ruleName);
            return violation;
        }