//<input aria-label="target">
 //*[(self::a or self::button or @role='button' or @role='link' or @role='menuitem' or self::input or self::textarea or self::select) and @aria-label='{target}']
 virtual protected Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > ByNested(string elementType) =>
 (target, prefixes, driver) => Permutate(prefixes, driver, (prefix) =>
                                         $"{prefix}//*[{elementType} and (" +
                                         $"{XpathProvider.TextMatch(target)} or " +
                                         $"label[{XpathProvider.TextMatch(target)}] or " +
                                         $"((@type='button' or @type='submit' or @type='reset') and @value={target.XpathEncode()}) or " +
                                         $"@name={target.XpathEncode()} or " +
                                         $"@aria-label={target.XpathEncode()} or " +
                                         $"(@type='radio' and @value={target.XpathEncode()})" +
                                         $")]");
 //<a href = "https://www.w3schools.com/html/" >target</a>
 //*[(self::a or self::button or @role='button' or @role='link' or @role='menuitem') and text()='{target}']
 virtual protected Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > ByText(string elementType) =>
 (target, prefixes, driver) => Permutate(prefixes, driver, (prefix) =>
                                         $"{prefix}//*[{elementType} and {XpathProvider.TextMatch(target)}]");
 //label[text()[normalize-space(.)='Bob']]/*[self::input]
 //<label>target<input type = "text" ></ label >
 //label[text()='{target}']/*[self::input or self::textarea or self::select]
 virtual protected Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > ByNestedInLabel(string elementType) =>
 (target, prefixes, driver) => Permutate(prefixes, driver, (prefix) =>
                                         $"{prefix}//*[(self::label or self::div) and {XpathProvider.TextMatch(target)}]/*[{elementType}]");
 //<label><span><strong>target</strong></span><input type = "text" ></ label >
 //*[text()='{target}']/ancestor::label//*[self::input or self::textarea or self::select]
 virtual protected Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > ByLabelAncestor(string elementType) =>
 (target, prefixes, driver) => Permutate(prefixes, driver, (prefix) =>
                                         $"{prefix}//*[{XpathProvider.MarkerElements} and {XpathProvider.TextMatch(target)}]/ancestor::label//*[{elementType}]");
        public SelectorFactory(ElementFactory elementFactory, XpathProvider xpathProvider)
        {
            ElementFactory = elementFactory;
            XpathProvider  = xpathProvider;

            Selectors = new Dictionary <string, List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > > >
            {
                {
                    SelectorNames.Settable,
                    new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > >
                    {
                        ByForAttribute,
                        ByNestedInLabel(XpathProvider.SettableElements),
                        ByNested(XpathProvider.SettableElements),
                        ByText(XpathProvider.SettableElements),
                        ByLabelledBy,
                        RadioByName,
                        ByFollowingMarker(XpathProvider.SettableElements),
                        ByCellBelow(XpathProvider.SettableElements),
                        ByLabelAncestor(XpathProvider.ActiveElements),
                    }
                },
                {
                    SelectorNames.Clickable,
                    new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > >
                    {
                        ByForAttribute,
                        ByNestedInLabel(XpathProvider.ClickableElements),
                        ByNested(XpathProvider.ClickableElements),
                        ByText(XpathProvider.ClickableElements),
                        ByTitle,
                        RadioByName,
                        SpecialButtons,
                        ByFollowingMarker(XpathProvider.ClickableElements),
                        ByCellBelow(XpathProvider.ClickableElements),
                        ByTypeAncestor(XpathProvider.ActiveElements),
                    }
                },
                {
                    SelectorNames.Active,
                    new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > >
                    {
                        ByForAttribute,
                        ByNestedInLabel(XpathProvider.ActiveElements),
                        ByNested(XpathProvider.ActiveElements),
                        ByText(XpathProvider.ActiveElements),
                        ByTitle,
                        ByLabelledBy,
                        RadioByName,
                        SpecialButtons,
                        ByFollowingMarker(XpathProvider.ActiveElements),
                        ByCellBelow(XpathProvider.ActiveElements),
                        ByLabelAncestor(XpathProvider.ActiveElements),
                        ByTypeAncestor(XpathProvider.ActiveElements),
                    }
                },
                {
                    SelectorNames.Content,
                    new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > >
                    {
                        ByContentSelf,
                        ByContentSelfForRow,
                        ByContent
                    }
                },
                {
                    SelectorNames.Selectable,
                    new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > >
                    {
                        ByForAttribute,
                        ByNestedInLabel(XpathProvider.SelectableElements),
                        ByNested(XpathProvider.SelectableElements),
                        ByText(XpathProvider.SelectableElements),
                        ByLabelledBy,
                        ByFollowingMarker(XpathProvider.SelectableElements),
                        ByCellBelow(XpathProvider.SelectableElements),
                    }
                },
                {
                    SelectorNames.Checkable,
                    new List <Func <string, IEnumerable <SelectorPrefix>, IWebDriver, IEnumerable <Element> > >
                    {
                        ByForAttribute,
                        ByNestedInLabel(XpathProvider.CheckableElements),
                        ByNested(XpathProvider.CheckableElements),
                        ByText(XpathProvider.CheckableElements),
                        ByLabelledBy,
                        ByFollowingMarker(XpathProvider.CheckableElements),
                        ByCellBelow(XpathProvider.CheckableElements),
                    }
                },
            };

            Prefixes = new Dictionary <string, List <Func <string, IEnumerable <string> > > >
            {
                {
                    PrefixNames.Row,
                    new List <Func <string, IEnumerable <string> > >
                    {
                        TableRow,
                        DivRoleRow,
                    }
                },
                {
                    PrefixNames.Under,
                    new List <Func <string, IEnumerable <string> > >
                    {
                        ParrentDiv,
                        ParrentDivWithRowRole,
                        FollowingRow,
                        Legend
                    }
                },
                { PrefixNames.Warning, new List <Func <string, IEnumerable <string> > > {
                  } },
                { PrefixNames.Error, new List <Func <string, IEnumerable <string> > > {
                  } }
            };
        }