private void processEPGFileForNZL(DateTime date, int serviceID, byte[] fileData, Logger logger)
        {
            if (logger != null && RunParameters.Instance.TraceIDs.Contains("DSMCCFILE"))
                logger.Dump("DSMCC Parser data - File Entry", fileData, fileData.Length);

            if (RunParameters.Instance.TraceIDs.Contains("DSMCCRECLAYOUT"))
            {
                Collection<byte[]> logRecords = Utils.SplitBytes(fileData, 0x1c);
                Logger.Instance.Write("Block contains " + logRecords.Count + " records");
                foreach (byte[] logRecord in logRecords)
                {
                    Collection<byte[]> logFields = Utils.SplitBytes(fileData, 0x1d);
                    Logger.Instance.Write("Record contains " + logFields.Count + " fields");
                    foreach (byte[] logField in logFields)
                        Logger.Instance.Write("    Field: " + Utils.GetAsciiString(logField));
                }
            }

            TVStation tvStation = TVStation.FindStation(serviceID);
            if (tvStation == null)
                return;

            bool process = checkChannelMapping(tvStation);
            if (!process)
                return;

            int rootCRIDFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.RootCRID);
            if (rootCRIDFieldNumber == -1)
                rootCRIDFieldNumber = 3;

            int programCountFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.ProgramCount);
            if (programCountFieldNumber == -1)
                programCountFieldNumber = 4;

            int eventIDFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.EventID);
            if (eventIDFieldNumber == -1)
                eventIDFieldNumber = 0;

            int startTimeFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.StartTime);
            if (startTimeFieldNumber == -1)
                startTimeFieldNumber = 1;

            int endTimeFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.EndTime);
            if (endTimeFieldNumber == -1)
                endTimeFieldNumber = 2;

            int eventCRIDFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.ProgramCRID);
            if (eventCRIDFieldNumber == -1)
                eventCRIDFieldNumber = 6;

            int eventNameFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.EventName);
            if (eventNameFieldNumber == -1)
                eventNameFieldNumber = 7;

            int shortDescriptionFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.ShortDescription);
            if (shortDescriptionFieldNumber == -1)
                shortDescriptionFieldNumber = 8;

            int imageCountFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.ImageCount);
            if (imageCountFieldNumber == -1)
                imageCountFieldNumber = 9;

            int seriesCRIDFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.SeriesCRID);
            if (seriesCRIDFieldNumber == -1)
                seriesCRIDFieldNumber = 2;

            try
            {
                Collection<byte[]> records = Utils.SplitBytes(fileData, 0x1c);

                for (int index = 0; index < records.Count; index++)
                {
                    Collection<byte[]> headerFields = Utils.SplitBytes(records[index], 0x1d);

                    int expectedHeaderFieldCount = MHEGParserParameters.HeaderFields;
                    if (expectedHeaderFieldCount != -1 && expectedHeaderFieldCount != headerFields.Count)
                        throw (new IndexOutOfRangeException(
                            "MHEG format error - count of header fields is incorrect - expected " +
                            expectedHeaderFieldCount + " got " + headerFields.Count));

                    // These fields are not used
                    // byte[] programNumber = headerFields[0];
                    // string friendlyDate = Utils.GetString(headerFields[1]);
                    // string stationName = Utils.GetString(headerFields[2]);

                    string rootCRID = Utils.GetAsciiString(headerFields[rootCRIDFieldNumber]);
                    int programCount = Int32.Parse(Utils.GetAsciiString(headerFields[programCountFieldNumber]));

                    while (programCount > 0)
                    {
                        index++;

                        if (logger != null && RunParameters.Instance.TraceIDs.Contains("DSMCCRECORD"))
                            logger.Dump("DSMCC Parser data - Program Entry", records[index], records[index].Length);

                        Collection<byte[]> dataFields = Utils.SplitBytes(records[index], 0x1d);

                        try
                        {
                            if (dataFields[1].Length != 0)
                            {
                                EPGEntry epgEntry = new EPGEntry();
                                epgEntry.OriginalNetworkID = tvStation.OriginalNetworkID;
                                epgEntry.TransportStreamID = tvStation.TransportStreamID;
                                epgEntry.ServiceID = serviceID;

                                epgEntry.EventID = Int32.Parse(Utils.GetAsciiString(headerFields[eventIDFieldNumber]));
                                epgEntry.StartTime = Utils.RoundTime(date.AddSeconds(((double)Int32.Parse(Utils.GetAsciiString(dataFields[startTimeFieldNumber])))));
                                epgEntry.Duration = Utils.RoundTime(date.AddSeconds(((double)Int32.Parse(Utils.GetAsciiString(dataFields[endTimeFieldNumber])))) - epgEntry.StartTime);

                                // These fields are not used
                                // byte[] titleLineCount = dataFields[3];
                                // byte[] friendlyTime = dataFields[4];
                                // byte[] entryType = dataFields[5];

                                string eventCRID = Utils.GetAsciiString(dataFields[eventCRIDFieldNumber]);

                                byte[] editedEventName = replaceByte(dataFields[eventNameFieldNumber], 0x0d, 0x20);
                                string eventName = Utils.GetString(editedEventName, "utf-8");
                                epgEntry.EventName = Utils.Compact(eventName);

                                byte[] editedDescription = replaceByte(dataFields[shortDescriptionFieldNumber], 0x0d, 0x20);
                                string eventDescription = Utils.GetString(editedDescription, "utf-8");
                                processNZLShortDescription(epgEntry, Utils.Compact(eventDescription));

                                int iconCount = Int32.Parse(Utils.GetAsciiString(dataFields[imageCountFieldNumber]));

                                if (iconCount < 0 || iconCount > 10)
                                {
                                    Logger.Instance.Dump("DSMCC Parser error - Icon Count - File Entry", fileData, fileData.Length);
                                    if (logger != null)
                                        logger.Dump("DSMCC Parser error - Icon Count - File Entry", fileData, fileData.Length);
                                }
                                else
                                {
                                    int imageIndex;

                                    for (imageIndex = imageCountFieldNumber + 1; imageIndex < iconCount + imageCountFieldNumber + 1; imageIndex++)
                                    {
                                        switch (Utils.GetAsciiString(dataFields[imageIndex]))
                                        {
                                            case "/pngs/ao.png":
                                                epgEntry.ParentalRating = "AO";
                                                epgEntry.MpaaParentalRating = ParentalRating.FindMpaaRating("NZL", "MHEG5", "AO");
                                                break;
                                            case "/pngs/pgr.png":
                                                epgEntry.ParentalRating = "PGR";
                                                epgEntry.MpaaParentalRating = ParentalRating.FindMpaaRating("NZL", "MHEG5", "PGR");
                                                break;
                                            case "/pngs/g.png":
                                                epgEntry.ParentalRating = "G";
                                                epgEntry.MpaaParentalRating = ParentalRating.FindMpaaRating("NZL", "MHEG5", "G");
                                                break;
                                            case "/pngs/ear.png":
                                                epgEntry.SubTitles = "teletext";
                                                break;
                                            case "/pngs/hd.png":
                                                epgEntry.VideoQuality = "HDTV";
                                                break;
                                            case "/pngs/dolby.png":
                                                epgEntry.AudioQuality = "dolby digital";
                                                break;
                                            default:
                                                break;
                                        }

                                    }

                                    int expectedDetailFieldCount = MHEGParserParameters.DetailFields;
                                    int addedDetailFieldCount = iconCount;

                                    string seriesCRID = string.Empty;

                                    if (Int32.Parse(Utils.GetAsciiString(dataFields[imageIndex])) != 0)
                                    {
                                        // This field is not used.
                                        // string entryType2 = Utils.GetString(dataFields[imageIndex + 1]);

                                        seriesCRID = Utils.GetAsciiString(dataFields[imageIndex + seriesCRIDFieldNumber]);

                                        // These fields are not used
                                        // string eventName2 = Utils.GetString(dataFields[imageIndex + 3]);
                                        // string shortDescription2 = Utils.GetString(dataFields[imageIndex + 4]);
                                        // int otherIconCount = Int32.Parse(Utils.GetString(dataFields[imageIndex + 5]));

                                        addedDetailFieldCount += 6;
                                    }
                                    else
                                        addedDetailFieldCount += 2;

                                    if (expectedDetailFieldCount != -1 && expectedDetailFieldCount + addedDetailFieldCount != dataFields.Count)
                                        throw (new IndexOutOfRangeException(
                                            "MHEG format error - count of detail fields is incorrect - expected " +
                                            (expectedDetailFieldCount + addedDetailFieldCount) + " got " + dataFields.Count));

                                    processNZLCRID(epgEntry, seriesCRID, eventCRID);

                                    epgEntry.EventCategory = CustomProgramCategory.FindCategoryDescription(epgEntry.EventName);
                                    if (epgEntry.EventCategory == null)
                                        epgEntry.EventCategory = CustomProgramCategory.FindCategoryDescription(epgEntry.ShortDescription);

                                    tvStation.AddEPGEntry(epgEntry);

                                    if (titleLogger != null)
                                        logTitle(eventName, epgEntry, titleLogger);
                                    if (descriptionLogger != null)
                                        logDescription(eventDescription, epgEntry, descriptionLogger);
                                }
                            }

                            programCount--;
                        }
                        catch (ArithmeticException)
                        {
                            Logger.Instance.Dump("DSMCC Parser error - Arithmetic Exception - File Entry", fileData, fileData.Length);
                            if (logger != null)
                                logger.Dump("DSMCC Parser error - Arithmetic Exception - File Entry", fileData, fileData.Length);
                        }
                    }
                }
            }
            catch (ArithmeticException e)
            {
                throw (new ArgumentOutOfRangeException("DSMCC file entry parsing failed: " + e.Message));
            }
        }
        private void processEPGFileForAUS(DateTime date, int serviceID, byte[] fileData, Logger logger)
        {
            /*if (logger != null && RunParameters.Instance.TraceIDs.Contains("DSMCCFILE"))
                logger.Dump("DSMCC Parser data - File Entry", fileData, fileData.Length);*/

            if (RunParameters.Instance.TraceIDs.Contains("DSMCCFILE"))
                Logger.Instance.Dump("DSMCC Parser data - File Entry", fileData, fileData.Length);

            TVStation tvStation = TVStation.FindStation(serviceID);
            if (tvStation == null)
            {
                if (RunParameters.Instance.DebugIDs.Contains("CREATEDSMCCSTATIONS"))
                {
                    Logger.Instance.Write("No station for service ID: " + serviceID);
                    tvStation = new TVStation("Service ID " + serviceID);
                    tvStation.ServiceID = serviceID;
                    TVStation.StationCollection.Add(tvStation);
                }
                else
                    return;
            }

            bool process = checkChannelMapping(tvStation);
            if (!process)
                return;

            if (RunParameters.Instance.TraceIDs.Contains("DSMCCRECLAYOUT"))
            {
                Collection<byte[]> logRecords = Utils.SplitBytes(fileData, 0x1e);
                Logger.Instance.Write("Block contains " + logRecords.Count + " records");
                foreach (byte[] logRecord in logRecords)
                {
                    Collection<byte[]> logFields = Utils.SplitBytes(fileData, 0x1d);
                    Logger.Instance.Write("Record contains " + logFields.Count + " fields");
                    foreach (byte[] logField in logFields)
                        Logger.Instance.Write("    Field: " + Utils.GetAsciiString(logField));
                }
            }

            /*int rootCRIDFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.RootCRID);
            if (rootCRIDFieldNumber == -1)
                rootCRIDFieldNumber = 0;*/

            int endTimeFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.EndTime);
            if (endTimeFieldNumber == -1)
                endTimeFieldNumber = 0;

            int startTimeFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.StartTime);
            if (startTimeFieldNumber == -1)
                startTimeFieldNumber = 1;

            int eventCRIDFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.ProgramCRID);
            if (eventCRIDFieldNumber == -1)
                eventCRIDFieldNumber = 2;

            int seriesCRIDFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.SeriesCRID);
            if (seriesCRIDFieldNumber == -1)
                seriesCRIDFieldNumber = 3;

            int eventNameFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.EventName);
            if (eventNameFieldNumber == -1)
                eventNameFieldNumber = 4;

            int shortDescriptionFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.ShortDescription);
            if (shortDescriptionFieldNumber == -1)
                shortDescriptionFieldNumber = 5;

            int highDefinitionFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.HighDefinition);
            if (highDefinitionFieldNumber == -1)
                highDefinitionFieldNumber = 6;

            int closedCaptionsFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.ClosedCaptions);
            if (closedCaptionsFieldNumber == -1)
                closedCaptionsFieldNumber = 7;

            int parentalRatingFieldNumber = MHEGParserParameters.GetField(MHEGParserParameters.FieldName.ParentalRating);
            if (parentalRatingFieldNumber == -1)
                parentalRatingFieldNumber = 8;

            try
            {
                Collection<byte[]> records = Utils.SplitBytes(fileData, 0x1e);

                for (int index = 1; index < records.Count; index++)
                {
                    if (logger != null && RunParameters.Instance.TraceIDs.Contains("DSMCCRECORD"))
                        logger.Dump("DSMCC Parser data - Program Entry", records[index], records[index].Length);

                    Collection<byte[]> dataFields = Utils.SplitBytes(records[index], 0x1d);

                    if (dataFields[0].Length != 0)
                    {
                        try
                        {
                            EPGEntry epgEntry = new EPGEntry();
                            epgEntry.OriginalNetworkID = tvStation.OriginalNetworkID;
                            epgEntry.TransportStreamID = tvStation.TransportStreamID;
                            epgEntry.ServiceID = serviceID;

                            epgEntry.StartTime = Utils.RoundTime(date.AddSeconds(((double)Int32.Parse(Utils.GetAsciiString(dataFields[startTimeFieldNumber])))));
                            epgEntry.Duration = Utils.RoundTime(date.AddSeconds(((double)Int32.Parse(Utils.GetAsciiString(dataFields[endTimeFieldNumber])))) - epgEntry.StartTime);
                            string eventCRID = Utils.GetAsciiString(dataFields[eventCRIDFieldNumber]);
                            string seriesCRID = Utils.GetAsciiString(dataFields[seriesCRIDFieldNumber]);

                            byte[] editedEventName = replaceByte(dataFields[eventNameFieldNumber], 0x0d, 0x20);
                            string eventName = Utils.GetString(editedEventName, "utf-8");
                            epgEntry.EventName = Utils.Compact(eventName);

                            byte[] editedDescription = replaceByte(dataFields[shortDescriptionFieldNumber], 0x0d, 0x20);
                            string eventDescription = Utils.GetString(editedDescription, "utf-8");
                            processAUSShortDescription(epgEntry, Utils.Compact(eventDescription));

                            if (Int32.Parse(Utils.GetAsciiString(dataFields[highDefinitionFieldNumber])) == 1)
                            {
                                epgEntry.AspectRatio = "16:9";
                                epgEntry.VideoQuality = "HDTV";
                                epgEntry.AudioQuality = "dolby digital";
                            }

                            if (Int32.Parse(Utils.GetAsciiString(dataFields[closedCaptionsFieldNumber])) == 1)
                                epgEntry.SubTitles = "teletext";

                            string parentalRating = Utils.GetAsciiString(dataFields[parentalRatingFieldNumber]).Replace("(", "").Replace(")", "");
                            if (parentalRating.Length != 0)
                            {
                                epgEntry.ParentalRating = parentalRating;
                                epgEntry.MpaaParentalRating = ParentalRating.FindMpaaRating("AUS", "MHEG5", parentalRating);
                                epgEntry.ParentalRatingSystem = ParentalRating.FindSystem("AUS", "MHEG5", parentalRating);
                            }

                            processAUSCRID(epgEntry, seriesCRID, eventCRID);

                            epgEntry.EventCategory = CustomProgramCategory.FindCategoryDescription(epgEntry.EventName);
                            if (epgEntry.EventCategory == null)
                                epgEntry.EventCategory = CustomProgramCategory.FindCategoryDescription(epgEntry.ShortDescription);

                            tvStation.AddEPGEntry(epgEntry);

                            if (titleLogger != null)
                                logTitle(eventName, epgEntry, titleLogger);
                            if (descriptionLogger != null)
                                logDescription(eventDescription, epgEntry, descriptionLogger);
                        }
                        catch (ArithmeticException)
                        {
                            Logger.Instance.Dump("DSMCC Parser error - Arithmetic Exception - File Entry", fileData, fileData.Length);
                            if (logger != null)
                                logger.Dump("DSMCC Parser error - Arithmetic Exception - File Entry", fileData, fileData.Length);
                        }
                    }
                }
            }
            catch (ArithmeticException e)
            {
                throw (new ArgumentOutOfRangeException("DSMCC file entry parsing failed: " + e.Message));
            }
        }