/// <summary>
        /// Parses key:value string pairs by specified match string from log entries.
        /// </summary>
        /// <param name="logEntry">The log entry dataset which contains all log entries.</param>
        /// <param name="dict">The dictionary which contains the matching key:value pairs.</param>
        /// <param name="matchString">The string to match. "matchString : value" is a valid log entry message.</param>
        /// <param name="filter">The filter expression to select log messages</param>
        private static void GetStatsFromLogEntry(TestLog logEntry, ref Dictionary <string, string> dict, string matchString, string filter)
        {
            if (dict == null)
            {
                dict = new Dictionary <string, string>();
            }
            DataRow[] rows = logEntry.LogEntry.Select(filter);
            if (rows.Length == 0)
            {
                Warning("[Warning] The log entry kind 'Comment' and 'Settings' should be enabled.");
            }
            foreach (DataRow row in rows)
            {
                string tmp = (row as TestLog.LogEntryRow).Message;
                if (tmp.StartsWith(matchString))
                {
                    tmp = tmp.Remove(0, matchString.Length);
                    int index = tmp.IndexOf(":");

                    if (index != -1)
                    {
                        string key   = tmp.Substring(0, index);
                        string value = tmp.Substring(index + 1);
                        if (!dict.ContainsKey(key))
                        {
                            dict.Add(key, value);
                        }
                        else
                        {
                            dict[key] = value;
                        }
                        if (key == "TestsExecuted")
                        {
                            DateTime stamp = ((TestLog.LogEntryRow)row).timeStamp;
                            dict.Add("TimeStamp", stamp.ToString());
                        }
                    }
                }
            }
        }
        private void Load(IList<string> logFilenames)
        {
            string currentFile = string.Empty;
            try
            {
                TestLog logEntry = null;
                TestLog tempLogEntry = new TestLog();
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.XmlResolver = null;
                foreach (string logfile in logFilenames)
                {
                    currentFile = logfile;
                    //allow log file contain zero entry.
                    if (logEntry == null)
                    {
                        logEntry = new TestLog();
                        logEntry.ReadXml(XmlReader.Create(logfile, settings));
                    }
                    else
                    {
                        tempLogEntry.ReadXml(XmlReader.Create(logfile, settings));
                        logEntry.Merge(tempLogEntry);
                        tempLogEntry.Clear();
                    }
                }
                tempLogEntry.Dispose();

                currentFile = string.Empty;

                // get all ptf configurations
                GetStatsFromLogEntry(logEntry, ref ptfConfigurations, CONFPROP, SETTINGSSTATEMENT);

                // get all test results
                GetStatsFromLogEntry(logEntry, ref testResult, TESTRESULT, COMMENTSTATEMENT);

                //group all test cases by test outcome
                GetTestCasesWithOutcome(logEntry);

                // remove all entries except Checkpoint kind log entries
                DataRow[] rows = logEntry.LogEntry.Select(CHECKPOINTSTATEMENT);
                foreach (DataRow row in rows)
                {
                    row.Delete();
                }
                logEntry.LogEntry.AcceptChanges();

                // fill data for checkpoints
                FillCheckpointEntries(logEntry.LogEntry);

                logEntry.Dispose();
            }
            catch (Exception e)
            {
                throw new InvalidOperationException(
                    String.Format("[ERROR] Unable to get test log data from specified xml log file(s) {0}. Details:\r\n{1}", currentFile, e.Message + e.StackTrace));
            }
        }
 /// <summary>
 /// Stores all checkpoint log entry messages to <c ref="checkpointEntries"></c>
 /// </summary>
 /// <param name="dt">The datatable contias all checkpoint log entries</param>
 private void FillCheckpointEntries(TestLog.LogEntryDataTable dt)
 {
     if (checkpointEntries == null)
     {
         checkpointEntries = new Dictionary<string, string>();
     }
     if (excludedRequirements == null)
     {
         excludedRequirements = new Dictionary<string, string>();
     }
     if (excludedRequirementsTimestamp == null)
     {
         excludedRequirementsTimestamp = new Dictionary<string, string>();
     }
     foreach (TestLog.LogEntryRow entry in dt)
     {
         //excluding captured requirements from failed test cases.
         if (!entry.IstestCaseNull() && !string.IsNullOrEmpty(entry.testCase))
         {
             //requirements covered in failed test case.
             if (testCases.ContainsKey(entry.testCase) &&
                 string.Compare(testCases[entry.testCase], TESTPASSED, true) != 0)
             {
                 if (!excludedRequirements.ContainsKey(entry.Message))
                 {
                     excludedRequirements.Add(entry.Message, entry.testCase);
                     excludedRequirementsTimestamp.Add(
                         entry.Message, entry.timeStamp.ToString());
                 }
                 continue;
             }
         }
         if (!checkpointEntries.ContainsKey(entry.Message))
         {
             checkpointEntries.Add(entry.Message, entry.timeStamp.ToString());
             // parse protocol name from message string
             Match ms = MSPATTERN.Match(entry.Message);
             Match rfc = RFCPATTERN.Match(entry.Message);
             if (ms.Success || rfc.Success)
             {
                 string protocol = entry.Message.Remove(entry.Message.IndexOf('_'));
                 if (!protocols.Contains(protocol))
                 {
                     protocols.Add(protocol);
                 }
             }
             else
             {
                 //Remove the schema restriction to the reqirement id
                 //The protocols will not be parse from message string.
                 continue;
             }
         }
     }
 }
 private void GetTestCasesWithOutcome(TestLog logEntry)
 {
     if (testCases == null)
     {
         testCases = new Dictionary<string, string>();
     }
     foreach (string[] valuePair in testStatusName)
     {
         DataRow[] rows = logEntry.LogEntry.Select(
                 string.Format(TESTOUTCOMESTATEMENT, valuePair[0]));
         if (rows.Length == 0 && testResult.ContainsKey(valuePair[1]))
         {
             Warning("[Warning] The log entry kind '{0}' should be enabled.", valuePair[0]);
         }
         else
         {
             foreach (DataRow row in rows)
             {
                 //get the test case name from the testfailed, testinconclusive, testpassed,
                 //testerror, testtimeout, testaborted or testunknown log entries.
                 string testCaseName = (row as TestLog.LogEntryRow).Message.Trim();
                 testCases[testCaseName] = valuePair[0];
             }
         }
     }
 }
        /// <summary>
        /// Parses key:value string pairs by specified match string from log entries.
        /// </summary>
        /// <param name="logEntry">The log entry dataset which contains all log entries.</param>
        /// <param name="dict">The dictionary which contains the matching key:value pairs.</param>
        /// <param name="matchString">The string to match. "matchString : value" is a valid log entry message.</param>
        /// <param name="filter">The filter expression to select log messages</param>
        private static void GetStatsFromLogEntry(TestLog logEntry, ref Dictionary<string, string> dict, string matchString, string filter)
        {
            if (dict == null)
            {
                dict = new Dictionary<string, string>();
            }
            DataRow[] rows = logEntry.LogEntry.Select(filter);
            if (rows.Length == 0)
            {
                Warning("[Warning] The log entry kind 'Comment' and 'Settings' should be enabled.");
            }
            foreach (DataRow row in rows)
            {
                string tmp = (row as TestLog.LogEntryRow).Message;
                if (tmp.StartsWith(matchString))
                {
                    tmp = tmp.Remove(0, matchString.Length);
                    int index = tmp.IndexOf(":");

                    if (index != -1)
                    {
                        string key = tmp.Substring(0, index);
                        string value = tmp.Substring(index + 1);
                        if (!dict.ContainsKey(key))
                        {
                            dict.Add(key, value);
                        }
                        else
                        {
                            dict[key] = value;
                        }
                        if (key == "TestsExecuted")
                        {
                            DateTime stamp = ((TestLog.LogEntryRow)row).timeStamp;
                            dict.Add("TimeStamp", stamp.ToString());
                        }
                    }

                }
            }
        }