using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySqlConnector;
using skyscraper5.Dvb.Descriptors;
using skyscraper5.Dvb.Descriptors.Extension;
using skyscraper5.Dvb.Psi.Model;
using skyscraper8.Skyscraper.Scraper.Storage;

namespace skyscraper5.Data.MySql
{
    public partial class MySqlDataStorage : DataStorage
    {
        private void InsertNitCells(MySqlConnection connection, NitNetwork nitNetwork)
        {
            if (nitNetwork.Cells == null)
                return;
            if (nitNetwork.Cells.Count == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_cells" +
                "    (nid_id, cell_id, cell_longitude, cell_latitude, extend_of_latitude, extend_of_longitude) " +
                "VALUES" +
                "    (@nid_id,@cell_id,@cell_longitude,@cell_laitutde,@extend_of_latitude,@extend_of_longitude)";
            mySqlCommand.Parameters.Add("@nid_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_longitude", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_laitutde", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@extend_of_latitude", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@extend_of_longitude", MySqlDbType.Int32);
            mySqlCommand.Parameters["@nid_id"].Value = nitNetwork.NetworkId;
            foreach (CellListDescriptor.Cell cell in nitNetwork.Cells)
            {
                mySqlCommand.Parameters["@cell_id"].Value = cell.CellId;
                mySqlCommand.Parameters["@cell_longitude"].Value = cell.CellLongitude;
                mySqlCommand.Parameters["@cell_laitutde"].Value = cell.CellLatitude;
                mySqlCommand.Parameters["@extend_of_latitude"].Value = cell.ExtentOfLatitude;
                mySqlCommand.Parameters["@extend_of_longitude"].Value = cell.ExtentOfLongitude;
                mySqlCommand.ExecuteNonQuery();
                InsertNitCellSubcells(connection, nitNetwork.NetworkId, cell);
            }
        }

        private void InsertNitCellSubcells(MySqlConnection connection, ushort nitNetworkNetworkId, CellListDescriptor.Cell cell)
        {
            if (cell.Subcells == null)
                return;
            if (cell.Subcells.Length == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_cells_subcells " +
                "    (nid, cell_id, cell_id_extension, subcell_latitude, subcell_longitude, subcell_extent_of_latitude, subcell_extent_of_longitude) " +
                "VALUES " +
                "    (@nid,@cell_id,@cell_id_extension,@subcell_latitude,@subcell_longitude,@subcell_extend_of_latitude,@subcell_extend_of_longitude";
            mySqlCommand.Parameters.Add("@nid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id_extension", MySqlDbType.Int16);
            mySqlCommand.Parameters.Add("@subcell_latitude", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@subcell_longitude", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@subcell_extend_of_latitude", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@subcell_extend_of_longitude", MySqlDbType.Int32);
            mySqlCommand.Parameters["@nid"].Value = nitNetworkNetworkId;
            mySqlCommand.Parameters["@cell_id"].Value = cell.CellId;
            foreach (CellListDescriptor.Subcell subcell in cell.Subcells)
            {
                mySqlCommand.Parameters["@cell_id_extension"].Value = subcell.CellIdExtension;
                mySqlCommand.Parameters["@subcell_latitude"].Value = subcell.SubcellLatitude;
                mySqlCommand.Parameters["@subcell_longitude"].Value = subcell.SubcellLongitude;
                mySqlCommand.Parameters["@subcell_extend_of_latitude"].Value = subcell.SubcellExtentOfLatitude;
                mySqlCommand.Parameters["@subcell_extend_of_longitude"].Value = subcell.SubcellExtentOfLongitude;
                mySqlCommand.ExecuteNonQuery();
            }
        }

        private void InsertNitMessages(MySqlConnection connection, NitNetwork nitNetwork)
        {
            if (nitNetwork.Messages == null)
                return;
            if (nitNetwork.Messages.Count == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_messages (network_id, message_id, language_code, message) VALUES (@network_id,@message_id,@language_code,@message)";
            mySqlCommand.Parameters.Add("@network_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@message_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@language_code", MySqlDbType.VarChar);
            mySqlCommand.Parameters.Add("@message", MySqlDbType.VarChar);
            mySqlCommand.Parameters["@network_id"].Value = nitNetwork.NetworkId;
            foreach (MessageDescriptor message in nitNetwork.Messages)
            {
                mySqlCommand.Parameters["@message_id"].Value = message.MessageId;
                mySqlCommand.Parameters["@language_code"].Value = message.Iso639LanguageCode;
                mySqlCommand.Parameters["@message"].Value = message.Message;
                mySqlCommand.ExecuteNonQuery();
            }
        }

        private void InsertNitMultilingualName(MySqlConnection connection, NitNetwork nitNetwork)
        {
            if (nitNetwork.MultilingualNetworkName == null)
                return;
            if (nitNetwork.MultilingualNetworkName.Count == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_multilingual_name (id, language, name) VALUES (@id,@language,@name)";
            mySqlCommand.Parameters.Add("@id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@language", MySqlDbType.VarChar);
            mySqlCommand.Parameters.Add("@name", MySqlDbType.VarChar);
            mySqlCommand.Parameters["@id"].Value = nitNetwork.NetworkId;
            foreach (KeyValuePair<string, string> pair in nitNetwork.MultilingualNetworkName)
            {
                mySqlCommand.Parameters["@language"].Value = pair.Key;
                mySqlCommand.Parameters["@name"].Value = pair.Value;
                mySqlCommand.ExecuteNonQuery();
            }
        }

        private void InsertNitRegionNames(MySqlConnection connection, NitNetwork nitNetwork)
        {
            if (nitNetwork.RegionNames == null)
                return;
            if (nitNetwork.RegionNames.Count == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_region_names (id, name, primary_code, secondary_code, teritary_code) VALUES (@id,@name,@primary,@secondary,@teritary)";
            mySqlCommand.Parameters.Add("@id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@name", MySqlDbType.VarChar);
            mySqlCommand.Parameters.Add("@primary", MySqlDbType.Int16);
            mySqlCommand.Parameters.Add("@secondary", MySqlDbType.Int16);
            mySqlCommand.Parameters.Add("@teritary", MySqlDbType.Int32);
            mySqlCommand.Parameters["@id"].Value = nitNetwork.NetworkId;
            foreach (TargetRegionNameDescriptor.TargetRegionName regionName in nitNetwork.RegionNames)
            {
                mySqlCommand.Parameters["@name"].Value = regionName.RegionName;
                mySqlCommand.Parameters["@primary"].Value = regionName.PrimaryRegionCode;
                mySqlCommand.Parameters["@secondary"].Value = regionName.SecondaryRegionCode;
                mySqlCommand.Parameters["@teritary"].Value = regionName.TertiaryRegionCode;
                SetNulls(mySqlCommand);
                mySqlCommand.ExecuteNonQuery();
            }
        }

        private void InsertNitRegions(MySqlConnection connection, NitNetwork nitNetwork)
        {
            if (nitNetwork.Regions == null)
                return;
            if (nitNetwork.RegionNames.Count == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_regions " +
                "(id, country_code, primary_region_code, secondary_region_code, teritary_region_code) " +
                "VALUES " +
                "(@id,@country,@primary,@secondary,@teritary)";
            mySqlCommand.Parameters.Add("@id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@country", MySqlDbType.VarChar);
            mySqlCommand.Parameters.Add("@primary", MySqlDbType.Int16);
            mySqlCommand.Parameters.Add("@secondary", MySqlDbType.Int16);
            mySqlCommand.Parameters.Add("@teritary", MySqlDbType.Int32);
            mySqlCommand.Parameters["@id"].Value = nitNetwork.NetworkId;
            foreach (TargetRegionDescriptor.TargetRegion region in nitNetwork.Regions)
            {
                mySqlCommand.Parameters["@country"].Value = region.CountryCode;
                mySqlCommand.Parameters["@primary"].Value = region.PrimaryRegionCode;
                mySqlCommand.Parameters["@secondary"].Value = region.SecondaryRegionCode;
                mySqlCommand.Parameters["@teritary"].Value = region.TertiaryRegionCode;
                SetNulls(mySqlCommand);
                mySqlCommand.ExecuteNonQuery();
            }
        }

        private void InsertNitServices(MySqlConnection connection, NitNetwork nitNetwork)
        {
            if (nitNetwork.ServiceList == null)
                return;
            if (nitNetwork.ServiceList.Length == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_services (network_id, service_id, service_type) VALUES (@network_id,@service_id,@service_type)";
            mySqlCommand.Parameters.Add("@network_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@service_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@service_type", MySqlDbType.Int32);
            mySqlCommand.Parameters["@network_id"].Value = nitNetwork.NetworkId;
            foreach (ServiceListDescriptor.Service service in nitNetwork.ServiceList)
            {
                mySqlCommand.Parameters["@service_id"].Value = service.ServiceId;
                mySqlCommand.Parameters["@service_type"].Value = (int)service.ServiceType;
                mySqlCommand.ExecuteNonQuery();
            }
        }

        private NitNetwork GetNitNetwork(ushort newerNetworkId)
        {
            using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString()))
            {
                connection.Open();
                MySqlCommand mySqlCommand = connection.CreateCommand();
                mySqlCommand.CommandText = "SELECT * FROM dvb_nit WHERE id = @id";
                mySqlCommand.Parameters.Add("@id", MySqlDbType.Int32);
                mySqlCommand.Parameters["@id"].Value = newerNetworkId;
                MySqlDataReader dataReader = mySqlCommand.ExecuteReader();
                NitNetwork result = null;
                if (dataReader.Read())
                {
                    ushort id = dataReader.GetUInt16(0);
                    result = new NitNetwork(id);
                    if (!dataReader.IsDBNull(1))
                        result.Name = dataReader.GetString(1);
                    if (!dataReader.IsDBNull(2))
                        ;
                    if (!dataReader.IsDBNull(3))
                        result.PrivateDataSpecifierId = dataReader.GetUInt32(3);
                    if (!dataReader.IsDBNull(4))
                        result.XaitPid = dataReader.GetUInt16(4);
                    if (!dataReader.IsDBNull(5))
                        result.RegionNameCountryCode = dataReader.GetString(5);
                    if (!dataReader.IsDBNull(6))
                        result.RegionNameLanguageCode = dataReader.GetString(6);
                    if (!dataReader.IsDBNull(7))
                        result.RegionCountryCode = dataReader.GetString(7);
                    if (!dataReader.IsDBNull(8))
                        result.MinPollingInterval = dataReader.GetUInt16(8);
                    if (!dataReader.IsDBNull(9))
                        result.Uri = dataReader.GetString(9);
                    if (!dataReader.IsDBNull(10))
                        result.UriLinkageType = dataReader.GetByte(10);
                    dataReader.Close();
                }
                connection.Close();
                return result;
            }
        }

        private void InsertNitTransportStreamCellFrequencies(MySqlConnection connection, ushort networkId, NitTransportStream transportStream)
        {
            if (transportStream.CellFrequencies == null)
                return;

            if (transportStream.CellFrequencies.Count == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_transport_stream_cell_frequencies (nid, tsid, cell_id, frequency) VALUES (@nid,@tsid,@cell_id, @frequency)";
            mySqlCommand.Parameters.Add("@nid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@tsid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@frequency", MySqlDbType.Int64);
            mySqlCommand.Parameters["@nid"].Value = networkId;
            mySqlCommand.Parameters["@tsid"].Value = transportStream.TransportStreamId;
            foreach (CellFrequencyLinkDescriptor.Cell cell in transportStream.CellFrequencies)
            {
                mySqlCommand.Parameters["@cell_id"].Value = cell.CellId;
                mySqlCommand.Parameters["@frequency"].Value = cell.Frequency;
                mySqlCommand.ExecuteNonQuery();
            }
        }

        private void InsertNitTransportStreamCellInfos(MySqlConnection connection, ushort networkId, NitTransportStream transportStream)
        {
            if (transportStream.CellInfos == null)
                return;

            if (transportStream.CellInfos.Count == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_transport_stream_cell_infos (nid, tsid, cell_id) VALUES (@nid,@tsid,@cell_id)";
            mySqlCommand.Parameters.Add("@nid", DbType.Int32);
            mySqlCommand.Parameters.Add("@tsid", DbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id", DbType.Int32);
            mySqlCommand.Parameters["@nid"].Value = networkId;
            mySqlCommand.Parameters["@tsid"].Value = transportStream.TransportStreamId;
            foreach (T2DeliverySystemDescriptor.CellInfo cellInfo in transportStream.CellInfos)
            {
                mySqlCommand.Parameters["@cell_id"].Value = cellInfo.CellId;
                mySqlCommand.ExecuteNonQuery();

                InsertNitTransportStreamCellInfosCenterFrequencies(connection, networkId, transportStream.TransportStreamId, cellInfo);
                InsertNitTransportStreamCellInfosSubcellInfos(connection, networkId, transportStream.TransportStreamId, cellInfo);
            }
        }

        private void InsertNitTransportStreamCellInfosSubcellInfos(MySqlConnection connection, ushort networkId, ushort transportStreamTransportStreamId, T2DeliverySystemDescriptor.CellInfo cellInfo)
        {
            if (cellInfo.CentreFrequencies == null)
                return;

            if (cellInfo.CentreFrequencies.Length == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_transport_stream_cell_infos_subcell_infos (nid, tsid, cell_id, ordinal, cell_id_extension, transposer_frequency) " +
                "VALUES (@nid,@tsid,@cell_id,@ordinal,@cell_id_extension,@transposeer_frequency)";
            mySqlCommand.Parameters.Add("@nid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@tsid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@ordinal", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id_extension", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@transposer_frequency", MySqlDbType.Int32);
            mySqlCommand.Parameters["@nid"].Value = networkId;
            mySqlCommand.Parameters["@tsid"].Value = transportStreamTransportStreamId;
            mySqlCommand.Parameters["@cell_id"].Value = cellInfo.CellId;
            for (int i = 0; i < cellInfo.SubcellInfos.Length; i++)
            {
                mySqlCommand.Parameters["@ordinal"].Value = i;
                mySqlCommand.Parameters["@cell_id_extension"].Value = cellInfo.SubcellInfos[i].CellIdExtension;
                mySqlCommand.Parameters["@transposer_frequency"].Value = cellInfo.SubcellInfos[i].TransposerFrequency;
                mySqlCommand.ExecuteNonQuery();
            }

        }

        private void InsertNitTransportStreamCellInfosCenterFrequencies(MySqlConnection connection, ushort networkId, ushort transportStreamTransportStreamId, T2DeliverySystemDescriptor.CellInfo cellInfo)
        {
            if (cellInfo.CentreFrequencies == null)
                return;

            if (cellInfo.CentreFrequencies.Length == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_transport_stream_cell_infos_center_frequencies (nid, tsid, cell_id, ordinal, frequency) " +
                "VALUES (@nid, @tsid, @cell_id, @ordinal, @frequency)";
            mySqlCommand.Parameters.Add("@nid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@tsid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@ordinal", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@frequency", MySqlDbType.Int64);
            mySqlCommand.Parameters["@nid"].Value = networkId;
            mySqlCommand.Parameters["@tsid"].Value = transportStreamTransportStreamId;
            mySqlCommand.Parameters["@cell_id"].Value = cellInfo.CellId;
            for (int i = 0; i < cellInfo.CentreFrequencies.Length; i++)
            {
                mySqlCommand.Parameters["@ordinal"].Value = i;
                mySqlCommand.Parameters["@frequency"].Value = cellInfo.CentreFrequencies[i];
                mySqlCommand.ExecuteNonQuery();
            }
        }

        private void InsertNitTransportStreamCells(MySqlConnection connection, ushort networkId, NitTransportStream transportStream)
        {
            if (transportStream.Cells == null)
                return;

            if (transportStream.Cells.Count == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_transport_stream_cells (nid, tsid, cell_id, cell_lat, cell_lon, extent_lat, extent_lon) " +
                "VALUES (@nid, @tsid, @cell_id, @cell_lat, @cell_lon, @extent_lat, @extent_lon)";
            mySqlCommand.Parameters.Add("@nid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@tsid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_lat", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_lon", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@extent_lat", MySqlDbType.Int64);
            mySqlCommand.Parameters.Add("@extent_lon", MySqlDbType.Int64);
            mySqlCommand.Parameters["@nid"].Value = networkId;
            mySqlCommand.Parameters["@tsid"].Value = transportStream.TransportStreamId;
            foreach (CellListDescriptor.Cell cell in transportStream.Cells)
            {
                mySqlCommand.Parameters["@cell_id"].Value = cell.CellId;
                mySqlCommand.Parameters["@cell_lat"].Value = cell.CellLatitude;
                mySqlCommand.Parameters["@cell_lon"].Value = cell.CellLongitude;
                mySqlCommand.Parameters["@extent_lat"].Value = cell.ExtentOfLatitude;
                mySqlCommand.Parameters["@extent_lon"].Value = cell.ExtentOfLongitude;
                mySqlCommand.ExecuteNonQuery();

                InsertDvbNitTransportStreamCellSubcells(connection, networkId, transportStream.TransportStreamId, cell);
            }
        }

        private void InsertDvbNitTransportStreamCellSubcells(MySqlConnection connection, ushort networkId, ushort transportStreamTransportStreamId, CellListDescriptor.Cell cell)
        {
            if (cell.Subcells == null)
                return;

            if (cell.Subcells.Length == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_transport_stream_cells_subcells (nid, tsid, cell_id, cell_id_extension, subcell_lat, subcell_lon, subcell_extent_lat, subcell_extent_lon) " +
                "VALUES (@nid, @tsid, @cell_id, @cell_id_extension, @subcell_lat, @subcell_lon, @subcell_extent_lat, @subcell_extent_lon)";
            mySqlCommand.Parameters.Add("@nid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@tsid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@cell_id_extension", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@subcell_lat", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@subcell_lon", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@subcell_extent_lat", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@subcell_extent_lon", MySqlDbType.Int32);
            mySqlCommand.Parameters["@nid"].Value = networkId;
            mySqlCommand.Parameters["@tsid"].Value = transportStreamTransportStreamId;
            mySqlCommand.Parameters["@cell_id"].Value = cell.CellId;
            foreach (CellListDescriptor.Subcell subcell in cell.Subcells)
            {
                mySqlCommand.Parameters["@cell_id_extension"].Value = subcell.CellIdExtension;
                mySqlCommand.Parameters["@subcell_lat"].Value = subcell.SubcellLatitude;
                mySqlCommand.Parameters["@subcell_lon"].Value = subcell.SubcellLongitude;
                mySqlCommand.Parameters["@subcell_extent_lat"].Value = subcell.SubcellExtentOfLatitude;
                mySqlCommand.Parameters["@subcell_extent_lon"].Value = subcell.SubcellExtentOfLongitude;
                mySqlCommand.ExecuteNonQuery();
            }
        }


        private void InsertNitTransportStreamCentreFrequencies(MySqlConnection connection, ushort networkId, NitTransportStream transportStream)
        {
            if (transportStream.CentreFrequencies == null)
                return;

            if (transportStream.CentreFrequencies.Length == 0)
                return;

            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText =
                "INSERT INTO dvb_nit_transport_stream_centre_frequencies (nid, tsid, ordinal, frequency) " +
                "VALUES (@nid,@tsid,@ordinal,@frequency)";
            mySqlCommand.Parameters.Add("@nid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@tsid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@ordinal", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@frequency", MySqlDbType.Int64);
            mySqlCommand.Parameters["@nid"].Value = networkId;
            mySqlCommand.Parameters["@tsid"].Value = transportStream.TransportStreamId;
            for (int i = 0; i < transportStream.CentreFrequencies.Length; i++)
            {
                mySqlCommand.Parameters["@ordinal"].Value = i;
                mySqlCommand.Parameters["@frequency"].Value = transportStream.CentreFrequencies[i];
                mySqlCommand.ExecuteNonQuery();
            }
        }

        private void InsertNitTransportStreamServices(MySqlConnection connection, ushort networkId, NitTransportStream transportStream, MySqlTransaction transaction)
        {
            if (transportStream.Services == null)
                return;

            if (transportStream.Services.Services == null)
                return;

            if (transportStream.Services.Services.Length == 0)
                return;

            MySqlCommand command = connection.CreateCommand();
            command.Transaction = transaction;
            command.CommandText =
                "INSERT INTO dvb_nit_transport_stream_services (nid, tsid, service_id, service_type) " +
                "VALUES (@nid, @tsid, @service_id, @service_type)";
            command.Parameters.Add("@nid", MySqlDbType.Int32);
            command.Parameters.Add("@tsid", MySqlDbType.Int32);
            command.Parameters.Add("@service_id", MySqlDbType.Int32);
            command.Parameters.Add("@service_type", MySqlDbType.Int32);
            command.Parameters["@nid"].Value = networkId;
            command.Parameters["@tsid"].Value = transportStream.TransportStreamId;
            foreach (ServiceListDescriptor.Service service in transportStream.Services.Services)
            {
                command.Parameters["@service_id"].Value = service.ServiceId;
                command.Parameters["@service_type"].Value = (int)service.ServiceType;
                command.ExecuteNonQuery();
            }
        }

        private void InsertNitTransportStreamTargetRegions(MySqlConnection connection, ushort networkId, NitTransportStream transportStream)
        {
            if (transportStream.TargetRegions == null)
                return;

            if (transportStream.TargetRegions.Count == 0)
                return;

            MySqlCommand command = connection.CreateCommand();
            command.CommandText =
                "INSERT INTO dvb_nit_transport_stream_target_regions (nid, tsid, country_code, primary_rc, secondary_rc, teritary_rc) " +
                "VALUES (@nid,@tsid,@country_code,@primary_rc,@secondary_rc,@teritary_rc)";
            command.Parameters.Add("@nid", MySqlDbType.Int32);
            command.Parameters.Add("@tsid", MySqlDbType.Int32);
            command.Parameters.Add("@country_code", MySqlDbType.VarChar);
            command.Parameters.Add("@primary_rc", MySqlDbType.Int16);
            command.Parameters.Add("@secondary_rc", MySqlDbType.Int16);
            command.Parameters.Add("@teritary_rc", MySqlDbType.Int32);
            command.Parameters["@nid"].Value = networkId;
            command.Parameters["@tsid"].Value = transportStream.TransportStreamId;
            foreach (TargetRegionDescriptor.TargetRegion targetRegion in transportStream.TargetRegions)
            {
                command.Parameters["@country_code"].Value = targetRegion.CountryCode;
                command.Parameters["@primary_rc"].Value = targetRegion.PrimaryRegionCode;
                command.Parameters["@secondary_rc"].Value = targetRegion.SecondaryRegionCode;
                command.Parameters["@teritary_rc"].Value = targetRegion.TertiaryRegionCode;
                SetNulls(command);
                command.ExecuteNonQuery();
            }
        }

        private NitTransportStream GetNitTransportStream(MySqlConnection connection, ushort networkId, ushort olderTransportStreamId)
        {
            MySqlCommand mySqlCommand = connection.CreateCommand();
            mySqlCommand.CommandText = "SELECT * FROM dvb_nit_transport_stream WHERE nid = @nid AND tsid = @tsid";
            mySqlCommand.Parameters.Add("@nid", MySqlDbType.Int32);
            mySqlCommand.Parameters.Add("@tsid", MySqlDbType.Int32);
            mySqlCommand.Parameters["@nid"].Value = networkId;
            mySqlCommand.Parameters["@tsid"].Value = olderTransportStreamId;
            MySqlDataReader dataReader = mySqlCommand.ExecuteReader();
            if (!dataReader.Read())
            {
                dataReader.Close();
                return null;
            }
            
            ushort transportStreamId = dataReader.GetUInt16(1);
            ushort originalNetworkId = dataReader.GetUInt16(3);
            NitTransportStream.TransportMedium deliveryMethod = (NitTransportStream.TransportMedium)dataReader.GetInt32(4);

            NitTransportStream result = new NitTransportStream(originalNetworkId, transportStreamId);
            result.DeliveryMethod = deliveryMethod;

            if (!dataReader.IsDBNull(5))
                result.East = dataReader.GetBoolean(5);

            if (!dataReader.IsDBNull(6))
                result.FecInner = (SatelliteDeliverySystemDescriptor.InnerFecScheme)dataReader.GetInt32(6);

            if (!dataReader.IsDBNull(7))
                result.Frequency = dataReader.GetInt64(7);

            if (!dataReader.IsDBNull(8))
                result.OrbitalPosition = dataReader.GetFloat(8);

            if (!dataReader.IsDBNull(9))
                result.Polarization = (SatelliteDeliverySystemDescriptor.PolarizationEnum)dataReader.GetInt32(9);

            if (!dataReader.IsDBNull(10))
                result.RollOff = dataReader.GetFloat(10);

            if (!dataReader.IsDBNull(11))
                result.S2 = dataReader.GetBoolean(11);

            if (!dataReader.IsDBNull(12))
                result.SymbolRate = dataReader.GetInt64(12);

            if (!dataReader.IsDBNull(13))
                result.ScramblingSequenceIndex = dataReader.GetInt32(13);

            if (!dataReader.IsDBNull(14))
                result.InputStreamIdentifier = dataReader.GetByte(14);

            if (!dataReader.IsDBNull(15))
                result.TimesliceNumber = dataReader.GetByte(15);

            if (!dataReader.IsDBNull(16))
                result.TsGsMode = (S2SatelliteDeliverySystemDescriptor.TsGsModeCoding)dataReader.GetInt32(16);

            if (!dataReader.IsDBNull(17))
                result.PrivateDataSpecifierId = dataReader.GetUInt32(17);

            if (!dataReader.IsDBNull(18))
                result.TfsFlag = dataReader.GetBoolean(18);

            if (!dataReader.IsDBNull(19))
                result.Bandwidth = dataReader.GetInt32(19);

            if (!dataReader.IsDBNull(20))
                result.GuardInterval = dataReader.GetInt32(20);

            if (!dataReader.IsDBNull(21))
                result.OtherFrequencyFlag = dataReader.GetBoolean(21);

            if (!dataReader.IsDBNull(22))
                result.PlpId = dataReader.GetByte(22);

            if (!dataReader.IsDBNull(23))
                result.SisoMiso = dataReader.GetInt32(23);

            if (!dataReader.IsDBNull(24))
                result.T2SystemId = dataReader.GetUInt16(24);

            if (!dataReader.IsDBNull(25))
                result.TransmissionMode = dataReader.GetInt32(25);

            if (!dataReader.IsDBNull(26))
                result.CodingType = (FrequencyListDescriptor.CodingTypeValue)dataReader.GetInt32(26);

            if (!dataReader.IsDBNull(27))
                result.ModulationType = dataReader.GetInt32(27);

            if (!dataReader.IsDBNull(28))
                result.FecOuter = (CableDeliverySystemDescriptor.OuterFecScheme)dataReader.GetInt32(28);

            if (!dataReader.IsDBNull(29))
                result.CodeRateHpStream = (TerristialDeliverySystemDescriptor.CodeRate)dataReader.GetInt32(29);

            if (!dataReader.IsDBNull(30))
                result.CodeRateLpStream = (TerristialDeliverySystemDescriptor.CodeRate)dataReader.GetInt32(30);

            if (!dataReader.IsDBNull(31))
                result.HierarchyInformation = (TerristialDeliverySystemDescriptor.HierarchySignallingFormat)dataReader.GetInt32(31);

            if (!dataReader.IsDBNull(32))
                result.MpeFecIndicator = dataReader.GetBoolean(32);

            if (!dataReader.IsDBNull(33))
                result.Priority = dataReader.GetBoolean(33);

            if (!dataReader.IsDBNull(34))
                result.TimeSlicingIndicator = dataReader.GetInt32(34);

            if (!dataReader.IsDBNull(35))
                result.NetworkName = dataReader.GetString(35);

            if (!dataReader.IsDBNull(36))
                result.TargetRegionCountryCode = dataReader.GetString(36);

            dataReader.Close();
            return result;
        }

        struct NitTransportStreamCoordinate
        {
            private readonly ushort _networkId;
            private readonly ushort _transportStreamTransportStreamId;

            public NitTransportStreamCoordinate(ushort networkId, ushort transportStreamTransportStreamId)
            {
                _networkId = networkId;
                _transportStreamTransportStreamId = transportStreamTransportStreamId;
            }

            public bool Equals(NitTransportStreamCoordinate other)
            {
                return _networkId == other._networkId && _transportStreamTransportStreamId == other._transportStreamTransportStreamId;
            }

            public override bool Equals(object obj)
            {
                return obj is NitTransportStreamCoordinate other && Equals(other);
            }

            public override int GetHashCode()
            {
                return HashCode.Combine(_networkId, _transportStreamTransportStreamId);
            }
        }

        private HashSet<NitTransportStreamCoordinate> _nitTransportStreamCoordinates;
        private HashSet<NitTransportStreamCoordinate> _nitTransportStreamUpdateCoordinates;

		public bool TestForNitNetwork(NitNetwork nitNetwork)
		{
			using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString()))
			{
				connection.Open();
				MySqlCommand mySqlCommand = connection.CreateCommand();
				mySqlCommand.CommandText = "SELECT dateadded FROM dvb_nit WHERE id = @id";
				mySqlCommand.Parameters.Add("@id", MySqlDbType.Int32);
				mySqlCommand.Parameters["@id"].Value = nitNetwork.NetworkId;
				MySqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();
				bool result = mySqlDataReader.Read();
				mySqlDataReader.Close();
				connection.Close();
				return result;
			}
		}

		public void StoreNitNetwork(NitNetwork nitNetwork)
		{
			bool hasLinkages = HasLinkages(nitNetwork.Linkages);
			Guid linkageGuid = default(Guid);
			if (hasLinkages)
				linkageGuid = Guid.NewGuid();

			using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString()))
			{
				connection.Open();
				MySqlTransaction transaction = connection.BeginTransaction();
				MySqlCommand mySqlCommand = connection.CreateCommand();
				mySqlCommand.Transaction = transaction;
				mySqlCommand.CommandText =
					"INSERT INTO dvb_nit" +
					"    (id, name, uuid, private_data_specifier_id, xait_pid, region_name_country_code, region_name_language_code, region_country_code, min_polling_interval, uri, uri_linkage_type) " +
					"VALUES" +
					"    (@id,@name,@uuid,@private_data_specifier,@xait_pid,@region_name_country_code,@region_name_language_code,@region_country_code,@min_polling_interval,@uri,@uri_linkage_type)";
				mySqlCommand.Parameters.Add("@id", MySqlDbType.Int32);
				mySqlCommand.Parameters.Add("@name", MySqlDbType.VarChar);
				mySqlCommand.Parameters.Add("@uuid", MySqlDbType.VarChar);
				mySqlCommand.Parameters.Add("@private_data_specifier", MySqlDbType.Int64);
				mySqlCommand.Parameters.Add("@xait_pid", MySqlDbType.Int32);
				mySqlCommand.Parameters.Add("@region_name_country_code", MySqlDbType.VarChar);
				mySqlCommand.Parameters.Add("@region_name_language_code", MySqlDbType.VarChar);
				mySqlCommand.Parameters.Add("@region_country_code", MySqlDbType.VarChar);
				mySqlCommand.Parameters.Add("@min_polling_interval", MySqlDbType.Int32);
				mySqlCommand.Parameters.Add("@uri", MySqlDbType.VarChar);
				mySqlCommand.Parameters.Add("@uri_linkage_type", MySqlDbType.Int32);
				mySqlCommand.Parameters["@id"].Value = nitNetwork.NetworkId;
				mySqlCommand.Parameters["@name"].Value = nitNetwork.Name;
				if (hasLinkages)
					mySqlCommand.Parameters["@uuid"].Value = linkageGuid.ToString();
				mySqlCommand.Parameters["@private_data_specifier"].Value = nitNetwork.PrivateDataSpecifierId;
				mySqlCommand.Parameters["@xait_pid"].Value = nitNetwork.XaitPid;
				mySqlCommand.Parameters["@region_name_country_code"].Value = nitNetwork.RegionNameCountryCode;
				mySqlCommand.Parameters["@region_name_language_code"].Value = nitNetwork.RegionNameLanguageCode;
				mySqlCommand.Parameters["@region_country_code"].Value = nitNetwork.RegionCountryCode;
				mySqlCommand.Parameters["@min_polling_interval"].Value = nitNetwork.MinPollingInterval;
				mySqlCommand.Parameters["@uri"].Value = nitNetwork.Uri;
				mySqlCommand.Parameters["@uri_linkage_type"].Value = nitNetwork.UriLinkageType;
				SetNulls(mySqlCommand);
				mySqlCommand.ExecuteNonQuery();

				if (hasLinkages)
					InsertSdtLinkages(connection, linkageGuid, nitNetwork.Linkages, transaction);

				InsertNitCells(connection, nitNetwork);
				InsertNitMessages(connection, nitNetwork);
				InsertNitMultilingualName(connection, nitNetwork);
				InsertNitRegionNames(connection, nitNetwork);
				InsertNitRegions(connection, nitNetwork);
				InsertNitServices(connection, nitNetwork);
				transaction.Commit();
				connection.Close();
			}
		}

		public bool UpdateNitNetwork(NitNetwork newer)
		{
			NitNetwork older = GetNitNetwork(newer.NetworkId);
			if (older.NeedsUpdate(newer))
			{
				using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString()))
				{
					connection.Open();
					MySqlCommand mySqlCommand = connection.CreateCommand();
					mySqlCommand.CommandText =
						"UPDATE dvb_nit " +
						"SET name = @name, private_data_specifier_id = @private_data_specifier, xait_pid = @xait_pid, region_name_country_code = @region_name_country_code, region_name_language_code = @region_name_language_code, region_country_code = @region_country_code, min_polling_interval = @min_polling_interval, uri = @uri, uri_linkage_type = @uri_linkage_type, numupdates = numupdates + 1, dateupdated = CURRENT_TIMESTAMP " +
						"WHERE id = @id";
					mySqlCommand.Parameters.Add("@id", MySqlDbType.Int32);
					mySqlCommand.Parameters.Add("@name", MySqlDbType.VarChar);
					mySqlCommand.Parameters.Add("@private_data_specifier", MySqlDbType.Int64);
					mySqlCommand.Parameters.Add("@xait_pid", MySqlDbType.Int32);
					mySqlCommand.Parameters.Add("@region_name_country_code", MySqlDbType.VarChar);
					mySqlCommand.Parameters.Add("@region_name_language_code", MySqlDbType.VarChar);
					mySqlCommand.Parameters.Add("@region_country_code", MySqlDbType.VarChar);
					mySqlCommand.Parameters.Add("@min_polling_interval", MySqlDbType.Int32);
					mySqlCommand.Parameters.Add("@uri", MySqlDbType.VarChar);
					mySqlCommand.Parameters.Add("@uri_linkage_type", MySqlDbType.Int32);
					mySqlCommand.Parameters["@id"].Value = newer.NetworkId;
					mySqlCommand.Parameters["@name"].Value = newer.Name;
					mySqlCommand.Parameters["@private_data_specifier"].Value = newer.PrivateDataSpecifierId;
					mySqlCommand.Parameters["@xait_pid"].Value = newer.XaitPid;
					mySqlCommand.Parameters["@region_name_country_code"].Value = newer.RegionNameCountryCode;
					mySqlCommand.Parameters["@region_name_language_code"].Value = newer.RegionNameLanguageCode;
					mySqlCommand.Parameters["@region_country_code"].Value = newer.RegionCountryCode;
					mySqlCommand.Parameters["@min_polling_interval"].Value = newer.MinPollingInterval;
					mySqlCommand.Parameters["@uri"].Value = newer.Uri;
					mySqlCommand.Parameters["@uri_linkage_type"].Value = newer.UriLinkageType;
					mySqlCommand.ExecuteNonQuery();
					connection.Close();
					return true;
				}
			}
			return false;
		}

		public bool TestForNitTransportStream(ushort networkId, NitTransportStream transportStream)
		{
			if (_nitTransportStreamCoordinates == null)
				_nitTransportStreamCoordinates = new HashSet<NitTransportStreamCoordinate>();
			NitTransportStreamCoordinate coordinate = new NitTransportStreamCoordinate(networkId, transportStream.TransportStreamId);
			if (_nitTransportStreamCoordinates.Contains(coordinate))
				return true;

			using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString()))
			{
				connection.Open();
				MySqlCommand mySqlCommand = connection.CreateCommand();
				mySqlCommand.CommandText =
					"SELECT dateadded FROM dvb_nit_transport_stream WHERE nid=@nid AND tsid=@tsid";
				mySqlCommand.Parameters.Add("@nid", MySqlDbType.Int32);
				mySqlCommand.Parameters.Add("@tsid", MySqlDbType.Int32);
				mySqlCommand.Parameters["@nid"].Value = networkId;
				mySqlCommand.Parameters["@tsid"].Value = transportStream.TransportStreamId;
				MySqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();
				bool result = mySqlDataReader.Read();
				if (result)
					_nitTransportStreamCoordinates.Add(coordinate);
				mySqlDataReader.Close();
				connection.Close();
				return result;
			}
		}

		public void StoreNitTransportStream(ushort networkId, NitTransportStream transportStream)
		{
			EnqueueSpeedhack(SpeedhackType.InsertNitTransportStream, networkId, transportStream);
			NitTransportStreamCoordinate coordinate = new NitTransportStreamCoordinate(networkId, transportStream.TransportStreamId);
			_nitTransportStreamCoordinates.Add(coordinate);

		}

		public bool UpdateNitTransportStream(ushort networkId, NitTransportStream newer)
		{
			if (_nitTransportStreamUpdateCoordinates == null)
				_nitTransportStreamUpdateCoordinates = new HashSet<NitTransportStreamCoordinate>();

			NitTransportStreamCoordinate coordinate = new NitTransportStreamCoordinate(networkId, newer.TransportStreamId);
			if (_nitTransportStreamUpdateCoordinates.Contains(coordinate))
				return false;

			using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString()))
			{
				connection.Open();
				NitTransportStream older = GetNitTransportStream(connection, networkId, newer.TransportStreamId);
				connection.Close();
				if (older == null)
				{
					return false;
				}

				_nitTransportStreamUpdateCoordinates.Add(coordinate);
				if (older.NeedUpdate(newer))
				{
					EnqueueSpeedhack(SpeedhackType.UpdateNitTransportStream, networkId, newer);
					return true;
				}
				return false;
			}
		}

		public int CountNitEntries()
		{
			using (MySqlConnection connectino = new MySqlConnection(_mcsb.ToString()))
			{
				connectino.Open();
				using (MySqlCommand command = connectino.CreateCommand())
				{
					command.CommandText = "SELECT COUNT(*) FROM dvb_nit_transport_stream";
					MySqlDataReader dataReader = command.ExecuteReader();
					dataReader.Read();
					int result = dataReader.GetInt32(0);
					dataReader.Close();
					connectino.Close();
					return result;
				}
			}
		}

		public IEnumerable<NitTransportStream> EnumerateNitTransportStreams()
		{
			using (MySqlConnection connection = new MySqlConnection(_mcsb.ToString()))
			{
				connection.Open();
				using (MySqlCommand command = connection.CreateCommand())
				{
					command.CommandText = "SELECT * FROM dvb_nit_transport_stream";
					MySqlDataReader dataReader = command.ExecuteReader();
					while (dataReader.Read())
					{
						ushort nid = dataReader.GetUInt16(0);
						ushort tsid = dataReader.GetUInt16(1);
						DateTime dateAdded = dataReader.GetDateTime(2);
						int onid = dataReader.GetUInt16(3);
						NitTransportStream child = new NitTransportStream(nid, tsid);
						child.DeliveryMethod = (NitTransportStream.TransportMedium)dataReader.GetInt32(4);
						if (!dataReader.IsDBNull(5))
							child.East = dataReader.GetBoolean(5);

						if (!dataReader.IsDBNull(6))
							child.FecInner = (SatelliteDeliverySystemDescriptor.InnerFecScheme)dataReader.GetInt32(6);

						if (!dataReader.IsDBNull(7))
							child.Frequency = dataReader.GetInt64(7);

						if (!dataReader.IsDBNull(8))
							child.OrbitalPosition = dataReader.GetFloat(8);

						if (!dataReader.IsDBNull(9))
							child.Polarization = (SatelliteDeliverySystemDescriptor.PolarizationEnum)dataReader.GetInt32(9);

						if (!dataReader.IsDBNull(10))
							child.RollOff = dataReader.GetFloat(10);

						if (!dataReader.IsDBNull(11))
							child.S2 = dataReader.GetBoolean(11);

						if (!dataReader.IsDBNull(12))
							child.SymbolRate = dataReader.GetInt64(12);

						if (!dataReader.IsDBNull(13))
							child.ScramblingSequenceIndex = dataReader.GetInt32(13);

						if (!dataReader.IsDBNull(14))
							child.InputStreamIdentifier = dataReader.GetByte(14);

						if (!dataReader.IsDBNull(15))
							child.TimesliceNumber = dataReader.GetByte(15);

						if (!dataReader.IsDBNull(16))
							child.TsGsMode = (S2SatelliteDeliverySystemDescriptor.TsGsModeCoding)dataReader.GetInt32(16);

						if (!dataReader.IsDBNull(17))
							child.PrivateDataSpecifierId = (uint)dataReader.GetUInt32(17);

						if (!dataReader.IsDBNull(18))
							child.TfsFlag = dataReader.GetBoolean(18);

						if (!dataReader.IsDBNull(19))
							child.Bandwidth = dataReader.GetInt32(19);

						if (!dataReader.IsDBNull(20))
							child.GuardInterval = dataReader.GetInt32(20);

						if (!dataReader.IsDBNull(21))
							child.OtherFrequencyFlag = dataReader.GetBoolean(21);

						if (!dataReader.IsDBNull(22))
							child.PlpId = dataReader.GetByte(22);

						if (!dataReader.IsDBNull(23))
							child.SisoMiso = dataReader.GetInt32(23);

						if (!dataReader.IsDBNull(24))
							child.T2SystemId = dataReader.GetUInt16(24);

						if (!dataReader.IsDBNull(25))
							child.TransmissionMode = dataReader.GetInt32(25);

						if (!dataReader.IsDBNull(26))
							child.CodingType = (FrequencyListDescriptor.CodingTypeValue)dataReader.GetInt32(26);

						if (!dataReader.IsDBNull(27))
							child.ModulationType = dataReader.GetInt32(27);

						if (!dataReader.IsDBNull(28))
							child.FecOuter = (CableDeliverySystemDescriptor.OuterFecScheme)dataReader.GetInt32(28);

						if (!dataReader.IsDBNull(29))
							child.CodeRateHpStream = (TerristialDeliverySystemDescriptor.CodeRate)dataReader.GetInt32(29);

						if (!dataReader.IsDBNull(30))
							child.CodeRateLpStream = (TerristialDeliverySystemDescriptor.CodeRate)dataReader.GetInt32(30);

						if (!dataReader.IsDBNull(31))
							child.HierarchyInformation = (TerristialDeliverySystemDescriptor.HierarchySignallingFormat)dataReader.GetInt32(31);

						if (!dataReader.IsDBNull(32))
							child.MpeFecIndicator = dataReader.GetBoolean(32);

						if (!dataReader.IsDBNull(33))
							child.Priority = dataReader.GetBoolean(33);

						if (!dataReader.IsDBNull(34))
							child.TimeSlicingIndicator = dataReader.GetInt32(34);

						if (!dataReader.IsDBNull(35))
							child.NetworkName = dataReader.GetString(35);

						if (!dataReader.IsDBNull(36))
							child.TargetRegionCountryCode = dataReader.GetString(36);

						if (!dataReader.IsDBNull(37))
							Guid.Parse(dataReader.GetString(37));

						if (!dataReader.IsDBNull(38))
							dataReader.GetInt32(38);

						if (!dataReader.IsDBNull(39))
							dataReader.GetDateTime(39);

						yield return child;
					}
					dataReader.Close();
				}
				connection.Close();
			}
		}


	}
}
