internal SeekableMessageNavigator(SeekableMessageNavigator nav)
 {
     this.counter = nav.counter;
     this.dom = nav.dom;
     this.location = nav.location;
     this.specialParent = nav.specialParent;
     if (this.specialParent != 0)
     {
         this.nsStack = nav.CloneNSStack();
     }
 }
        // Move this navigator to the same position as the given one
        internal bool MoveTo(SeekableMessageNavigator nav)
        {
            if (nav == null)
            {
                return false;
            }

            this.dom = nav.dom;
            this.counter = nav.counter;
            this.location = nav.location;
            this.specialParent = nav.specialParent;
            if (this.specialParent != NullIndex)
            {
                this.nsStack = nav.CloneNSStack();
            }

            return true;
        }
        // Tests whether the given navigator is positioned on the same node as this navigator
        internal bool IsSamePosition(SeekableMessageNavigator nav)
        {
            if (nav == null)
            {
                return false;
            }

            return this.dom == nav.dom && this.location == nav.location && this.specialParent == nav.specialParent;
        }
        // Test whether the given navigator is positioned on a descendant of this navigator
        internal bool IsDescendant(SeekableMessageNavigator nav)
        {
            if (nav == null)
            {
                return false;
            }

            if (this.dom != nav.dom)
            {
                return false;
            }

            // Namespaces and attributes are not considered descendants
            XPathNodeType type = this.dom.nodes[nav.location].type;
            if (type == XPathNodeType.Namespace || type == XPathNodeType.Attribute)
            {
                return false;
            }

            // Namespaces and attributes are not parents
            type = this.dom.nodes[this.location].type;
            if (type == XPathNodeType.Namespace || type == XPathNodeType.Attribute)
            {
                return false;
            }

            // Climb up the tree looking for the current navigator's position
            int n = nav.location;
            while (n != NullIndex)
            {
                Increase();
                n = this.dom.nodes[n].parent;

                if (n == this.location)
                {
                    return true;
                }
            }
            return false;
        }
        // Compare the current position to that of another navigator.
        internal XmlNodeOrder ComparePosition(SeekableMessageNavigator nav)
        {
            if (nav == null)
            {
                return XmlNodeOrder.Unknown;
            }

            if (this.dom != nav.dom)
            {
                return XmlNodeOrder.Unknown;
            }

            return this.dom.ComparePosition(this.specialParent, this.location, nav.specialParent, nav.location);
        }
        internal SeekableMessageNavigator(SeekableMessageNavigator nav)
        {
            Fx.Assert(nav != null, "Navigator may not be null");

            this.counter = nav.counter;
            this.dom = nav.dom;
            this.location = nav.location;
            this.specialParent = nav.specialParent;
            if (this.specialParent != NullIndex)
            {
                this.nsStack = nav.CloneNSStack();
            }
        }
        // THREAD: Synchronize this function if multiple threads can try to re-initialize an instance at the same time.  Also, if you reinitialize the navigator that holds information referenced by clones, the clones will be affected as well.
        internal void Init(Message msg, int countMax, XmlSpace space, bool includeBody, bool atomize)
        {
            Fx.Assert(countMax > 0, "Maximum node count must be greater than zero");
            this.counter = this;
            this.nodeCount = countMax;
            this.nodeCountMax = countMax;

            Fx.Assert(msg != null, "Message may not be null");
            this.dom = this;
            this.location = RootIndex;
            this.specialParent = NullIndex;
            this.includeBody = includeBody;
            this.message = msg;
            this.headers = msg.Headers;
            this.space = space;
            this.atomize = false; // Will get fixed at the end of this function

            int minSize = msg.Headers.Count + FirstHeaderIndex + 1;

            if (this.nodes == null || this.nodes.Length < minSize)
            {
                this.nodes = new Node[minSize + StartSize];
            }
            else
            {
                Array.Clear(this.nodes, 1, this.nextFreeIndex - 1);
            }

            this.bodyIndex = minSize - 1;
            this.nextFreeIndex = minSize;

            // Use the static blank DOM to create the first few nodes
            Array.Copy(BlankDom, this.nodes, HeaderIndex + 1);

            string soapNS = msg.Version.Envelope.Namespace;
            this.nodes[EnvelopeIndex].ns = soapNS;
            this.nodes[SoapNSIndex].val = soapNS;
            this.nodes[HeaderIndex].ns = soapNS;

            this.nodes[HeaderIndex].nextSibling = bodyIndex;
            this.nodes[HeaderIndex].firstChild = this.bodyIndex != FirstHeaderIndex ? FirstHeaderIndex : NullIndex;

            // Headers
            if (msg.Headers.Count > 0)
            {
                for (int i = FirstHeaderIndex, h = 0; h < msg.Headers.Count; ++i, ++h)
                {
                    this.nodes[i].type = XPathNodeType.Element;
                    this.nodes[i].parent = HeaderIndex;
                    this.nodes[i].nextSibling = i + 1;
                    this.nodes[i].prevSibling = i - 1;

                    // Extract the header block stub data
                    MessageHeaderInfo header = msg.Headers[h];
                    this.nodes[i].ns = header.Namespace;
                    this.nodes[i].name = header.Name;
                    this.nodes[i].firstChild = -1;
                }
                this.nodes[FirstHeaderIndex].prevSibling = NullIndex;
                this.nodes[this.bodyIndex - 1].nextSibling = NullIndex;
            }

            // Body
            this.nodes[bodyIndex].type = XPathNodeType.Element;
            this.nodes[bodyIndex].prefix = SoapP;
            this.nodes[bodyIndex].ns = soapNS;
            this.nodes[bodyIndex].name = BodyTag;
            this.nodes[bodyIndex].parent = EnvelopeIndex;
            this.nodes[bodyIndex].prevSibling = HeaderIndex;
            this.nodes[bodyIndex].firstNamespace = SoapNSIndex;
            this.nodes[bodyIndex].firstChild = -1; // Need to load

            // Atomize
            if (atomize)
            {
                Atomize();
            }
        }
        // Set a new count for this navigator
        // Set it to use itself for the counter so all clones of it will share the new counter
        internal void ForkNodeCount(int count)
        {
            Fx.Assert(count > 0, "Maximum node count must be greater than zero");

            this.nodeCount = count;
            this.nodeCountMax = count;
            this.counter = this;
        }
 internal bool IsDescendant(SeekableMessageNavigator nav)
 {
     if (nav != null)
     {
         if (this.dom != nav.dom)
         {
             return false;
         }
         switch (this.dom.nodes[nav.location].type)
         {
             case XPathNodeType.Namespace:
             case XPathNodeType.Attribute:
                 return false;
         }
         switch (this.dom.nodes[this.location].type)
         {
             case XPathNodeType.Namespace:
             case XPathNodeType.Attribute:
                 return false;
         }
         int location = nav.location;
         while (location != 0)
         {
             this.Increase();
             location = this.dom.nodes[location].parent;
             if (location == this.location)
             {
                 return true;
             }
         }
     }
     return false;
 }
 internal void Init(System.ServiceModel.Channels.Message msg, int countMax, XmlSpace space, bool includeBody, bool atomize)
 {
     this.counter = this;
     this.nodeCount = countMax;
     this.nodeCountMax = countMax;
     this.dom = this;
     this.location = 1;
     this.specialParent = 0;
     this.includeBody = includeBody;
     this.message = msg;
     this.headers = msg.Headers;
     this.space = space;
     this.atomize = false;
     int num = (msg.Headers.Count + 6) + 1;
     if ((this.nodes == null) || (this.nodes.Length < num))
     {
         this.nodes = new Node[num + 50];
     }
     else
     {
         Array.Clear(this.nodes, 1, this.nextFreeIndex - 1);
     }
     this.bodyIndex = num - 1;
     this.nextFreeIndex = num;
     Array.Copy(BlankDom, this.nodes, 6);
     string str = msg.Version.Envelope.Namespace;
     this.nodes[2].ns = str;
     this.nodes[3].val = str;
     this.nodes[5].ns = str;
     this.nodes[5].nextSibling = this.bodyIndex;
     this.nodes[5].firstChild = (this.bodyIndex != 6) ? 6 : 0;
     if (msg.Headers.Count > 0)
     {
         int index = 6;
         for (int i = 0; i < msg.Headers.Count; i++)
         {
             this.nodes[index].type = XPathNodeType.Element;
             this.nodes[index].parent = 5;
             this.nodes[index].nextSibling = index + 1;
             this.nodes[index].prevSibling = index - 1;
             MessageHeaderInfo info = msg.Headers[i];
             this.nodes[index].ns = info.Namespace;
             this.nodes[index].name = info.Name;
             this.nodes[index].firstChild = -1;
             index++;
         }
         this.nodes[6].prevSibling = 0;
         this.nodes[this.bodyIndex - 1].nextSibling = 0;
     }
     this.nodes[this.bodyIndex].type = XPathNodeType.Element;
     this.nodes[this.bodyIndex].prefix = "s";
     this.nodes[this.bodyIndex].ns = str;
     this.nodes[this.bodyIndex].name = "Body";
     this.nodes[this.bodyIndex].parent = 2;
     this.nodes[this.bodyIndex].prevSibling = 5;
     this.nodes[this.bodyIndex].firstNamespace = 3;
     this.nodes[this.bodyIndex].firstChild = -1;
     if (atomize)
     {
         this.Atomize();
     }
 }
 internal void ForkNodeCount(int count)
 {
     this.nodeCount = count;
     this.nodeCountMax = count;
     this.counter = this;
 }