/// <summary>
        /// This is the Background worker which starts and controls the ScanMonitor.
        /// Does some UI things, also takes care of the ScanningDialog.
        /// This seems a doubling of the ScanMonitor's Watcher, but it is needed to keep the UI running independently.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void doThreadScan(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker bw     = (BackgroundWorker)sender;
            int    ScanCountSession = 0;
            double frac             = 100.0 / ((double)dorksToScan.Count);
            double realstat         = 0;

            using (ScanMonitor scanmonitor = new ScanMonitor(Properties.Settings.Default.MaxParallelScans))
            {
                foreach (SSelectedDork _dork in dorksToScan)
                {
                    ScanCountSession++;

                    if (scanningdialog != null)
                    {
                        scanningdialog.UpdateTitle(ScanCountSession);
                        Update();
                    }

                    DorkDone     dorkdone = CreateDorkForScanning(_dork);
                    ListViewItem lv       = ShowTemporaryDork(_dork);
                    lv.Tag            = dorkdone;
                    dorkdone.ViewItem = lv;
                    Update();

                    Scanner scanner = new Scanner(new ScanGoogleProvider(), dorkdone);

                    while (!scanmonitor.IsThreadAvail())
                    {
                        CheckAndDisplayResults(scanmonitor);
                        Thread.Sleep(300);
                    }

                    scanmonitor.Add(scanner);
                    Thread.Sleep(200);

                    CheckAndDisplayResults(scanmonitor);

                    if (scanningdialog != null)
                    {
                        realstat += frac / Properties.Settings.Default.RequestPages;
                        scanningdialog.SetPercentage((int)Math.Round(realstat));
                        Update();
                    }

                    if (bw.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }

                    int stealthtime = Properties.Settings.Default.StealthTime / 1000;

                    if (stealthtime > 0)
                    {
                        if (stealthtime > 3)
                        {
                            progressBar1.ForeColor = Color.DarkGray;
                        }

                        for (int i = 0; i < stealthtime; i++)
                        {
                            Thread.Sleep(1000);
                            if (bw.CancellationPending)
                            {
                                e.Cancel = true;
                                break;
                            }
                        }

                        if (stealthtime > 3)
                        {
                            progressBar1.ForeColor = Color.DarkBlue;
                        }
                    }

                    if (scanningdialog != null)
                    {
                        realstat = (frac * ScanCountSession);
                        scanningdialog.SetPercentage((int)Math.Round(realstat));
                        Update();
                    }

                    // be sure to cancel
                    if (e.Cancel == true)
                    {
                        break;
                    }
                } // foreach

                if (scanningdialog != null)
                {
                    if (scanmonitor.HasResults() || scanmonitor.HasPendingScans())
                    {
                        scanningdialog.UpdateTitleWaiting();
                    }
                }

                while (scanmonitor.HasResults() ||
                       (!e.Cancel && scanmonitor.HasPendingScans())
                       )
                {
                    CheckAndDisplayResults(scanmonitor);
                    Thread.Sleep(200);
                }
            }
        }
        /// <summary>
        /// This is one of the hearts of gS.
        /// Like it is named, it checks the results and with them controls
        /// the outer interface of the ScanMonitor. It's somehow a respectful
        /// connection between the UI and the parallel scanner in the backend.
        /// </summary>
        /// <param name="scanmonitor">Instance of ScanMonitor while scanning.</param>
        private void CheckAndDisplayResults(ScanMonitor scanmonitor)
        {
            if (scanmonitor.HasResults())
            {
                Scanner  scanner  = scanmonitor.GetFinishedScanner();
                DorkDone dorkdone = scanner.ResultDork;
                if (dorkdone == null)
                {
                    return;
                }

                if (dorkdone.ScanResult == (int)RESULT_STATUS.Cancel)
                {
                    Trace.WriteLineIf(Debug.Trace.TraceGoolag.TraceInfo, "Scan was canceled.");
                    dorkdone.ViewItem.ImageIndex       = (int)RESULT_STATUS.Cancel;
                    dorkdone.ViewItem.SubItems[0].Text = rm.GetString("RES_CANCELSCAN");
                    dorkdone.ViewItem.SubItems[2].Text = "";
                    return;
                }
                if (dorkdone.ScanResult == (int)RESULT_STATUS.Nothing)
                {
                    Trace.WriteLineIf(Debug.Trace.TraceGoolag.TraceInfo, "Scan returned no results.");
                    dorkdone.ViewItem.ImageIndex       = (int)RESULT_STATUS.Nothing;
                    dorkdone.ViewItem.SubItems[0].Text = rm.GetString("RES_NORESULT");
                    dorkdone.ViewItem.SubItems[2].Text = "";
                    summaryStat.ScansNoResult++;
                    return;
                }
                if (dorkdone.ScanResult == (int)RESULT_STATUS.Failure)
                {
                    dorkdone.ViewItem.ImageIndex       = (int)RESULT_STATUS.Failure;
                    dorkdone.ViewItem.SubItems[0].Text = rm.GetString("RES_FAILED");
                    dorkdone.ViewItem.SubItems[2].Text = "";
                    summaryStat.ScansFailed++;
                    Trace.WriteLineIf(Debug.Trace.TraceGoolag.TraceInfo, "Scan failed.");
                    return;
                }
                if (dorkdone.ScanResult == (int)RESULT_STATUS.Blocked)
                {
                    dorkdone.ViewItem.ImageIndex       = (int)RESULT_STATUS.Blocked;
                    dorkdone.ViewItem.SubItems[0].Text = rm.GetString("RES_BLOCKED");
                    dorkdone.ViewItem.SubItems[2].Text = dorkdone.ResultURL;
                    summaryStat.ScansFailed++;
                    Trace.WriteLineIf(Debug.Trace.TraceGoolag.TraceInfo, "Scan was blocked.");

                    if (Properties.Settings.Default.BlockDetectMode == (int)BLOCKING_MODE.SingleAndStop)
                    {
                        int stoppedscans = scanmonitor.StopAllActive();
                        Trace.WriteLineIf(Debug.Trace.TraceGoolag.TraceVerbose, stoppedscans, "Scans canceled in queue");

                        while (scanmonitor.HasPendingScans())
                        {
                            Thread.Sleep(200);
                        }
                    }

                    if (Properties.Settings.Default.BlockDetectMode != (int)BLOCKING_MODE.Ignore)
                    {
                        ShowScanningDialog(false);

                        DialogResult dr = MessageBox.Show("Start browser to unlock block? Cancel will stop scanning.", "Block detected!", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Stop);

                        if (dr == DialogResult.Yes)
                        {
                            OSUtils.OpenInBrowser(dorkdone.ResultURL);
                            MessageBox.Show("Ready to resume?", "Resume scanning.", MessageBoxButtons.OK, MessageBoxIcon.Question);
                        }
                        else if (dr == DialogResult.Cancel)
                        {
                            int stoppedscans = scanmonitor.StopAllActive();
                            Trace.WriteLineIf(Debug.Trace.TraceGoolag.TraceVerbose, stoppedscans, "Scans canceled in queue");

                            while (scanmonitor.HasPendingScans())
                            {
                                Thread.Sleep(100);
                            }
                            StopScanning();
                        }

                        ShowScanningDialog(true);
                    }

                    return;
                }
                if (dorkdone.ScanResult == (int)RESULT_STATUS.ScanWithResult)
                {
                    resultListView.Items.Remove(dorkdone.ViewItem); // remove the one that is displayed while scanning

                    if (scanner.Count > 0)
                    {
                        int      lastIdx    = 0;
                        DorkDone resDork    = scanner.ResultDork;
                        DorkDone followDork = null;

                        if (resDork.NextPage != 0)
                        {
                            if ((resDork.NextPage / 10) < Properties.Settings.Default.RequestPages)
                            {
                                followDork            = new DorkDone();
                                followDork            = (DorkDone)resDork.Clone();
                                followDork.ScanResult = (int)RESULT_STATUS.WhileScan;
                                Scanner nextscanner = new Scanner(new ScanGoogleProvider(), followDork);

                                while (!scanmonitor.IsThreadAvail())
                                {
                                    Thread.Sleep(300);
                                }

                                scanmonitor.Add(nextscanner);
                                Thread.Sleep(100);
                            }
                        }

                        do
                        {
                            ListViewItem lv1 = resultListView.Items.Add(rm.GetString("RES_SUCCESS"),
                                                                        (int)RESULT_STATUS.ScanWithResult);

                            lv1.SubItems.Add(resDork.Title);
                            lv1.SubItems.Add(resDork.ResultURL);
                            lastIdx = lv1.Index;
                            lv1.Tag = resDork;

                            summaryStat.ScansSuccess++;
                            resDork = resDork.Next;

                            resultListView.EnsureVisible(lastIdx);
                        } while (resDork != null);
                    }
                }
            }
        }