/// <summary>
        /// An event handler called when the user removes a slice from nodes.
        /// </summary>
        /// <param name="sender">The sender object.</param>
        /// <param name="e">The event arguments.</param>
        private void OnRemoveFromNodes(object sender, EventArgs e)
        {
            // If there is no validated PlanetLab person account, show a message and return.
            if (-1 == CrawlerConfig.Static.PlanetLabPersonId)
            {
                MessageBox.Show(this, "You must set and validate a PlanetLab account in the settings page before configuring the PlanetLab slices.", "PlanetLab Account Not Configured", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // If there is no selected slice, do nothing.
            if (this.listViewSlices.SelectedItems.Count == 0) return;

            // Get the slice.
            SliceInfo info = (SliceInfo)this.listViewSlices.SelectedItems[0].Tag;

            // If the slice does not have an ID, show an error message and return.
            if (!info.Slice.Id.HasValue)
            {
                MessageBox.Show(this, "The selected slice does not have an identifier.", "Remove Slice to Nodes", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Show the remove slice from node dialog.
            if (this.formRemoveSliceFromNodes.ShowDialog(this, info.Slice) == DialogResult.OK)
            {
                // Get the PlanetLab node IDs.
                int[] ids = this.formRemoveSliceFromNodes.Result;

                // Update the status.
                this.status.Send(
                    ApplicationStatus.StatusType.Busy,
                    "Showing {0} PlanetLab slices.".FormatWith(this.crawler.PlanetLab.LocalSlices.Count),
                    "Removing slice {0} from {1} PlanetLab node{2}...".FormatWith(info.Slice.Id, ids.Length, ids.Length.PluralSuffix()),
                    Resources.GlobeLab_16,
                    Resources.GlobeClock_16);
                // Log
                this.controlLog.Add(this.crawler.Log.Add(
                    LogEventLevel.Verbose,
                    LogEventType.Information,
                    ControlSlices.logSource,
                    "Removing slice {0} from {1} PlanetLab node{2}.",
                    new object[] { info.Slice.Id, ids.Length, ids.Length.PluralSuffix() }));

                // Create the request state.
                SliceIdsRequestState requestState = new SliceIdsRequestState(
                    this.OnRemoveSliceFromNodesRequestStarted,
                    this.OnRemoveSliceFromNodesRequestResult,
                    this.OnRemoveSliceFromNodesRequestCanceled,
                    this.OnRemoveSliceFromNodesRequestException,
                    this.OnRemoveSliceFromNodesRequestFinished,
                    info.Slice,
                    ids);

                // Begin an asynchronous PlanetLab request.
                this.BeginRequest(
                    this.requestRemoveSliceFromNodes,
                    this.crawler.PlanetLab.Username,
                    this.crawler.PlanetLab.Password,
                    new object[] { info.Slice.Id.Value, ids },
                    requestState);
            }
        }
        /// <summary>
        /// An event handler called when adding a slice to PlanetLab nodes.
        /// </summary>
        /// <param name="slice">The slice.</param>
        /// <param name="ids">The list of node IDs.</param>
        private void OnAddSliceToNodes(PlSlice slice, int[] ids)
        {
            // If the slice does not have an ID, show an error message and return.
            if (!slice.Id.HasValue)
            {
                MessageBox.Show(this, "The selected slice does not have an identifier.", "Add Slice to Nodes", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Update the status.
            this.status.Send(
                ApplicationStatus.StatusType.Busy,
                "Showing {0} PlanetLab slices.".FormatWith(this.crawler.PlanetLab.LocalSlices.Count),
                "Adding slice {0} to {1} PlanetLab node{2}...".FormatWith(slice.Id, ids.Length, ids.Length.PluralSuffix()),
                Resources.GlobeLab_16,
                Resources.GlobeClock_16);

            // Log
            this.controlLog.Add(this.crawler.Log.Add(
                LogEventLevel.Verbose,
                LogEventType.Information,
                ControlSlices.logSource,
                "Adding slice {0} to {1} PlanetLab node{2}.",
                new object[] { slice.Id, ids.Length, ids.Length.PluralSuffix() }));

            // Create the request state.
            SliceIdsRequestState requestState = new SliceIdsRequestState(
                this.OnAddSliceToNodesRequestStarted,
                this.OnAddSliceToNodesRequestResult,
                this.OnAddSliceToNodesRequestCanceled,
                this.OnAddSliceToNodesRequestException,
                this.OnAddSliceToNodesRequestFinished,
                slice,
                ids);

            // Begin an asynchronous PlanetLab request.
            this.BeginRequest(
                this.requestAddSliceToNodes,
                this.crawler.PlanetLab.Username,
                this.crawler.PlanetLab.Password,
                new object[] { slice.Id.Value, ids },
                requestState);
        }