private Node GetNonTransparentChild(Node current, bool goForward)
        {
            if (current.ChildrenCount == 0)
            {
                return(null);
            }

            Node newNode;
            bool inStack = false;
            int  index   = goForward ? 0 : current.ChildrenCount - 1;

            do
            {
                newNode = current.GetChild(index);

                if (newNode == null && current.IsTransparent)
                {
                    return(GetNonTransparentSibling(current, goForward));
                }

                // If we have to detect loops.
                if (_context.DetectLoops)
                {
                    if (newNode != null && newNode.Object != null &&
                        _navigationStack.Contains(newNode.Object))
                    {
                        var evt = new LoopDetectionEventArgs(this, newNode);
                        _context.OnLoopDetected(evt);

                        if (!evt.IgnoreLoop)
                        {
                            inStack = true;
                            Trace(() => String.Format("GetNonTransparentChild {0} already in stack", newNode.Object));
                            if (goForward)
                            {
                                index++;
                            }
                            else
                            {
                                index--;
                            }

                            continue;
                        }
                    }
                    else
                    {
                        inStack = false;
                    }
                }

                current = newNode;
                if (current != null)
                {
                    index = goForward ? 0 : current.ChildrenCount - 1;
                }
            } while(inStack || (current != null && current.IsTransparent && !IsNodeXPathNavigable(current)));
            // Break if current is null, or non trasparent or navigable

            return(current);
        }
        private Node GetNonTransparentSibling(Node current, bool goForward)
        {
            if (current.NodeType == XPathNodeType.Attribute)
            {
                return(null);
            }

            Node newnode = null;
            Node parent  = current.Parent;

            if (parent == null)
            {
                return(null);
            }

            Object old = null;

            if (_context.DetectLoops)
            {
                if (_navigationStack.Count > 0)
                {
                    old = _navigationStack.Pop();
                }
            }
            do
            {
                newnode = goForward
                                        ? parent.GetChild(current.Index + 1)
                                        : parent.GetChild(current.Index - 1);

                // While there are no more nodes in this transparent parent, try to
                // ascend up the hierarchy and take node next to this transparent node.
                while (newnode == null && parent.IsTransparent)
                {
                    newnode = parent;
                    parent  = parent.Parent;
                    newnode = goForward
                                                ? parent.GetChild(newnode.Index + 1)
                                                : parent.GetChild(newnode.Index - 1);
                }

                // If node is found but it is transparent and not navigable
                if (newnode != null && newnode.IsTransparent && !IsNodeXPathNavigable(newnode))
                {
                    current = newnode;
                    newnode = GetNonTransparentChild(current, goForward);
                    if (newnode != null)
                    {
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }

                // If we have to detect loops
                else if (_context.DetectLoops)
                {
                    if (newnode != null && newnode.Object != null &&
                        _navigationStack.Contains(newnode.Object))
                    {
                        var evt = new LoopDetectionEventArgs(this, newnode);
                        _context.OnLoopDetected(evt);

                        if (!evt.IgnoreLoop)
                        {
                            current = newnode;
                            continue;
                        }
                    }
                }
                break;
            } while(true);

            if (old != null)
            {
                _navigationStack.Push(old);
            }

            return(newnode);
        }
		private Node GetNonTransparentChild(Node current, bool goForward)
		{
			if( current.ChildrenCount == 0 )
				return null;

			Node newNode;
			bool inStack = false;
			int index = goForward ? 0 : current.ChildrenCount - 1;
			do
			{
				newNode = current.GetChild( index );

				if( newNode == null && current.IsTransparent )
					return GetNonTransparentSibling( current, goForward );

				// If we have to detect loops.
				if( _context.DetectLoops )
				{
					if( newNode != null && newNode.Object != null
						&& _navigationStack.Contains( newNode.Object ) )
					{
						var evt = new LoopDetectionEventArgs( this, newNode );
						_context.OnLoopDetected( evt );

						if( !evt.IgnoreLoop )
						{
							inStack = true;
							Trace( () => String.Format( "GetNonTransparentChild {0} already in stack", newNode.Object ) );
							if( goForward )
								index++;
							else
								index--;

							continue;
						}
					}
					else
						inStack = false;
				}

				current = newNode;
				if( current != null )
					index = goForward ? 0 : current.ChildrenCount - 1;

			} while( inStack || ( current != null && current.IsTransparent && !IsNodeXPathNavigable( current ) ) );
			// Break if current is null, or non trasparent or navigable

			return current;
		}