/// <summary>
        /// 合并两个关系选择器
        /// </summary>
        /// <param name="left">左关系选择器</param>
        /// <param name="right">右关系选择器</param>
        /// <returns>合并后的关系选择器</returns>
        public static CssRelativeSelector Combine( CssRelativeSelector left, CssRelativeSelector right )
        {
            if ( left == null )
            throw new ArgumentNullException( "left" );

              if ( right == null )
            throw new ArgumentNullException( "right" );

              var selector = right.LeftSelector;
              var combinator = right.Combinator;

              var casecadingSelector = selector as CssCasecadingSelector;
              if ( casecadingSelector != null )                                                                        //如果右边关系选择器的左选择器是一个层叠选择器
            return CreateRelativeSelector( CssCasecadingSelector.Combine( left, casecadingSelector ), combinator );//将层叠选择器与左边的关系选择器合并,得到一个新的层叠选择器,再根据结合符创建新的关系选择器。

              /*
               * 举例说明如下:
               * 假设左关系选择器是 p>,右关系选择器是 div>ul>li+
               * 则右关系选择器的左选择器(selector)是div>ul>li,结合符(combinator)是+。
               * 将selector与左边的关系选择器合并,得到:p>div>ul>li,再与结合符结合得到新的关系选择器:p>div>ul>li+
               */

              var elementSelector = selector as CssElementSelector;
              if ( elementSelector != null )
            return CreateRelativeSelector( new CssCasecadingSelector( left, elementSelector ), combinator );

              throw new NotSupportedException();
        }
        /// <summary>
        /// 创建 CSS 层叠选择器对象
        /// </summary>
        /// <param name="relativeSelector">关系选择器</param>
        /// <param name="lastSelector">附加的最后一个选择器</param>
        public CssCasecadingSelector( CssRelativeSelector relativeSelector, ISelector lastSelector )
        {
            if ( relativeSelector == null )
            throw new ArgumentNullException( "relativeSelector" );

              if ( lastSelector == null )
            throw new ArgumentNullException( "lastSelector" );

              RelativeSelector = relativeSelector;
              LastSelector = lastSelector;
        }
        /// <summary>
        /// 创建 CSS 层叠选择器对象
        /// </summary>
        /// <param name="relativeSelector">关系选择器</param>
        /// <param name="lastSelector">附加的最后一个选择器</param>
        public CssCasecadingSelector(CssRelativeSelector relativeSelector, ISelector lastSelector)
        {
            if (relativeSelector == null)
            {
                throw new ArgumentNullException("relativeSelector");
            }

            if (lastSelector == null)
            {
                throw new ArgumentNullException("lastSelector");
            }


            RelativeSelector = relativeSelector;
            LastSelector     = lastSelector;
        }
        /// <summary>
        /// 合并两个关系选择器
        /// </summary>
        /// <param name="left">左关系选择器</param>
        /// <param name="right">右关系选择器</param>
        /// <returns>合并后的关系选择器</returns>
        public static CssRelativeSelector Combine(CssRelativeSelector left, CssRelativeSelector right)
        {
            if (left == null)
            {
                throw new ArgumentNullException("left");
            }

            if (right == null)
            {
                throw new ArgumentNullException("right");
            }


            var selector   = right.LeftSelector;
            var combinator = right.Combinator;


            var casecadingSelector = selector as CssCasecadingSelector;

            if (casecadingSelector != null)                                                                          //如果右边关系选择器的左选择器是一个层叠选择器
            {
                return(CreateRelativeSelector(CssCasecadingSelector.Combine(left, casecadingSelector), combinator)); //将层叠选择器与左边的关系选择器合并,得到一个新的层叠选择器,再根据结合符创建新的关系选择器。
            }

            /*
             * 举例说明如下:
             * 假设左关系选择器是 p>,右关系选择器是 div>ul>li+
             * 则右关系选择器的左选择器(selector)是div>ul>li,结合符(combinator)是+。
             * 将selector与左边的关系选择器合并,得到:p>div>ul>li,再与结合符结合得到新的关系选择器:p>div>ul>li+
             */

            var elementSelector = selector as CssElementSelector;

            if (elementSelector != null)
            {
                return(CreateRelativeSelector(new CssCasecadingSelector(left, elementSelector), combinator));
            }


            throw new NotSupportedException();
        }
        /// <summary>
        /// 创建层叠选择器
        /// </summary>
        /// <param name="relativeSelector">前置关系选择器</param>
        /// <param name="selector">右选择器</param>
        /// <returns></returns>
        public static ISelector Create(CssRelativeSelector relativeSelector, ISelector selector)
        {
            if (relativeSelector == null)
            {
                throw new ArgumentNullException("relativeSelector");
            }

            if (selector == null)
            {
                throw new ArgumentNullException("selector");
            }


            var elementSelector = selector as CssElementSelector;

            if (elementSelector != null)
            {
                return(new CssCasecadingSelector(relativeSelector, elementSelector));
            }

            var casecadingSelector = selector as CssCasecadingSelector;

            if (casecadingSelector != null)
            {
                return(Combine(relativeSelector, casecadingSelector));
            }

            var multipleSelector = selector as CssMultipleSelector;

            if (multipleSelector != null)
            {
                return(CssMultipleSelector.Combine(relativeSelector, multipleSelector));
            }


            throw new NotSupportedException();
        }
 /// <summary>
 /// 合并关系选择器和层叠选择器
 /// </summary>
 /// <param name="relativeSelector">关系选择器</param>
 /// <param name="selector">层叠选择器</param>
 /// <returns></returns>
 internal static CssCasecadingSelector Combine(CssRelativeSelector relativeSelector, CssCasecadingSelector selector)
 {
     relativeSelector = Combine(relativeSelector, selector.RelativeSelector);
     return(new CssCasecadingSelector(relativeSelector, selector.LastSelector));
 }
 public static ISelector Combine( CssRelativeSelector relativeSelector, CssMultipleSelector multipleSelector )
 {
     return new CssMultipleSelector( multipleSelector._selectors.Select( selector => CssCasecadingSelector.Create( relativeSelector, selector ) ).ToArray() );
 }
 public static ISelector Combine(CssRelativeSelector relativeSelector, CssMultipleSelector multipleSelector)
 {
     return(new CssMultipleSelector(multipleSelector._selectors.Select(selector => CssCasecadingSelector.Create(relativeSelector, selector)).ToArray()));
 }
 /// <summary>
 /// 合并关系选择器和层叠选择器
 /// </summary>
 /// <param name="relativeSelector">关系选择器</param>
 /// <param name="selector">层叠选择器</param>
 /// <returns></returns>
 internal static CssCasecadingSelector Combine( CssRelativeSelector relativeSelector, CssCasecadingSelector selector )
 {
     relativeSelector = Combine( relativeSelector, selector.RelativeSelector );
       return new CssCasecadingSelector( relativeSelector, selector.LastSelector );
 }
        /// <summary>
        /// 创建层叠选择器
        /// </summary>
        /// <param name="relativeSelector">前置关系选择器</param>
        /// <param name="selector">右选择器</param>
        /// <returns></returns>
        public static ISelector Create( CssRelativeSelector relativeSelector, ISelector selector )
        {
            if ( relativeSelector == null )
            throw new ArgumentNullException( "relativeSelector" );

              if ( selector == null )
            throw new ArgumentNullException( "selector" );

              var elementSelector = selector as CssElementSelector;
              if ( elementSelector != null )
            return new CssCasecadingSelector( relativeSelector, elementSelector );

              var casecadingSelector = selector as CssCasecadingSelector;
              if ( casecadingSelector != null )
            return Combine( relativeSelector, casecadingSelector );

              var multipleSelector = selector as CssMultipleSelector;
              if ( multipleSelector != null )
            return CssMultipleSelector.Combine( relativeSelector, multipleSelector );

              throw new NotSupportedException();
        }