private static XmlNodeList SelectAllAttributes(XmlNode parentNode)
        {
            XmlAttributeCollection attributes = parentNode.Attributes;

            if (attributes.Count == 0)
            {
                OnNoMatchingNode("@*");
                return(null);
            }
            else if (attributes.Count == 1)
            {
                XmlPatchNodeList nodeList = new SingleNodeList();
                nodeList.AddNode(attributes.Item(0));
                return(nodeList);
            }
            else
            {
                IEnumerator      enumerator = attributes.GetEnumerator();
                XmlPatchNodeList nodeList   = new MultiNodeList();
                while (enumerator.MoveNext())
                {
                    nodeList.AddNode((XmlNode)enumerator.Current);
                }
                return(nodeList);
            }
        }
        private static XmlNodeList SelectAllChildren(XmlNode parentNode)
        {
            XmlNodeList children = parentNode.ChildNodes;

            if (children.Count == 0)
            {
                OnNoMatchingNode("*");
                return(null);
            }
            else if (children.Count == 1)
            {
                XmlPatchNodeList nodeList = new SingleNodeList();
                nodeList.AddNode(children.Item(0));
                return(nodeList);
            }
            else
            {
                IEnumerator      enumerator = children.GetEnumerator();
                XmlPatchNodeList nodeList   = new MultiNodeList();
                while (enumerator.MoveNext())
                {
                    nodeList.AddNode((XmlNode)enumerator.Current);
                }
                return(nodeList);
            }
        }
        private static XmlNodeList SelectAbsoluteNodes( XmlNode rootNode, string path )
        {
            Debug.Assert( path[0] == '/' );
            
            int pos = 1;
            XmlNode node = rootNode;

            for (;;)
            {
                int startPos = pos;
                XmlNodeList childNodes = node.ChildNodes;

                int nodePos = ReadPosition( path, ref pos );
                
                if ( pos == path.Length || path[pos] == '/' ) {
                    if ( childNodes.Count == 0 || nodePos < 0 || nodePos > childNodes.Count )
                        OnNoMatchingNode( path );

                    node = childNodes.Item( nodePos - 1 );

                    if ( pos == path.Length ) {
                        XmlPatchNodeList list = new SingleNodeList();
                        list.AddNode( node );
                        return list;
                    }
                    pos++;
                }
                else {
                    if ( path[pos] == '-' || path[pos] == '|' ) {
                        return SelectChildNodes( node, path, startPos );
                    }
                    OnInvalidExpression( path );
                }
            }
        }
        private static XmlNodeList SelectAbsoluteNodes(XmlNode rootNode, string path)
        {
            Debug.Assert(path[0] == '/');

            int     pos  = 1;
            XmlNode node = rootNode;

            for (;;)
            {
                int         startPos   = pos;
                XmlNodeList childNodes = node.ChildNodes;

                int nodePos = ReadPosition(path, ref pos);

                if (pos == path.Length || path[pos] == '/')
                {
                    if (childNodes.Count == 0 || nodePos < 0 || nodePos > childNodes.Count)
                    {
                        OnNoMatchingNode(path);
                    }

                    node = childNodes.Item(nodePos - 1);

                    if (pos == path.Length)
                    {
                        XmlPatchNodeList list = new SingleNodeList();
                        list.AddNode(node);
                        return(list);
                    }
                    pos++;
                }
                else
                {
                    if (path[pos] == '-' || path[pos] == '|')
                    {
                        return(SelectChildNodes(node, path, startPos));
                    }
                    OnInvalidExpression(path);
                }
            }
        }
        private static XmlNodeList SelectAllChildren( XmlNode parentNode )
        {
            XmlNodeList children = parentNode.ChildNodes;

            if ( children.Count == 0 )
            {
                OnNoMatchingNode( "*" );
                return null;
            }
            else if ( children.Count == 1 )
            {
                XmlPatchNodeList nodeList = new SingleNodeList();
                nodeList.AddNode( children.Item( 0 ) );
                return nodeList;
            }
            else
            {
                IEnumerator enumerator = children.GetEnumerator();
                XmlPatchNodeList nodeList = new MultiNodeList();
                while ( enumerator.MoveNext() )
                    nodeList.AddNode( (XmlNode) enumerator.Current );
                return nodeList;
            }
        }
        private static XmlNodeList SelectAllAttributes( XmlNode parentNode )
        {
            XmlAttributeCollection attributes = parentNode.Attributes;

            if ( attributes.Count == 0 )
            {
                OnNoMatchingNode( "@*" );
                return null;
            }
            else if ( attributes.Count == 1 )
            {
                XmlPatchNodeList nodeList = new SingleNodeList();
                nodeList.AddNode( attributes.Item( 0 ) );
                return nodeList;
            }
            else
            {
                IEnumerator enumerator = attributes.GetEnumerator();
                XmlPatchNodeList nodeList = new MultiNodeList();
                while ( enumerator.MoveNext() )
                    nodeList.AddNode( (XmlNode) enumerator.Current );
                return nodeList;
            }
        }