/// <summary>Re-initializes internal state to be ready for re-use.</summary>
        public void Reset()
        {
            // some declarations may be pending in nextScope
            nextScope.ClearMappings();
            // store active scopes for re-use
            NamespaceScope scope = topScope;

            if (scope != null)
            {
                // need to reset active scopes before storing them for re-use
                scope.ClearMappings();
                while (scope.parent != null)
                {
                    scope = scope.parent;
                    scope.ClearMappings();
                }
                // attach free scopes to end of active scopes
                scope.parent = nextScope;
                // move the whole stack from topScope to nextScope
                nextScope = topScope;
                topScope  = null;
            }
            // the 'xml' prefix is always declared
            nextScope.AddMapping("xml", Constants.XmlUri);
        }
        /// <summary>Given a prefix mapping for a specific URI, this returns
        /// the prefix mapping previously in effect for the same URI.</summary>
        /// <remarks>This can be used to iterate backwards through the stack of
        /// prefix mappings for a given URI.</remarks>
        /// <param name="prefix"><see cref="ActiveMapping"/> instance for which
        /// we want to find the instance previously in effect with the same URI.</param>
        /// <returns><see cref="ActiveMapping"/> instance to look for,
        /// or <c>null</c> if none exists.</returns>
        public ActiveMapping PreviousUriMapping(ActiveMapping prefix)
        {
            string uri = prefix.Uri;
            // check active mapping record
            NamespaceMapping nsMapping = prefix.mappingsTop;

            if (nsMapping == null || !nsMapping.declared)
            {
                string msg = Resources.GetString(RsId.UndeclaredMapping);
                throw new XmlNamespacesException(String.Format(msg, prefix.Prefix));
            }
            // find a parent scope where the same URI maps to an "active" prefix
            NamespaceScope scope = nsMapping.scope.parent;

            while (scope != null)
            {
                nsMapping = scope.FindByUri(uri);
                if (nsMapping != null)
                {
                    ActiveMapping result = nsMapping.prefix;
                    // result must be different from prefix, since the same prefix
                    // cannot be "declared" with two different URIs at the same time
                    if (result.IsDeclared)
                    {
                        Debug.Assert(result != prefix, Resources.GetString(RsId.InternalNsError));
                        return(result);
                    }
                }
                scope = scope.parent;
            }
            return(null);
        }
        /// <summary>Returns the most recently added namespace mapping "in effect"
        /// for a given URI.</summary>
        /// <remarks>"In effect" means that the prefix mapping must <b>not</b> have
        /// been "undeclared".</remarks>
        /// <param name="uri">Namespace URI to get mapping for.</param>
        /// <returns><see cref="ActiveMapping"/> instance for <c>uri</c>, or <c>null</c>
        /// if there is no such mapping.</returns>
        public ActiveMapping GetUriMapping(string uri)
        {
            NamespaceScope scope = topScope;

            while (scope != null)
            {
                NamespaceMapping nsMapping = scope.FindByUri(uri);
                if (nsMapping != null && nsMapping.declared)
                {
                    return(nsMapping.prefix);
                }
                scope = scope.parent;
            }
            return(null);
        }
        /// <param name="prefixStr">String containing prefix sub-string.</param>
        /// <param name="start">Start index of prefix sub-string.</param>
        /// <param name="len">Length of prefix sub-string.</param>
        public ActiveMapping GetPrefixMapping(string prefixStr, int start, int len)
        {
            NamespaceScope scope = topScope;

            while (scope != null)
            {
                NamespaceMapping nsMapping = scope.FindByPrefix(prefixStr, start, len);
                if (nsMapping != null)
                {
                    return(nsMapping.prefix);
                }
                scope = scope.parent;
            }
            return(null);
        }
        /// <summary>Establishes a new mapping for the prefix associated with this
        /// instance, to an URI in a namespace scope, and pushes it on the stack.</summary>
        /// <param name="scope">Namespace scope the new mapping will be part of.</param>
        /// <param name="uri">URI to be mapped to this instance's prefix.</param>
        /// <returns>Newly added <see cref="NamespaceMapping"/>.</returns>
        protected internal NamespaceMapping PushMapping(string uri, NamespaceScope scope)
        {
            NamespaceMapping result = namespaces.NewNSMapping();

            result.prefix   = this;
            result.scope    = scope;
            result.declared = uri != null;
            if (result.declared)
            {
                result.uri = uri;
            }
            else
            {
                result.uri = this.Uri;
            }
            result.next = mappingsTop;
            mappingsTop = result;
            return(result);
        }
 /// <summary>Deactivates namespace scope.</summary>
 /// <remarks>All namespace mappings that became active with this scope
 /// are going out of effect.</remarks>
 public void PopScope()
 {
     if (nextScope.emptyLevels > 0)
     {
         nextScope.emptyLevels--;
     }
     else if (topScope == null) // don't pop too many times
     {
         string msg = Resources.GetString(RsId.NoActiveNsScope);
         throw new InvalidOperationException(msg);
     }
     else
     {
         NamespaceScope oldNextScope = nextScope;
         // clear pending declarations
         oldNextScope.ClearMappings();
         nextScope        = topScope;
         topScope         = topScope.parent;
         nextScope.parent = oldNextScope;
         nextScope.ClearMappings();
     }
 }
 /// <summary>Activates new namespace scope.</summary>
 /// <remarks>All namespace mappings that were added since the last
 /// call to <see cref="PushScope"/>are going into effect.</remarks>
 public void PushScope()
 {
     if (nextScope.nsMappings.Count == 0)
     {
         nextScope.emptyLevels++;
     }
     else
     {
         NamespaceScope newNextScope = nextScope.parent;
         nextScope.parent = topScope;
         topScope         = nextScope; // assume it was reset
         if (newNextScope == null)
         {
             newNextScope = new NamespaceScope(this);
         }
         else
         {
             newNextScope.emptyLevels = 0;
         }
         nextScope = newNextScope;
     }
 }
 /// <summary>Indicates if a namespace scope is the most recent scope.</summary>
 /// <param name="scope"><see cref="NamespaceScope"/> to be checked.</param>
 /// <returns><c>true</c> if <c>scope</c> is most recent, <c>false</c> otherwise.</returns>
 protected internal bool IsLastScope(NamespaceScope scope)
 {
     return scope == topScope || scope == nextScope;
 }
 /// <summary>Re-initializes internal state to be ready for re-use.</summary>
 public void Reset()
 {
     // some declarations may be pending in nextScope
       nextScope.ClearMappings();
       // store active scopes for re-use
       NamespaceScope scope = topScope;
       if (scope != null) {
     // need to reset active scopes before storing them for re-use
     scope.ClearMappings();
     while (scope.parent != null) {
       scope = scope.parent;
       scope.ClearMappings();
     }
     // attach free scopes to end of active scopes
     scope.parent = nextScope;
     // move the whole stack from topScope to nextScope
     nextScope = topScope;
     topScope = null;
       }
       // the 'xml' prefix is always declared
       nextScope.AddMapping("xml", Constants.XmlUri);
 }
 /// <summary>Activates new namespace scope.</summary>
 /// <remarks>All namespace mappings that were added since the last
 /// call to <see cref="PushScope"/>are going into effect.</remarks>
 public void PushScope()
 {
     if (nextScope.nsMappings.Count == 0) {
     nextScope.emptyLevels++;
       }
       else {
     NamespaceScope newNextScope = nextScope.parent;
     nextScope.parent = topScope;
     topScope = nextScope;  // assume it was reset
     if (newNextScope == null)
       newNextScope = new NamespaceScope(this);
     else
       newNextScope.emptyLevels = 0;
     nextScope = newNextScope;
       }
 }
 /// <summary>Deactivates namespace scope.</summary>
 /// <remarks>All namespace mappings that became active with this scope
 /// are going out of effect.</remarks>
 public void PopScope()
 {
     if (nextScope.emptyLevels > 0)
     nextScope.emptyLevels--;
       else if (topScope == null) {  // don't pop too many times
     string msg = Resources.GetString(RsId.NoActiveNsScope);
     throw new InvalidOperationException(msg);
       }
       else {
     NamespaceScope oldNextScope = nextScope;
     // clear pending declarations
     oldNextScope.ClearMappings();
     nextScope = topScope;
     topScope = topScope.parent;
     nextScope.parent = oldNextScope;
     nextScope.ClearMappings();
       }
 }
 /* Public Interface */
 /// <summary>Initializes new instance.</summary>
 public XmlNamespaces()
 {
     nextScope = new NamespaceScope(this);
       // the 'xml' prefix is always declared
       nextScope.AddMapping("xml", Constants.XmlUri);
 }
 /// <summary>Establishes a new mapping for the prefix associated with this 
 /// instance, to an URI in a namespace scope, and pushes it on the stack.</summary>
 /// <param name="scope">Namespace scope the new mapping will be part of.</param>
 /// <param name="uri">URI to be mapped to this instance's prefix.</param>
 /// <returns>Newly added <see cref="NamespaceMapping"/>.</returns>
 protected internal NamespaceMapping PushMapping(string uri, NamespaceScope scope)
 {
     NamespaceMapping result = namespaces.NewNSMapping();
       result.prefix = this;
       result.scope = scope;
       result.declared = uri != null;
       if (result.declared)
     result.uri = uri;
       else
     result.uri = this.Uri;
       result.next = mappingsTop;
       mappingsTop = result;
       return result;
 }
        /* Public Interface */

        /// <summary>Initializes new instance.</summary>
        public XmlNamespaces()
        {
            nextScope = new NamespaceScope(this);
            // the 'xml' prefix is always declared
            nextScope.AddMapping("xml", Constants.XmlUri);
        }
 /// <summary>Indicates if a namespace scope is the most recent scope.</summary>
 /// <param name="scope"><see cref="NamespaceScope"/> to be checked.</param>
 /// <returns><c>true</c> if <c>scope</c> is most recent, <c>false</c> otherwise.</returns>
 protected internal bool IsLastScope(NamespaceScope scope)
 {
     return(scope == topScope || scope == nextScope);
 }