public IEnumerable <StepDefinitionUsage> FindUsagesFromContent(ProjectStepDefinitionBinding[] stepDefinitions,
                                                                       string featureFileContent, string featureFilePath, DeveroomConfiguration configuration)
        {
            var dialectProvider = SpecFlowGherkinDialectProvider.Get(configuration.DefaultFeatureLanguage);
            var parser          = new DeveroomGherkinParser(dialectProvider, _monitoringService);

            parser.ParseAndCollectErrors(featureFileContent, _logger,
                                         out var gherkinDocument, out _);

            var featureNode = gherkinDocument?.Feature;

            if (featureNode == null)
            {
                yield break;
            }

            var dummyRegistry = new ProjectBindingRegistry
            {
                StepDefinitions = stepDefinitions
            };

            var featureContext = new UsageFinderContext(featureNode);

            foreach (var scenarioDefinition in featureNode.FlattenStepsContainers())
            {
                var context = new UsageFinderContext(scenarioDefinition, featureContext);
                foreach (var step in scenarioDefinition.Steps)
                {
                    var matchResult = dummyRegistry.MatchStep(step, context);
                    if (matchResult == null)
                    {
                        continue; // this will not happen
                    }
                    if (matchResult.HasDefined)
                    {
                        yield return(new StepDefinitionUsage(
                                         GetSourceLocation(step, featureFilePath), step));
                    }
                }
            }
        }
        private DeveroomTag GetFeatureTags(ITextSnapshot fileSnapshot, ProjectBindingRegistry bindingRegistry, Feature feature)
        {
            var featureTag = CreateDefinitionBlockTag(feature, DeveroomTagTypes.FeatureBlock, fileSnapshot,
                                                      fileSnapshot.LineCount);

            foreach (var scenarioDefinition in feature.StepsContainers())
            {
                var scenarioDefinitionTag = CreateDefinitionBlockTag(scenarioDefinition,
                                                                     DeveroomTagTypes.ScenarioDefinitionBlock, fileSnapshot,
                                                                     GetScenarioDefinitionLastLine(scenarioDefinition), featureTag);

                foreach (var step in scenarioDefinition.Steps)
                {
                    var stepTag = scenarioDefinitionTag.AddChild(new DeveroomTag(DeveroomTagTypes.StepBlock,
                                                                                 GetBlockSpan(fileSnapshot, step.Location, GetStepLastLine(step)), step));

                    stepTag.AddChild(
                        new DeveroomTag(DeveroomTagTypes.StepKeyword,
                                        GetTextSpan(fileSnapshot, step.Location, step.Keyword),
                                        step.Keyword));

                    if (step.Argument is DataTable dataTable)
                    {
                        var dataTableBlockTag = new DeveroomTag(DeveroomTagTypes.DataTable,
                                                                GetBlockSpan(fileSnapshot, dataTable.Rows.First().Location,
                                                                             dataTable.Rows.Last().Location.Line),
                                                                dataTable);
                        stepTag.AddChild(dataTableBlockTag);
                        var dataTableHeader = dataTable.Rows.FirstOrDefault();
                        if (dataTableHeader != null)
                        {
                            TagRowCells(fileSnapshot, dataTableHeader, dataTableBlockTag, DeveroomTagTypes.DataTableHeader);
                        }
                    }
                    else if (step.Argument is DocString docString)
                    {
                        stepTag.AddChild(
                            new DeveroomTag(DeveroomTagTypes.DocString,
                                            GetBlockSpan(fileSnapshot, docString.Location,
                                                         GetStepLastLine(step)),
                                            docString));
                    }

                    if (scenarioDefinition is ScenarioOutline)
                    {
                        AddPlaceholderTags(fileSnapshot, stepTag, step);
                    }

                    var match = bindingRegistry?.MatchStep(step, scenarioDefinitionTag);
                    if (match != null)
                    {
                        if (match.HasDefined || match.HasAmbiguous)
                        {
                            stepTag.AddChild(new DeveroomTag(DeveroomTagTypes.DefinedStep,
                                                             GetTextSpan(fileSnapshot, step.Location, step.Text, offset: step.Keyword.Length),
                                                             match));
                            if (!(scenarioDefinition is ScenarioOutline) || !step.Text.Contains("<"))
                            {
                                var parameterMatch = match.Items.FirstOrDefault(m => m.ParameterMatch != null)
                                                     ?.ParameterMatch;
                                AddParameterTags(fileSnapshot, parameterMatch, stepTag, step);
                            }
                        }

                        if (match.HasUndefined)
                        {
                            stepTag.AddChild(new DeveroomTag(DeveroomTagTypes.UndefinedStep,
                                                             GetTextSpan(fileSnapshot, step.Location, step.Text, offset: step.Keyword.Length),
                                                             match));
                        }

                        if (match.HasErrors)
                        {
                            stepTag.AddChild(new DeveroomTag(DeveroomTagTypes.BindingError,
                                                             GetTextSpan(fileSnapshot, step.Location, step.Text, offset: step.Keyword.Length),
                                                             match.GetErrorMessage()));
                        }
                    }
                }

                if (scenarioDefinition is ScenarioOutline scenarioOutline)
                {
                    foreach (var scenarioOutlineExample in scenarioOutline.Examples)
                    {
                        var examplesBlockTag = CreateDefinitionBlockTag(scenarioOutlineExample,
                                                                        DeveroomTagTypes.ExamplesBlock, fileSnapshot,
                                                                        GetExamplesLastLine(scenarioOutlineExample), scenarioDefinitionTag);
                        if (scenarioOutlineExample.TableHeader != null)
                        {
                            TagRowCells(fileSnapshot, scenarioOutlineExample.TableHeader, examplesBlockTag, DeveroomTagTypes.ScenarioOutlinePlaceholder);
                        }
                    }
                }
            }

            return(featureTag);
        }