/// <summary>
        /// Get a table containing all groups (including parents) that contain items that 
        /// have transactions matching the specified parameters.
        /// </summary>
        /// <param name="accessList"></param>
        /// <returns></returns>
        public static EveDataSet.invMarketGroupsDataTable GetGroupsForItems(List<int> itemIDs)
        {
            EveDataSet.invMarketGroupsDataTable retVal = new EveDataSet.invMarketGroupsDataTable();
            // Build a string contianing all the ids of items we want to get groups for.
            StringBuilder itemList = new StringBuilder();
            foreach (int id in itemIDs)
            {
                if (itemList.Length != 0) { itemList.Append(","); }
                itemList.Append(id);
            }
            tableAdapter.FillByItems(retVal, itemList.ToString());
            // The SQL procedure only returns the first level group that the item is in, we want
            // all the parent groups as well so use this recursive method to get them...
            EveDataSet.invMarketGroupsDataTable parentGroups = new EveDataSet.invMarketGroupsDataTable();
            foreach (EveDataSet.invMarketGroupsRow group in retVal)
            {
                if (!group.IsparentGroupIDNull())
                {
                    AddGroupParents(parentGroups, group.parentGroupID);
                }
            }
            // ..then we can add them all to the result datatable.
            foreach (EveDataSet.invMarketGroupsRow group in parentGroups)
            {
                EveDataSet.invMarketGroupsRow oldGroup = retVal.FindBymarketGroupID(group.marketGroupID);
                if (oldGroup == null)
                {
                    retVal.ImportRow(group);
                }
            }

            return retVal;
        }
        /// <summary>
        /// recursively add the parent groups of the specified group id to the given table.
        /// </summary>
        /// <param name="table"></param>
        /// <param name="groupID"></param>
        private static void AddGroupParents(EveDataSet.invMarketGroupsDataTable table, int groupID)
        {
            EveDataSet.invMarketGroupsRow group = table.FindBymarketGroupID(groupID);
            if (group == null)
            {
                EveDataSet.invMarketGroupsDataTable resultTable = new EveDataSet.invMarketGroupsDataTable();
                tableAdapter.FillByID(resultTable, groupID);
                table.ImportRow(resultTable[0]);
                group = table.FindBymarketGroupID(groupID);
            }

            if (!group.IsparentGroupIDNull())
            {
                AddGroupParents(table, group.parentGroupID);
            }
        }
        protected override void InitSections()
        {
            _sections = new ReportSections();

            UpdateStatus(0, 1, "Building Report Sections...", "", false);

            if (_byItemGroup)
            {
                // Note that an additonal root section 'Non-market items' may be added during
                // GetDataFromDatabase if it is required.
                List<int> itemIDs = Items.GetItemIDsWithTransactions(_financeAccessParams);
                List<int> tmpItemIDs = new List<int>();
                if (_tradedItemsOnly)
                {
                    List<int> tradedItemIDs = UserAccount.CurrentGroup.TradedItems.GetAllItemIDs();
                    foreach (int itemID in itemIDs)
                    {
                        if (tradedItemIDs.Contains(itemID)) { tmpItemIDs.Add(itemID); }
                    }
                    itemIDs = tmpItemIDs;
                }
                _marketGroups = MarketGroups.GetGroupsForItems(itemIDs);
                DataRow[] rootGroups = _marketGroups.Select("parentGroupID IS null");
                int counter = 0;
                ReportSection rootSection = new ReportSection(_columns.Length, "All Items", "All Items", this);
                _sections.Add(rootSection);
                foreach (DataRow group in rootGroups)
                {
                    counter++;
                    EveDataSet.invMarketGroupsRow marketGroup = (EveDataSet.invMarketGroupsRow)group;
                    ReportSection section = new ReportSection(_columns.Length, marketGroup.marketGroupID.ToString(),
                        marketGroup.marketGroupName, this);
                    rootSection.AddSection(section);
                    BuildSection(section);
                    UpdateStatus(counter, rootGroups.Length, "", section.Text, false);
                }
            }
            else
            {
                _sections.Add(new ReportSection(_columns.Length, "All Items", "All Items", this));
            }
            UpdateStatus(1, 1, "", "", false);
        }
        protected override void InitSections()
        {
            _sections = new ReportSections();

            UpdateStatus(0, 1, "Building Report Sections...", "", false);

            if (_byItemGroup)
            {
                // Note that an additonal root section 'Non-market items' may be added during
                // GetDataFromDatabase if it is required.
                EveDataSet.invTypesDataTable items = Items.GetItemsThatAreAssets(_assetAccessParams);
                List<int> itemIDs = new List<int>();
                foreach (EveDataSet.invTypesRow item in items)
                {
                    itemIDs.Add(item.typeID);
                }
                _marketGroups = MarketGroups.GetGroupsForItems(itemIDs);
                DataRow[] rootGroups = _marketGroups.Select("parentGroupID IS null");
                int counter = 0;
                ReportSection rootSection = new ReportSection(_columns.Length, "All Items", "All Items", this);
                _sections.Add(rootSection);
                ReportSection nonMarket = new ReportSection(_columns.Length, "Non-Market Items", "Non-Market Items", this);
                rootSection.AddSection(nonMarket);
                foreach (DataRow group in rootGroups)
                {
                    counter++;
                    EveDataSet.invMarketGroupsRow marketGroup = (EveDataSet.invMarketGroupsRow)group;
                    ReportSection section = new ReportSection(_columns.Length, marketGroup.marketGroupID.ToString(),
                        marketGroup.marketGroupName, this);
                    rootSection.AddSection(section);
                    BuildSection(section);
                    UpdateStatus(counter, rootGroups.Length, "", section.Text, false);
                }
            }
            else
            {
                _sections.Add(new ReportSection(_columns.Length, "All Items", "All Items", this));
            }
            UpdateStatus(1, 1, "", "", false);
        }