private void ExecuteStep(StepArgs stepArgs)
        {
            HandleBlockSwitch(stepArgs.Type.ToScenarioBlock());

            testTracer.TraceStep(stepArgs, true);

            bool isStepSkipped = contextManager.ScenarioContext.TestStatus != TestStatus.OK;

            BindingMatch match = null;

            object[] arguments = null;
            try
            {
                match     = GetStepMatch(stepArgs);
                arguments = GetExecuteArguments(match);

                if (isStepSkipped)
                {
                    testTracer.TraceStepSkipped();
                }
                else
                {
                    OnStepStart();
                    TimeSpan duration = ExecuteStepMatch(match, arguments);
                    if (runtimeConfiguration.TraceSuccessfulSteps)
                    {
                        testTracer.TraceStepDone(match, arguments, duration);
                    }
                }
            }
            catch (PendingStepException)
            {
                Debug.Assert(match != null);
                Debug.Assert(arguments != null);

                testTracer.TraceStepPending(match, arguments);
                contextManager.ScenarioContext.PendingSteps.Add(
                    stepFormatter.GetMatchText(match, arguments));

                if (contextManager.ScenarioContext.TestStatus < TestStatus.StepDefinitionPending)
                {
                    contextManager.ScenarioContext.TestStatus = TestStatus.StepDefinitionPending;
                }
            }
            catch (MissingStepDefinitionException)
            {
                if (contextManager.ScenarioContext.TestStatus < TestStatus.MissingStepDefinition)
                {
                    contextManager.ScenarioContext.TestStatus = TestStatus.MissingStepDefinition;
                }
            }
            catch (BindingException ex)
            {
                testTracer.TraceBindingError(ex);
                if (contextManager.ScenarioContext.TestStatus < TestStatus.BindingError)
                {
                    contextManager.ScenarioContext.TestStatus = TestStatus.BindingError;
                    contextManager.ScenarioContext.TestError  = ex;
                }
            }
            catch (Exception ex)
            {
                testTracer.TraceError(ex);

                if (contextManager.ScenarioContext.TestStatus < TestStatus.TestError)
                {
                    contextManager.ScenarioContext.TestStatus = TestStatus.TestError;
                    contextManager.ScenarioContext.TestError  = ex;
                }
                if (runtimeConfiguration.StopAtFirstError)
                {
                    throw;
                }
            }
            finally
            {
                if (!isStepSkipped)
                {
                    OnStepEnd();
                }
            }
        }
        private void ExecuteStep(IContextManager contextManager, StepInstance stepInstance)
        {
            HandleBlockSwitch(stepInstance.StepDefinitionType.ToScenarioBlock());

            _testTracer.TraceStep(stepInstance, true);

            bool isStepSkipped       = contextManager.ScenarioContext.ScenarioExecutionStatus != ScenarioExecutionStatus.OK;
            bool onStepStartExecuted = false;

            BindingMatch match = null;

            object[] arguments = null;
            try
            {
                match = GetStepMatch(stepInstance);
                contextManager.StepContext.StepInfo.BindingMatch = match;
                contextManager.StepContext.StepInfo.StepInstance = stepInstance;
                arguments = GetExecuteArguments(match);

                if (isStepSkipped)
                {
                    OnSkipStep();
                }
                else
                {
                    _obsoleteStepHandler.Handle(match);

                    onStepStartExecuted = true;
                    OnStepStart();
                    TimeSpan duration = ExecuteStepMatch(match, arguments);
                    if (_specFlowConfiguration.TraceSuccessfulSteps)
                    {
                        _testTracer.TraceStepDone(match, arguments, duration);
                    }
                }
            }
            catch (PendingStepException)
            {
                Debug.Assert(match != null);
                Debug.Assert(arguments != null);

                _testTracer.TraceStepPending(match, arguments);
                contextManager.ScenarioContext.PendingSteps.Add(
                    _stepFormatter.GetMatchText(match, arguments));

                if (contextManager.ScenarioContext.ScenarioExecutionStatus < ScenarioExecutionStatus.StepDefinitionPending)
                {
                    contextManager.ScenarioContext.ScenarioExecutionStatus = ScenarioExecutionStatus.StepDefinitionPending;
                }
            }
            catch (MissingStepDefinitionException)
            {
                if (contextManager.ScenarioContext.ScenarioExecutionStatus < ScenarioExecutionStatus.UndefinedStep)
                {
                    contextManager.ScenarioContext.ScenarioExecutionStatus = ScenarioExecutionStatus.UndefinedStep;
                }
            }
            catch (BindingException ex)
            {
                _testTracer.TraceBindingError(ex);
                if (contextManager.ScenarioContext.ScenarioExecutionStatus < ScenarioExecutionStatus.BindingError)
                {
                    contextManager.ScenarioContext.ScenarioExecutionStatus = ScenarioExecutionStatus.BindingError;
                    contextManager.ScenarioContext.TestError = ex;
                }
            }
            catch (Exception ex)
            {
                _testTracer.TraceError(ex);

                if (contextManager.ScenarioContext.ScenarioExecutionStatus < ScenarioExecutionStatus.TestError)
                {
                    contextManager.ScenarioContext.ScenarioExecutionStatus = ScenarioExecutionStatus.TestError;
                    contextManager.ScenarioContext.TestError = ex;
                }

                if (_specFlowConfiguration.StopAtFirstError)
                {
                    throw;
                }
            }
            finally
            {
                if (onStepStartExecuted)
                {
                    OnStepEnd();
                }
            }
        }