public void ConvertMemoryLeakToVSTestResult()
        {
            LogEntryMemoryLeak leak = new LogEntryMemoryLeak();

            leak.LeakLineNumber = 32;
            leak.LeakMemoryAllocationNumber = 836;
            leak.LeakLeakedDataContents = " Data: <`-  Leak...     > 60 2D BD 00 4C 65 61 6B 2E 2E 2E 00 CD CD CD CD ";

            leak.LeakSourceFilePath = @"C:\boostunittestsample.cpp";
            leak.LeakSourceFileName = "boostunittestsample.cpp";

            BoostTestResult testCaseResult = new BoostTestResultBuilder().
                For(this.TestCase).
                Passed().
                Duration(1000).
                Log(leak).
                Build();

            VSTestResult result = testCaseResult.AsVSTestResult(this.TestCase);

            AssertVSTestModelProperties(result);

            Assert.That(result.Outcome, Is.EqualTo(TestOutcome.Passed));
            Assert.That(result.Duration, Is.EqualTo(Microseconds(1000)));

            Assert.That(result.Messages.Count, Is.EqualTo(1));

            TestResultMessage message = result.Messages.First();
            Assert.That(message.Category, Is.EqualTo(TestResultMessage.StandardErrorCategory));
        }
        /// <summary>
        /// Formats a LogEntryMemoryLeak to append to test result string
        /// </summary>
        /// <param name="memoryLeak">The memory leak to format</param>
        /// <param name="sb">The StringBuilder which will host the output</param>
        /// <returns>sb</returns>
        private static StringBuilder FormatMemoryLeak(LogEntryMemoryLeak memoryLeak, StringBuilder sb)
        {
            if ((memoryLeak.LeakSourceFilePath != null) && (memoryLeak.LeakSourceFileName != null))
            {
                sb.Append("source file path leak detected at :").
                    Append(memoryLeak.LeakSourceFilePath).
                    Append(memoryLeak.LeakSourceFileName);
            }

            if (memoryLeak.LeakLineNumber != null)
            {
                sb.Append(", ").
                    Append("Line number: ").
                    Append(memoryLeak.LeakLineNumber);
            }

            sb.Append(", ").
                Append("Memory allocation number: ").
                Append(memoryLeak.LeakMemoryAllocationNumber);

            sb.Append(", ").
                Append("Leak size: ").
                Append(memoryLeak.LeakSizeInBytes).
                Append(" byte");

            if (memoryLeak.LeakSizeInBytes > 0)
            {
                sb.Append('s');
            }

            sb.Append(Environment.NewLine).
                Append(memoryLeak.LeakLeakedDataContents);

            return sb;
        }
        private void RegisterMemoryLeak(string leakInformation, TestResultCollection collection)
        {
            foreach (TestResult result in collection)
            {
                if (this.FailTestOnMemoryLeak)
                {
                    result.Result = TestResultType.Failed;
                }

                Regex regexLeakInformation = new Regex(@"(?:([\\:\w\rA-z.]*?)([\w\d.]*)\((\d{1,})\)\s:\s)?\{(\d{1,})\}[\w\s\d]*,\s(\d{1,})[\s\w.]*\n(.*?)(?=$|(?:[\\\w.:]*\(\d{1,}\)\s:\s)?\{\d{1,}\d)", RegexOptions.IgnoreCase | RegexOptions.Singleline);   //the old one wasRegex regexLeakInformation = new Regex(@"^(.*\\)(.*?)\((\d{1,})\).*?{(\d{1,})}.*?(\d{1,})\sbyte", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                /*

                 The same regex works for when the complete file path along with the line number are reported in the console output such as in the below sample output

                 d:\hwa\dev\svn\boostunittestadapterdev\branches\tempbugfixing\sample\boostunittest\boostunittest2\adapterbugs.cpp(58) : {869} normal block at 0x00A88A58, 4 bytes long.
                    Data: <    > CD CD CD CD
                 d:\hwa\dev\svn\boostunittestadapterdev\branches\tempbugfixing\sample\boostunittest\boostunittest2\adapterbugs.cpp(55) : {868} normal block at 0x00A88788, 4 bytes long.
                    Data: <    > F5 01 00 00

                 and also when this information is not reported such as in the below sample output

                {869} normal block at 0x005E8998, 4 bytes long.
                 Data: <    > CD CD CD CD
                {868} normal block at 0x005E8848, 4 bytes long.
                 Data: <    > F5 01 00 00

                 */

                #region regexLeakInformation

                // (?:([\\:\w\rA-z.]*?)([\w\d.]*)\((\d{1,})\)\s:\s)?\{(\d{1,})\}[\w\s\d]*,\s(\d{1,})[\s\w.]*\n(.*?)(?=$|(?:[\\\w.:]*\(\d{1,}\)\s:\s)?\{\d{1,}\d)
                //
                // Options: Case insensitive; Exact spacing; Dot matches line breaks; ^$ don't match at line breaks; Numbered capture
                //
                // Match the regular expression below «(?:([\\:\w\rA-z.]*?)([\w\d.]*)\((\d{1,})\)\s:\s)?»
                //    Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
                //    Match the regex below and capture its match into backreference number 1 «([\\:\w\rA-z.]*?)»
                //       Match a single character present in the list below «[\\:\w\rA-z.]*?»
                //          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
                //          The backslash character «\\»
                //          The literal character “:” «:»
                //          A “word character” (Unicode; any letter or ideograph, digit, connector punctuation) «\w»
                //          The carriage return character «\r»
                //          A character in the range between “A” and “z” (case insensitive) «A-z»
                //          The literal character “.” «.»
                //    Match the regex below and capture its match into backreference number 2 «([\w\d.]*)»
                //       Match a single character present in the list below «[\w\d.]*»
                //          Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
                //          A “word character” (Unicode; any letter or ideograph, digit, connector punctuation) «\w»
                //          A “digit” (0–9 in any Unicode script) «\d»
                //          The literal character “.” «.»
                //    Match the character “(” literally «\(»
                //    Match the regex below and capture its match into backreference number 3 «(\d{1,})»
                //       Match a single character that is a “digit” (0–9 in any Unicode script) «\d{1,}»
                //          Between one and unlimited times, as many times as possible, giving back as needed (greedy) «{1,}»
                //    Match the character “)” literally «\)»
                //    Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                //    Match the character “:” literally «:»
                //    Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                // Match the character “{” literally «\{»
                // Match the regex below and capture its match into backreference number 4 «(\d{1,})»
                //    Match a single character that is a “digit” (0–9 in any Unicode script) «\d{1,}»
                //       Between one and unlimited times, as many times as possible, giving back as needed (greedy) «{1,}»
                // Match the character “}” literally «\}»
                // Match a single character present in the list below «[\w\s\d]*»
                //    Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
                //    A “word character” (Unicode; any letter or ideograph, digit, connector punctuation) «\w»
                //    A “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                //    A “digit” (0–9 in any Unicode script) «\d»
                // Match the character “,” literally «,»
                // Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                // Match the regex below and capture its match into backreference number 5 «(\d{1,})»
                //    Match a single character that is a “digit” (0–9 in any Unicode script) «\d{1,}»
                //       Between one and unlimited times, as many times as possible, giving back as needed (greedy) «{1,}»
                // Match a single character present in the list below «[\s\w.]*»
                //    Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
                //    A “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                //    A “word character” (Unicode; any letter or ideograph, digit, connector punctuation) «\w»
                //    The literal character “.” «.»
                // Match the line feed character «\n»
                // Match the regex below and capture its match into backreference number 6 «(.*?)»
                //    Match any single character «.*?»
                //       Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
                // Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=$|(?:[\\\w.:]*\(\d{1,}\)\s:\s)?\{\d{1,}\d)»
                //    Match this alternative (attempting the next alternative only if this one fails) «$»
                //       Assert position at the end of the string, or before the line break at the end of the string, if any (line feed) «$»
                //    Or match this alternative (the entire group fails if this one fails to match) «(?:[\\\w.:]*\(\d{1,}\)\s:\s)?\{\d{1,}\d»
                //       Match the regular expression below «(?:[\\\w.:]*\(\d{1,}\)\s:\s)?»
                //          Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
                //          Match a single character present in the list below «[\\\w.:]*»
                //             Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
                //             The backslash character «\\»
                //             A “word character” (Unicode; any letter or ideograph, digit, connector punctuation) «\w»
                //             A single character from the list “.:” «.:»
                //          Match the character “(” literally «\(»
                //          Match a single character that is a “digit” (0–9 in any Unicode script) «\d{1,}»
                //             Between one and unlimited times, as many times as possible, giving back as needed (greedy) «{1,}»
                //          Match the character “)” literally «\)»
                //          Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                //          Match the character “:” literally «:»
                //          Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
                //       Match the character “{” literally «\{»
                //       Match a single character that is a “digit” (0–9 in any Unicode script) «\d{1,}»
                //          Between one and unlimited times, as many times as possible, giving back as needed (greedy) «{1,}»
                //       Match a single character that is a “digit” (0–9 in any Unicode script) «\d»

                #endregion regexLeakInformation

                Match matchLeakInformation = regexLeakInformation.Match(leakInformation);
                while (matchLeakInformation.Success)
                {
                    LogEntryMemoryLeak leak = new LogEntryMemoryLeak();

                    result.LogEntries.Add(leak);

                    //Capturing group 1,2 and 3 will have the 'Success' property false in case the C++ new operator has not been replaced via the macro

                    // Temporary variable used to try and parse unsigned integer values;
                    uint value = 0;

                    if (matchLeakInformation.Groups[1].Success && matchLeakInformation.Groups[2].Success && matchLeakInformation.Groups[3].Success)
                    {
                        leak.LeakSourceFilePath = matchLeakInformation.Groups[1].Value;

                        leak.LeakSourceFileName = matchLeakInformation.Groups[2].Value;

                        if (uint.TryParse(matchLeakInformation.Groups[3].Value, out value))
                        {
                            leak.LeakLineNumber = value;
                        }

                        leak.LeakSourceFileAndLineNumberReportingActive = true;
                    }
                    else
                    {
                        leak.LeakSourceFileAndLineNumberReportingActive = false;
                    }

                    if (uint.TryParse(matchLeakInformation.Groups[4].Value, out value))
                    {
                        leak.LeakMemoryAllocationNumber = value;
                    }

                    if (uint.TryParse(matchLeakInformation.Groups[5].Value, out value))
                    {
                        leak.LeakSizeInBytes = value;
                    }

                    leak.LeakLeakedDataContents = matchLeakInformation.Groups[6].Value;

                    matchLeakInformation = matchLeakInformation.NextMatch();
                }
            }
        }
 /// <summary>
 /// Compares 2 LogEntryMemoryLeak for equivalence. Issues an assertion failure if leak information is not equivalent.
 /// </summary>
 /// <param name="lhs">The left-hand side LogEntryMemoryLeak instance</param>
 /// <param name="rhs">The right-hand side LogEntryMemoryLeak instance</param>
 private void AssertMemoryLeakDetails(LogEntryMemoryLeak lhs, LogEntryMemoryLeak rhs)
 {
     Assert.AreEqual(lhs.LeakLineNumber, rhs.LeakLineNumber);
     Assert.AreEqual(lhs.LeakLeakedDataContents, rhs.LeakLeakedDataContents);
     Assert.AreEqual(lhs.LeakMemoryAllocationNumber, rhs.LeakMemoryAllocationNumber);
     Assert.AreEqual(lhs.LeakSizeInBytes, rhs.LeakSizeInBytes);
     Assert.AreEqual(lhs.LeakSourceFileAndLineNumberReportingActive,
         rhs.LeakSourceFileAndLineNumberReportingActive);
     Assert.AreEqual(lhs.LeakSourceFileName, rhs.LeakSourceFileName);
     Assert.AreEqual(lhs.LeakSourceFilePath, rhs.LeakSourceFilePath);
 }