void solver_OnSolutionStepCompleted(object sender, SolutionStepCompletedEventArgs e)
    {
      if (!e.Finished)
      {
        PictureBox currentStepImg = stepImgs[currentIndex];
        Label currentStep = stepLabels[currentIndex];
        if (currentStepImg.InvokeRequired) currentStepImg.Invoke((MethodInvoker)delegate() { currentStepImg.Image = Properties.Resources.ok; });
        if (currentStep.InvokeRequired) currentStep.Invoke((MethodInvoker)delegate() { currentStep.Text = e.Type == SolutionStepType.Standard ? string.Format("{0} moves", e.Algorithm.Moves.Count) : string.Empty; });
        currentIndex++;

        if (currentIndex < stepImgs.Count)
        {
          currentStepImg = stepImgs[currentIndex];
          currentStep = stepLabels[currentIndex];
          if (currentStepImg.InvokeRequired) currentStepImg.Invoke((MethodInvoker)delegate() { currentStepImg.Image = Properties.Resources.refresh; });
          if (currentStep.InvokeRequired) currentStep.Invoke((MethodInvoker)delegate() { currentStep.Text = "In progress ..."; });
        }
      }
      else
      {
        if (lblTimeHeader.InvokeRequired) lblTimeHeader.Invoke((MethodInvoker)delegate() { lblTime.Text = string.Format("{0:f2}s", e.Milliseconds / 1000.0); });
        if (lblMovesHeader.InvokeRequired) lblMovesHeader.Invoke((MethodInvoker)delegate() { lblMoves.Text = string.Format("{0} moves", e.Algorithm.Moves.Count); });
        if (lblHeader.InvokeRequired) lblHeader.Invoke((MethodInvoker)delegate() { lblHeader.Text = "Solution found."; });
        if (btnAdd.InvokeRequired) btnAdd.Invoke((MethodInvoker)delegate() { btnAdd.Enabled = true; });
        solver.OnSolutionStepCompleted -= solver_OnSolutionStepCompleted;
        this.Algorithm = e.Algorithm;
      }
    }
        private void solver_OnSolutionStepCompleted(object sender, SolutionStepCompletedEventArgs e)
        {
            if (!e.Finished)
            {
                var currentStepImg = this.stepImgs[this.currentIndex];
                var currentStep = this.stepLabels[this.currentIndex];
                if (currentStepImg.InvokeRequired)
                {
                    var img = currentStepImg;
                    currentStepImg.Invoke((MethodInvoker)delegate { img.Image = Properties.Resources.ok; });
                }
                if (currentStep.InvokeRequired)
                {
                    var step = currentStep;
                    currentStep.Invoke((MethodInvoker)delegate
                        {
                            step.Text = e.Type == SolutionStepType.Standard
                                                   ? $"{e.Algorithm.Moves.Count} moves"
                                                   : string.Empty;
                        });
                }
                this.currentIndex++;

                if (this.currentIndex >= this.stepImgs.Count)
                {
                    return;
                }
                currentStepImg = this.stepImgs[this.currentIndex];
                currentStep = this.stepLabels[this.currentIndex];
                if (currentStepImg.InvokeRequired) currentStepImg.Invoke((MethodInvoker)delegate { currentStepImg.Image = Properties.Resources.refresh; });
                if (currentStep.InvokeRequired) currentStep.Invoke((MethodInvoker)delegate { currentStep.Text = "In progress ..."; });
            }
            else
            {
                if (this.lblTimeHeader.InvokeRequired)
                    this.lblTimeHeader.Invoke((MethodInvoker)delegate
                        {
                            lblTime.Text = $"{e.Milliseconds / 1000.0:f2}s";
                        });
                if (this.lblMovesHeader.InvokeRequired)
                    this.lblMovesHeader.Invoke((MethodInvoker)delegate
                        {
                            lblMoves.Text = $"{e.Algorithm.Moves.Count} moves";
                        });
                if (this.lblHeader.InvokeRequired) this.lblHeader.Invoke((MethodInvoker)delegate { lblHeader.Text = "Solution found."; });
                if (this.btnAdd.InvokeRequired) this.btnAdd.Invoke((MethodInvoker)delegate { btnAdd.Enabled = true; });
                this.solver.OnSolutionStepCompleted -= this.solver_OnSolutionStepCompleted;
                this.Algorithm = e.Algorithm;
            }
        }