/// <summary>
        /// Reads dataset from specified file.
        /// </summary>
        private ProjectStatisticDataSet ReadDataSet(string fileName)
        {
            var    dataSet     = new ProjectStatisticDataSet();
            string refDataPath = Path.Combine(
                this.TestContext.TestDeploymentDir,
                Path.Combine("ReferenceData", fileName));

            dataSet.ReadXml(refDataPath);
            return(dataSet);
        }
        /// <summary>
        /// Reads specific tables to dataset from specified file.
        /// </summary>
        private ProjectStatisticDataSet ReadDataSet(string fileName,
                                                    string[] tables)
        {
            var    dataSet     = new ProjectStatisticDataSet();
            string refDataPath = Path.Combine(
                this.TestContext.TestDeploymentDir,
                Path.Combine("ReferenceData", fileName));

            // Read all
            dataSet.ReadXml(refDataPath);

            // But clear tables which aren't specified
            foreach (DataTable table in dataSet.Tables)
            {
                if (Array.IndexOf(tables, table.TableName) == -1)
                {
                    table.Clear();
                }
            }
            return(dataSet);
        }
        /// <summary>
        /// Returns data set containing all data for the report.
        /// </summary>
        /// <remarks>
        /// Returned data set contains following tables:
        /// +) Bugfixing periods (Periods)
        /// +) Bugfixing statistics (Statistics)
        /// +) Report information (Info)
        /// 
        /// --------------------------------------------------
        /// Bugfixing periods contains information on Added,
        /// Postponed, Reactivated, Removed bugs for each 
        /// time period and additionally two balances - 
        /// with Postponed/Reactivated and with only Added/Removed
        /// accounted.
        /// 
        /// There are following columns in the table:
        /// +) Interval - interval index
        /// +) FromDate - period start date
        /// +) ToDate - period end date
        /// +) Added - number of Add transition during period
        /// +) Postponed - -//- 
        /// +) Reactivated - -//- 
        /// +) Removed - -//- 
        /// +) Balance1 - balance with Postponed/Reactivated
        /// +) Balance2 - balance with only Added/Removed
        /// 
        /// Each row contains information for one time period.
        /// 
        /// --------------------------------------------------
        /// Bugfixing statistics table contains information on
        /// Sum, Average per period and Average per day statistics.
        /// 
        /// There are following columns in the table:
        /// +) Aggregate - name of aggregate (Sum, Avg, AvgDay)
        /// +) Added - value of aggregate for Added through all periods
        /// +) Postponed - -//- for Postponed
        /// +) Reactivated - -//- 
        /// +) Removed - -//- 
        /// +) Balance1 - -//- 
        /// +) Balance2 - -//- 
        /// 
        /// --------------------------------------------------
        /// Report information table contains parameters 
        /// for which report was created:
        /// +) GroupPeriod - Day, Week, etc
        /// +) FromDate - start date of report
        /// +) ToDate - end date of report
        /// +) MinDate - minimum date of handled revision
        /// +) MaxDate - maximum date of handled revision
        /// </remarks>
        public DataSet CreateReport()
        {
            // Create data set
              ProjectStatisticDataSet dataSet = new ProjectStatisticDataSet();

              // Use filter to iterate through revisions
              RevisionTransitionFilter filter = new RevisionTransitionFilter();

              // Select transition which fall into desired time interval
              // Group them by interval index
              // Order groups by interval index
              var query = from t in filter.GetTransitions(m_revisions)
                  where t.CurrentRevision.Date >= m_fromDate &&
                        t.CurrentRevision.Date <= m_toDate
                  group t by GetGroup(m_groupBy, t.CurrentRevision) into g
                  orderby g.Key.Interval
                  select g;

              DateTime minDate = DateTime.MaxValue, maxDate = DateTime.MinValue;
              int prevInterval = -1;
              // Count transitions
              foreach(var group in query)
              {
            // Initialize values
            int added = 0;
            int postponed = 0;
            int reactivated = 0;
            int removed = 0;

            // Update values for all revisions in group
            foreach(RevisionStatusTransition transition in group)
            {
              // Update correspondent values
              added += transition.Name == "Added" ? 1 : 0;
              postponed += transition.Name == "Postponed" ? 1 : 0;
              reactivated += transition.Name == "Reactivated" ? 1 : 0;
              removed += transition.Name == "Removed" ? 1 : 0;

              // Remember min/max dates
              if( transition.CurrentRevision.Date < minDate )
              {
            minDate = transition.CurrentRevision.Date;
              }
              if( transition.CurrentRevision.Date > maxDate )
              {
            maxDate = transition.CurrentRevision.Date;
              }
            }

            // Fill gaps between nonempty periods with zero rows
            if (prevInterval != -1 && group.Key.Interval > (prevInterval + 1))
            {
              for (int interval = prevInterval + 1; interval < group.Key.Interval; interval++)
              {
            DateTime fromDate, toDate;
            GetIntervalDates(m_groupBy, interval, out fromDate, out toDate);
            dataSet.Periods.AddPeriodsRow(interval, fromDate, toDate,
              0, 0, 0, 0);
              }
            }
            // Add row for current group
            dataSet.Periods.AddPeriodsRow(group.Key.Interval,
              group.Key.IntervalStart, group.Key.IntervalEnd,
              added, postponed, reactivated, removed);

            // Remember current interval
            prevInterval = group.Key.Interval;
              }

              // Fill info table
              dataSet.Info.AddInfoRow(m_fromDate, m_toDate, m_groupBy.ToString(),
                              minDate, maxDate);

              // Fill statistics table

              return dataSet;
        }
        /// <summary>
        /// Returns data set containing all data for the report.
        /// </summary>
        /// <remarks>
        /// Returned data set contains following tables:
        /// +) Bugfixing periods (Periods)
        /// +) Bugfixing statistics (Statistics)
        /// +) Report information (Info)
        ///
        /// --------------------------------------------------
        /// Bugfixing periods contains information on Added,
        /// Postponed, Reactivated, Removed bugs for each
        /// time period and additionally two balances -
        /// with Postponed/Reactivated and with only Added/Removed
        /// accounted.
        ///
        /// There are following columns in the table:
        /// +) Interval - interval index
        /// +) FromDate - period start date
        /// +) ToDate - period end date
        /// +) Added - number of Add transition during period
        /// +) Postponed - -//-
        /// +) Reactivated - -//-
        /// +) Removed - -//-
        /// +) Balance1 - balance with Postponed/Reactivated
        /// +) Balance2 - balance with only Added/Removed
        ///
        /// Each row contains information for one time period.
        ///
        /// --------------------------------------------------
        /// Bugfixing statistics table contains information on
        /// Sum, Average per period and Average per day statistics.
        ///
        /// There are following columns in the table:
        /// +) Aggregate - name of aggregate (Sum, Avg, AvgDay)
        /// +) Added - value of aggregate for Added through all periods
        /// +) Postponed - -//- for Postponed
        /// +) Reactivated - -//-
        /// +) Removed - -//-
        /// +) Balance1 - -//-
        /// +) Balance2 - -//-
        ///
        /// --------------------------------------------------
        /// Report information table contains parameters
        /// for which report was created:
        /// +) GroupPeriod - Day, Week, etc
        /// +) FromDate - start date of report
        /// +) ToDate - end date of report
        /// +) MinDate - minimum date of handled revision
        /// +) MaxDate - maximum date of handled revision
        /// </remarks>
        public DataSet CreateReport()
        {
            // Create data set
            ProjectStatisticDataSet dataSet = new ProjectStatisticDataSet();

            // Use filter to iterate through revisions
            RevisionTransitionFilter filter = new RevisionTransitionFilter();

            // Select transition which fall into desired time interval
            // Group them by interval index
            // Order groups by interval index
            var query = from t in filter.GetTransitions(m_revisions)
                        where t.CurrentRevision.Date >= m_fromDate &&
                        t.CurrentRevision.Date <= m_toDate
                        group t by GetGroup(m_groupBy, t.CurrentRevision) into g
                        orderby g.Key.Interval
                        select g;

            DateTime minDate = DateTime.MaxValue, maxDate = DateTime.MinValue;
            int      prevInterval = -1;

            // Count transitions
            foreach (var group in query)
            {
                // Initialize values
                int added       = 0;
                int postponed   = 0;
                int reactivated = 0;
                int removed     = 0;

                // Update values for all revisions in group
                foreach (RevisionStatusTransition transition in group)
                {
                    // Update correspondent values
                    added       += transition.Name == "Added" ? 1 : 0;
                    postponed   += transition.Name == "Postponed" ? 1 : 0;
                    reactivated += transition.Name == "Reactivated" ? 1 : 0;
                    removed     += transition.Name == "Removed" ? 1 : 0;

                    // Remember min/max dates
                    if (transition.CurrentRevision.Date < minDate)
                    {
                        minDate = transition.CurrentRevision.Date;
                    }
                    if (transition.CurrentRevision.Date > maxDate)
                    {
                        maxDate = transition.CurrentRevision.Date;
                    }
                }

                // Fill gaps between nonempty periods with zero rows
                if (prevInterval != -1 && group.Key.Interval > (prevInterval + 1))
                {
                    for (int interval = prevInterval + 1; interval < group.Key.Interval; interval++)
                    {
                        DateTime fromDate, toDate;
                        GetIntervalDates(m_groupBy, interval, out fromDate, out toDate);
                        dataSet.Periods.AddPeriodsRow(interval, fromDate, toDate,
                                                      0, 0, 0, 0);
                    }
                }
                // Add row for current group
                dataSet.Periods.AddPeriodsRow(group.Key.Interval,
                                              group.Key.IntervalStart, group.Key.IntervalEnd,
                                              added, postponed, reactivated, removed);

                // Remember current interval
                prevInterval = group.Key.Interval;
            }

            // Fill info table
            dataSet.Info.AddInfoRow(m_fromDate, m_toDate, m_groupBy.ToString(),
                                    minDate, maxDate);

            // Fill statistics table

            return(dataSet);
        }
        /// <summary>
        /// Reads specific tables to dataset from specified file.
        /// </summary>
        private ProjectStatisticDataSet ReadDataSet(string fileName, 
            string[] tables)
        {
            var dataSet = new ProjectStatisticDataSet();
              string refDataPath = Path.Combine(
            this.TestContext.TestDeploymentDir,
            Path.Combine("ReferenceData", fileName));

              // Read all
              dataSet.ReadXml(refDataPath);

              // But clear tables which aren't specified
              foreach(DataTable table in dataSet.Tables)
              {
            if( Array.IndexOf(tables, table.TableName) == -1 )
            {
              table.Clear();
            }
              }
              return dataSet;
        }
 /// <summary>
 /// Reads dataset from specified file.
 /// </summary>
 private ProjectStatisticDataSet ReadDataSet(string fileName)
 {
     var dataSet = new ProjectStatisticDataSet();
       string refDataPath = Path.Combine(
     this.TestContext.TestDeploymentDir,
     Path.Combine("ReferenceData", fileName));
       dataSet.ReadXml(refDataPath);
       return dataSet;
 }