/// <summary>
        /// Ermittelt die zu verwendende Größe für die Zwischenspeicherung beim Schreiben.
        /// </summary>
        /// <param name="type">Die Art des Bildsignals.</param>
        /// <returns>Die zu verwendende Speichergröße.</returns>
        public int? GetFileBufferSize( legacy.StreamTypes? type )
        {
            // Want audio
            if (!type.HasValue)
                return AudioFileBufferSize;

            // Check for supported types
            switch (type.Value)
            {
                case legacy.StreamTypes.Video13818: return SDTVFileBufferSize;
                case legacy.StreamTypes.H264: return HDTVFileBufferSize;
            }

            // We don't known
            return null;
        }
        /// <summary>
        /// Erzeugt die Beschreibung eines Eintrags aus der Programmzeitschrift.
        /// </summary>
        /// <remarks>Wird auf einem separaten <see cref="Thread"/> ausgeführt und
        /// muss alle Zugriff auf die statischen Daten geeignet synchronisieren.</remarks>
        /// <param name="source">Die Quelle, zu der die Information gehört.</param>
        /// <param name="identifier">Die eindeutige Kennung der Sendung.</param>
        /// <param name="startTime">Anfangszeitpunkt in UTC / GMT.</param>
        /// <param name="duration">Dauer der zugehörigen Sendung.</param>
        /// <param name="descriptors">Ergänzende Beschreibungen zur Sendung.</param>
        /// <returns>Die neu erzeugte Beschreibungsinstanz.</returns>
        private ProgramGuideItem CreateGuideItem( SourceIdentifier source, uint identifier, DateTime startTime, TimeSpan duration, legacy.Descriptor[] descriptors )
        {
            // Descriptors we can have
            legacy.Descriptors.ParentalRating rating = null;
            legacy.Descriptors.ShortEvent shortEvent = null;
            //

            // Collector
            var exEvents = new List<legacy.Descriptors.ExtendedEvent>();
            var categories = new HashSet<ContentCategory>();

            // Check all descriptors
            foreach (var descr in descriptors)
                if (descr.IsValid)
                {
                    // Check type
                    if (shortEvent == null)
                    {
                        // Read
                        shortEvent = descr as legacy.Descriptors.ShortEvent;

                        // Done for now
                        if (null != shortEvent)
                            continue;
                    }
                    if (rating == null)
                    {
                        // Read
                        rating = descr as legacy.Descriptors.ParentalRating;

                        // Done for now
                        if (null != rating)
                            continue;
                    }

                    // Event
                    var exEvent = descr as legacy.Descriptors.ExtendedEvent;
                    if (exEvent != null)
                    {
                        // Remember
                        exEvents.Add( exEvent );

                        // Next
                        continue;
                    }

                    // Check for content information
                    var content = descr as legacy.Descriptors.Content;
                    if (content != null)
                    {
                        // Process
                        if (content.Categories != null)
                            foreach (var singleCategory in content.Categories)
                                categories.Add( Event.GetContentCategory( singleCategory ) );

                        // Next
                        continue;
                    }
                }

            // Data
            string name = null, description = null, language = null, shortDescription = null;

            // Take the best we got
            if (exEvents.Count > 0)
            {
                // Text builder
                StringBuilder text = new StringBuilder();

                // Process all
                foreach (legacy.Descriptors.ExtendedEvent exEvent in exEvents)
                {
                    // Normal
                    if (null == name)
                        name = exEvent.Name;
                    if (null == language)
                        language = exEvent.Language;

                    // Merge
                    if (exEvent.Text != null)
                        text.Append( exEvent.Text );
                }

                // Use
                description = text.ToString();
            }

            // Try short event
            if (shortEvent != null)
            {
                // Remember
                if (string.IsNullOrEmpty( shortEvent.Name ))
                    shortDescription = shortEvent.Text;
                else if (string.IsNullOrEmpty( shortEvent.Text ))
                    shortDescription = shortEvent.Name;
                else if (string.IsNullOrEmpty( description ) || StringComparer.Ordinal.Equals( shortEvent.Text, description ))
                    shortDescription = shortEvent.Name;
                else
                    shortDescription = string.Format( "{0} ({1})", shortEvent.Name, shortEvent.Text );

                // Read
                if (string.IsNullOrEmpty( name ))
                    name = shortEvent.Name;
                if (string.IsNullOrEmpty( description ))
                    description = shortEvent.Text;
                if (string.IsNullOrEmpty( language ))
                    language = shortEvent.Language;
            }

            // Not possible
            if (string.IsNullOrEmpty( name ))
                return null;

            // Defaults
            if (shortDescription == null)
                shortDescription = string.Empty;

            // Defaults
            if (string.IsNullOrEmpty( description ))
                description = "-";
            if (null == language)
                language = string.Empty;

            // Create event
            return new ProgramGuideItem
            {
                Ratings = ((rating == null) ? null : rating.Ratings) ?? EmptyStringArray,
                Duration = (int) duration.TotalSeconds,
                ShortDescription = shortDescription,
                Content = categories.ToArray(),
                Description = description,
                Identifier = identifier,
                Language = language,
                Start = startTime,
                Source = source,
                Name = name
            };
        }
        /// <summary>
        /// Erzeugt die Beschreibung eines Eintrags aus der Programmzeitschrift und vermerkt diese
        /// in der Gesamtliste.
        /// </summary>
        /// <remarks>Wird auf einem separaten <see cref="Thread"/> ausgeführt und
        /// muss alle Zugriff auf die statischen Daten geeignet synchronisieren.</remarks>
        /// <param name="source">Die Quelle, zu der die Information gehört.</param>
        /// <param name="identifier">Die eindeutige Kennung der Sendung.</param>
        /// <param name="startTime">Anfangszeitpunkt in UTC / GMT.</param>
        /// <param name="duration">Dauer der zugehörigen Sendung.</param>
        /// <param name="descriptors">Ergänzende Beschreibungen zur Sendung.</param>
        /// <returns>Die neu erzeugte Beschreibungsinstanz.</returns>
        private void AddGuideItem( SourceIdentifier source, uint identifier, DateTime startTime, TimeSpan duration, legacy.Descriptor[] descriptors )
        {
            // First create it
            ProgramGuideItem info = CreateGuideItem( source, identifier, startTime, duration, descriptors );
            if (null == info)
                return;

            // Must synchronize
            lock (m_EPGItems)
            {
                // Attach to the source list
                Dictionary<DateTime, ProgramGuideItem> list;
                if (!m_EPGItems.TryGetValue( source, out list ))
                {
                    // Create new
                    list = new Dictionary<DateTime, ProgramGuideItem>();

                    // Add it
                    m_EPGItems[source] = list;
                }

                // Old count
                int before = list.Count;

                // Remember
                list[startTime] = info;

                // New count
                m_EPGItemCount += (list.Count - before);
            }
        }