/// <summary>
        /// Creates a new task schedule instance.
        /// </summary>
        /// <param name="task">The task.</param>
        /// <param name="type">The schedule type.</param>
        /// <param name="startTime">The start time.</param>
        public CrawlerSchedule(CrawlerTask task, ScheduleType type, DateTime startTime)
        {
            // The identifier.
            this.Id = Guid.NewGuid();

            // The task.
            this.task = task;

            // The schedule type.
            this.type = type;

            // The start time.
            this.startTime = startTime;
            this.useUniversalStartTime = false;

            // Task enabled.
            this.enabled = true;

            // Settings.
            this.delayEnabled = false;
            this.delayMaximumInterval = TimeSpan.FromHours(1.0);
            this.repeatEnabled = false;
            this.repeatInterval = TimeSpan.FromHours(1.0);
            this.repeatDuration = TimeSpan.FromDays(1.0);
            this.stopAfterRepeatEnabled = false;
            this.stopEnabled = false;
            this.stopInterval = TimeSpan.FromDays(3.0);
            this.expiresEnabled = false;
            this.expiresTime = startTime.AddYears(1);

            // Create the triggers.
        }
        /// <summary>
        /// Adds a task to the tasks list.
        /// </summary>
        /// <param name="task"></param>
        public void AddTask(CrawlerTask task)
        {
            // Validate the argument.
            if (null == task) throw new ArgumentNullException("task");

            // Check the task is in the stopped state.
            if (task.State != CrawlerTask.TaskState.Stopped) throw new CrawlerException("Cannot add the task because the it is not in the stopped state.");

            // Synchronize access.
            lock (this.sync)
            {
                // Check the task does not exist.
                if (this.tasks.ContainsKey(task.Id)) throw new CrawlerException("Cannot add task because a task with the identifier {0} already exists.".FormatWith(task.Id));

                // Add the task to the tasks list.
                this.tasks.Add(task.Id, task);

                // Add the task event handlers.
                task.ScheduleAdded += this.OnTaskScheduleAdded;
                task.ScheduleRemoved += this.OnTaskScheduleRemoved;
            }

            // Raise the event.
            if (null != this.TaskAdded) this.TaskAdded(this, new CrawlerTaskEventArgs(task));
        }
 /// <summary>
 /// Creates a new event arguments instance.
 /// </summary>
 /// <param name="task">The crawler task.</param>
 public CrawlerTaskEventArgs(CrawlerTask task)
 {
     this.Task = task;
 }
        /// <summary>
        /// Removes the task from the tasks list asynchronously.
        /// </summary>
        /// <param name="task">The task.</param>
        /// <param name="callback">A method called when the removal has completed.</param>
        public void RemoveTask(CrawlerTask task, CrawlerTaskCallback callback)
        {
            // Validate the arguments.
            if (null != task) throw new ArgumentNullException("task");
            if (null != callback) throw new ArgumentNullException("callback");

            // Call the remove task handler on the thread pool.
            ThreadPool.QueueUserWorkItem((object state) =>
            {
                try
                {
                    // Call the remove the task handler.
                    this.RemoveTask(task);
                }
                catch { } // Catch all exceptions
                finally
                {
                    // Execute the callback method.
                    callback(task);
                }
            });
        }
        /// <summary>
        /// Removes a task from the tasks list.
        /// </summary>
        /// <param name="task">The task.</param>
        public void RemoveTask(CrawlerTask task)
        {
            // Validate the argument.
            if (null == task) throw new ArgumentNullException("task");

            // Cancel the task execution.
        }