/// <inheritdoc />
        public override void Push(string xpath, string xmlNamespace = null, string prefix = "", int index = -1)
        {
            PushNamespace(xmlNamespace, prefix);

            xpath = QualifyXPath(xpath, prefix, xmlNamespace, index);

            pathStack.Push(Tuple.Create(xpath, index));

            XElement        q;
            List <XElement> nodes = null;

            if (elementStack.Count == 0)
            {
                q = (from x in RootElement.Elements(xpath) select x).FirstOrDefault();
            }
            else if (CurrentElement == null)
            {
                q = null;
            }
            else if (index == -1)
            {
                q = (from x in CurrentElement.Elements(xpath) select x).FirstOrDefault();
            }
            else
            {
                // Get the collection and work out which one we want.
                nodes = XElements(xpath);
                q     = index > nodes.Count ? null : nodes[index - 1];
            }

            elementStack.Push(CurrentElement);

            CurrentElement = q;
            CurrentNodes   = nodes;
        }
        private XElement ToXElement(string xpath, string prefix = "", int index = -1)
        {
            if (string.IsNullOrEmpty(xpath) || CurrentElement == null)
            {
                return(CurrentElement);
            }

            xpath = QualifyXPath(xpath, prefix);

            if (index == -1)
            {
                return(CurrentElement.Elements(xpath).FirstOrDefault());
            }

            var nodes = CurrentElement.Elements(xpath).ToList();

            return(nodes.Count >= index ? nodes[index - 1] : null);
        }
        private List <XElement> XElements(string xpath)
        {
            List <XElement> nodes;
            var             ns = nodesStack[elementStack.Count];

            // Need to query
            if (ns == null)
            {
                nodes = (from x in CurrentElement.Elements(xpath) select x).ToList();

                // Locally cache nodes until the next pop^2, i.e. acquire on Jim[1] and don't
                // remove until pop Jim's parent.
                nodesStack[elementStack.Count] = nodes;
            }
            else
            {
                nodes = ns;
            }

            return(nodes);
        }
 public IEnumerable <XElement> PropertyElements() => CurrentElement.Elements(CompositeDefinitionHelper.Property);