/// <summary>
        /// Ermittelt den aktuellen Aufzeichnungsplan.
        /// </summary>
        /// <param name="scheduler">Die zu verwendende Zeitplanungsinstanz.</param>
        /// <param name="referenceTime">Der Bezugspunkt für die Planung.</param>
        /// <param name="disabled">Alle deaktivierte Aufträge und Aufgaben.</param>
        /// <param name="limit">Die Anzahl der zu berücksichtigenden Planungselemente.</param>
        /// <returns>Die Liste der nächsten Aufzeichnungen.</returns>
        private PlanContext GetPlan(RecordingScheduler scheduler, DateTime referenceTime, Func <Guid, bool> disabled, int limit)
        {
            // Create a new plan context
            var context = new PlanContext(m_started.Values);

            // Configure it
            m_site.AddRegularJobs(scheduler, disabled, this, context);

            // Enable all
            if (disabled == null)
            {
                disabled = identifier => false;
            }

            // Do the sort
            context.LoadPlan(scheduler.GetSchedules(referenceTime, m_tasks.Where(task => !disabled(task.UniqueIdentifier)).ToArray()).Take(limit));

            // Report
            return(context);
        }
        /// <summary>
        /// Ermittelt die nächste Aufgabe.
        /// </summary>
        /// <param name="referenceTime">Der Bezugspunkt für die Analyse.</param>
        public void DispatchNextActivity(DateTime referenceTime)
        {
            // As long as necessary
            for (var skipped = new HashSet <Guid>(); ;)
            {
                // The plan context we created
                PlanContext context = null;

                // Request activity - we only look 200 plan items into the future to reduce execution time at least a bit
                var activity = m_manager.GetNextActivity(referenceTime, (scheduler, time) => context = GetPlan(scheduler, time, skipped.Contains, 200));
                if (activity == null)
                {
                    return;
                }

                // The easiest case is a wait
                var wait = activity as WaitActivity;
                if (wait != null)
                {
                    // Report to site
                    m_site.Idle(wait.RetestTime);

                    // Done
                    return;
                }

                // Start processing
                var start = activity as StartActivity;
                if (start != null)
                {
                    // Check mode of operation
                    var schedule   = start.Recording;
                    var definition = schedule.Definition;
                    if (schedule.Resource == null)
                    {
                        // Report to site
                        m_site.Discard(definition);

                        // Add to exclusion list
                        skipped.Add(definition.UniqueIdentifier);

                        // Try again without
                        continue;
                    }

                    // Forward to site
                    m_site.Start(schedule, this, context);

                    // Done
                    return;
                }

                // End processing
                var stop = activity as StopActivity;
                if (stop != null)
                {
                    // Lookup the item and report to site
                    ScheduleInformation schedule;
                    if (!m_started.TryGetValue(stop.UniqueIdentifier, out schedule))
                    {
                        return;
                    }

                    // Report to site
                    m_site.Stop(schedule.Schedule, this);

                    // Done
                    return;
                }

                // Must be some wrong version
                throw new NotSupportedException(activity.GetType().AssemblyQualifiedName);
            }
        }