/// <summary>
        /// Execute it in the given document with current position at the given node.
        /// </summary>
        /// <param name="dom">Document</param>
        /// <param name="cursor">Nodes we're currently at</param>
        /// <param name="stack">Execution stack</param>
        /// <returns>New current nodes</returns>
        public ICursor Exec(XNode dom, ICursor cursor, IStack stack)
        {
            var doc = new XmlDocumentOf(dom).Value();
            var pi  = new XProcessingInstruction(this.target.Raw(), this.data.Raw());

            // if cursor list is empty
            if (new LengthOf(cursor).Value() == 0)
            {
                doc.Root.AddBeforeSelf(pi);
            }
            else
            {
                foreach (var node in cursor)
                {
                    (node as XContainer).Add(pi);
                }
            }

            return(cursor);
        }
        /// <summary>
        /// Execute it in the given document with current position at the given node.
        /// </summary>
        /// <param name="dom">Document</param>
        /// <param name="cursor">Nodes we're currently at</param>
        /// <param name="stack">Execution stack</param>
        /// <returns>New current nodes</returns>
        public ICursor Exec(XNode dom, ICursor cursor, IStack stack)
        {
            var doc = new XmlDocumentOf(dom).Value();

            var val = this.value.Raw();

            foreach (var node in cursor)
            {
                var ctn = node as XContainer;

                new FailPrecise(
                    new FailNull(ctn),
                    new ImpossibleModificationException("Cannot add CData to a node which is not of type XContainer")
                    ).Go();

                var cdata = new XCData(val);
                (node as XContainer).Add(cdata);
            }

            return(cursor);
        }
        /// <summary>
        /// Execute it in the given document with current position at the given node.
        /// </summary>
        /// <param name="dom">Document</param>
        /// <param name="cursor">Nodes we're currently at</param>
        /// <param name="stack">Execution stack</param>
        /// <returns>New current nodes</returns>
        public ICursor Exec(XNode dom, ICursor cursor, IStack stack)
        {
            var targets = new List <XNode>();
            var label   = name.Raw().ToLower();

            foreach (var node in cursor)
            {
                var ctn = node as XContainer;

                new FailPrecise(
                    new FailNull(ctn),
                    new ImpossibleModificationException("")
                    ).Go();

                var   kids   = ctn.Elements();
                XNode target = null;

                foreach (var kid in ctn.Elements())
                {
                    if (kid.Name.LocalName.ToLower() == label)
                    {
                        target = kid;
                        break;
                    }
                }

                if (target == null)
                {
                    XDocument doc = new XmlDocumentOf(dom).Value();

                    target = new XElement(this.name.Raw());
                    ctn.Add(target);
                }

                targets.Add(target);
            }

            return(new DomCursor(targets));
        }