/// <summary>
        /// Search for the given symbol definition in the environment.
        /// </summary>
        /// <param name="symbolName"></param>
        /// <returns></returns>
        private SymbolicDef _InternalGetSymbolDef(string symbolName)
        {
            symbolName = _CanonicalizeName(symbolName);
            // Try each stack frame.
            foreach (var dictionary in _define_stack.ToArray())
            {
                SymbolicDef symbolic_def;
                if (dictionary.TryGetValue(symbolName, out symbolic_def) && !_evaluated_symbols.ContainsKey(symbolic_def))
                {
                    return(symbolic_def);
                }
            }
            // If nothing is found on the stack, try the system environment variables.
            string environment_variable = Environment.GetEnvironmentVariable(symbolName);

            if (environment_variable != null)
            {
                var symbolic_def2 = new SymbolicDef
                {
                    Name  = symbolName,
                    Value = _StringToNodeSet(environment_variable)
                };
                return(symbolic_def2);
            }
            return(null);
        }
        /// <summary>
        /// XSLT extension method, called to define a notset symbolic_def in the preprocessor
        /// environment.  The symbolic_def can be referred to symbolically in subsequent
        /// definitions or expansions.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public IEnumerable <XNode> DefineNodesetSymbol(string name, IEnumerable <XNode> value)
        {
            _CheckAlreadyDefined(name);
            var sym = new SymbolicDef {
                Name = name, Value = value, IsExplicitlyDefined = true
            };

            _DefineSymbolOnStack(sym);
            return(new XNode[] {});
        }
        /// <summary>
        /// Retrieve the SymbolicDef bound to the given name.  If the name occurs multiple times
        /// in the stack, returns the highest (most-local) definition.
        /// </summary>
        /// <param name="name">symbol name</param>
        /// <returns>SymbolicDef</returns>
        /// <exception cref="EvaluationException">Symbol was not defined</exception>
        /// <exception cref="ExplicitDefinitionRequiredException">Symbol was defined in the
        /// environment, but preprocess is in "explicit definition required" mode.</exception>
        internal SymbolicDef GetSymbolDef(string name)
        {
            if (!_IsDefined(name))
            {
                Utils.ThrowException(UndefinedSymbolException.CreateException,
                                     "Reference to unknown symbol '{0}'", new object[] { name });
            }
            SymbolicDef symbolic_def = _InternalGetSymbolDef(_CanonicalizeName(name));

            if (_Settings.ExplicitDeclarationRequired && !symbolic_def.IsExplicitlyDefined)
            {
                Utils.ThrowException(ExplicitDefinitionRequiredException.CreateException,
                                     "Symbol '{0}' must be explicitly declared before usage.",
                                     new object[] { name });
            }
            return(symbolic_def);
        }
        private void _DefineTextSymbol(string name, string value, bool isExplicit)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw DefinitionException.CreateException(
                          "An attempt was made to define a nameless variable (value = '{0}'",
                          new object[] { value });
            }
            _CheckAlreadyDefined(name);
            var symbolic_def = new SymbolicDef
            {
                Name  = name,
                Value = new[] { new XText(value) },
                IsExplicitlyDefined = isExplicit
            };

            _DefineSymbolOnStack(symbolic_def);
        }
 /// <summary>
 /// Define the given symbol on the current stack frame.
 /// </summary>
 /// <param name="symbolicDef"></param>
 private void _DefineSymbolOnStack(SymbolicDef symbolicDef)
 {
     _define_stack.Peek().Add(_CanonicalizeName(symbolicDef.Name), symbolicDef);
 }