private static XmlNodeList SelectAttributes(XmlNode parentNode, string path)
        {
            Debug.Assert(path[0] == '@');

            int pos = 1;
            XmlAttributeCollection attributes = parentNode.Attributes;
            XmlPatchNodeList       nodeList   = null;

            for (;;)
            {
                string name = ReadAttrName(path, ref pos);

                if (nodeList == null)
                {
                    if (pos == path.Length)
                    {
                        nodeList = new SingleNodeList();
                    }
                    else
                    {
                        nodeList = new MultiNodeList();
                    }
                }

                XmlNode attr = attributes.GetNamedItem(name);
                if (attr == null)
                {
                    OnNoMatchingNode(path);
                }

                nodeList.AddNode(attr);

                if (pos == path.Length)
                {
                    break;
                }
                else if (path[pos] == '|')
                {
                    pos++;
                    if (path[pos] != '@')
                    {
                        OnInvalidExpression(path);
                    }
                    pos++;
                }
                else
                {
                    OnInvalidExpression(path);
                }
            }

            return(nodeList);
        }
        private static XmlNodeList SelectChildNodes(XmlNode parentNode, string path, int startPos)
        {
            int pos = startPos;
            XmlPatchNodeList nodeList = null;
            XmlNodeList      children = parentNode.ChildNodes;

            int nodePos = ReadPosition(path, ref pos);

            if (pos == path.Length)
            {
                nodeList = new SingleNodeList();
            }
            else
            {
                nodeList = new MultiNodeList();
            }

            for (;;)
            {
                if (nodePos <= 0 || nodePos > children.Count)
                {
                    OnNoMatchingNode(path);
                }

                XmlNode node = children.Item(nodePos - 1);
                nodeList.AddNode(node);

                if (pos == path.Length)
                {
                    break;
                }
                else if (path[pos] == '|')
                {
                    pos++;
                }
                else if (path[pos] == '-')
                {
                    pos++;
                    int endNodePos = ReadPosition(path, ref pos);
                    if (endNodePos <= 0 || endNodePos > children.Count)
                    {
                        OnNoMatchingNode(path);
                    }

                    while (nodePos < endNodePos)
                    {
                        nodePos++;
                        node = node.NextSibling;
                        nodeList.AddNode(node);
                    }

                    Debug.Assert((object)node == (object)children.Item(endNodePos - 1));

                    if (pos == path.Length)
                    {
                        break;
                    }
                    else if (path[pos] == '|')
                    {
                        pos++;
                    }
                    else
                    {
                        OnInvalidExpression(path);
                    }
                }

                nodePos = ReadPosition(path, ref pos);
            }
            return(nodeList);
        }