private static void AddAllAssembliesFromAppDomainBinDirectory(
                CompilationConfiguration result, XmlNode child)
            {
                // Get the path to the bin directory
                string binPath = HttpRuntime.BinDirectoryInternal;

                FileInfo[] binDlls;

                if (!FileUtil.DirectoryExists(binPath))
                {
                    // This is expected to fail if there is no 'bin' dir
                    Debug.Trace("Template", "Failed to access bin dir \"" + binPath + "\"");
                }
                else
                {
                    DirectoryInfo binPathDirectory = new DirectoryInfo(binPath);
                    // Get a list of all the DLL's in the bin directory
                    binDlls = binPathDirectory.GetFiles("*.dll");

                    string configFile = ConfigurationException.GetXmlNodeFilename(child);

                    for (int i = 0; i < binDlls.Length; i++)
                    {
                        string assemblyName = Util.GetAssemblyNameFromFileName(binDlls[i].Name);

                        // Remember the config file location info, in case an error
                        // occurs later when we try to load the assembly (ASURT 72183)
                        int configFileLine = ConfigurationException.GetXmlNodeLineNumber(child);
                        result._assemblies[assemblyName] = new object[]
                        { configFile, configFileLine, true /*starDirective*/ };
                    }
                }
            }
        private CompilationConfiguration(CompilationConfiguration original)
        {
            if (original._compilerLanguages != null)
            {
                _compilerLanguages = (Hashtable)original._compilerLanguages.Clone();
            }

            if (original._compilerExtensions != null)
            {
                _compilerExtensions = (Hashtable)original._compilerExtensions.Clone();
            }

            if (original._assemblies != null)
            {
                _assemblies = (Hashtable)original._assemblies.Clone();
            }

            _defaultLanguage                 = original._defaultLanguage;
            _tempDirectory                   = original._tempDirectory;
            _debug                           = original._debug;
            _strict                          = original._strict;
            _explicit                        = original._explicit;
            _batch                           = original._batch;
            _batchTimeout                    = original._batchTimeout;
            _maxBatchGeneratedFileSize       = original._maxBatchGeneratedFileSize;
            _maxBatchSize                    = original._maxBatchSize;
            _recompilationsBeforeAppRestarts = original._recompilationsBeforeAppRestarts;
        }
        internal /*public*/ static int GetRecompilationsBeforeAppRestarts(HttpContext context)
        {
            CompilationConfiguration compConfig =
                (UI.CompilationConfiguration)context.GetConfig(sectionName);

            if (compConfig == null)
            {
                return(recompilationsBeforeAppRestartsDefault);
            }

            return(compConfig.RecompilationsBeforeAppRestarts);
        }
        internal /*public*/ static int GetMaxBatchSize(HttpContext context)
        {
            CompilationConfiguration compConfig =
                (UI.CompilationConfiguration)context.GetConfig(sectionName);

            if (compConfig == null)
            {
                return(maxBatchSizeDefault);
            }

            return(compConfig.MaxBatchSize);
        }
        internal /*public*/ static int GetBatchTimeout(HttpContext context)
        {
            CompilationConfiguration compConfig =
                (UI.CompilationConfiguration)context.GetConfig(sectionName);

            if (compConfig == null)
            {
                return(batchTimeoutDefault);
            }

            return(compConfig.BatchTimeout);
        }
        internal /*public*/ static bool IsBatchingEnabled(HttpContext context)
        {
            CompilationConfiguration compConfig =
                (UI.CompilationConfiguration)context.GetConfig(sectionName);

            if (compConfig == null)
            {
                return(true);
            }

            return(compConfig.Batch);
        }
        internal /*public*/ static bool IsDebuggingEnabled(HttpContext context)
        {
            CompilationConfiguration compConfig =
                (UI.CompilationConfiguration)context.GetConfig(sectionName);

            if (compConfig == null)
            {
                return(false);
            }

            return(compConfig.DebuggingEnabled);
        }
        /*
         * Return a CompilerInfo that a extension maps to.
         */
        internal static CompilerInfo GetCompilerInfoFromExtension(HttpContext context, string extension)
        {
            // Get the <compilation> config object
            CompilationConfiguration config = (CompilationConfiguration)context.GetConfig(sectionName);

            if (config == null)
            {
                // Unsupported extension: throw an exception
                throw new HttpException(HttpRuntime.FormatResourceString(SR.Invalid_lang_extension, extension));
            }

            return(config.GetCompilerInfoFromExtension(extension));
        }
        /*
         * Simple wrapper to get the Assemblies for a context
         */
        internal static IDictionary GetAssembliesFromContext(HttpContext context)
        {
            // Get the CompilationConfiguration object for the passed in context
            CompilationConfiguration compilationConfiguration =
                (CompilationConfiguration)context.GetConfig(sectionName);

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

            return(compilationConfiguration.Assemblies);
        }
        internal /*public*/ static CompilerInfo GetDefaultLanguageCompilerInfo(HttpContext context)
        {
            CompilationConfiguration config = null;

            // Get the <compilation> config object
            if (context != null)
            {
                config = (CompilationConfiguration)context.GetConfig(sectionName);
            }

            // If no default language was specified in config, use VB
            if (config == null || config._defaultLanguage == null)
            {
                return(new CompilerInfo(typeof(Microsoft.VisualBasic.VBCodeProvider)));
            }

            return(config.GetCompilerInfoFromLanguage(config._defaultLanguage));
        }
        /*
         * Add all the assemblies specified in the config files
         */
        private void AppendConfigAssemblies()
        {
            // Always add dependencies to System.Web.dll and System.dll (ASURT 78531)
            AddAssemblyDependency(typeof(Page).Assembly);
            AddAssemblyDependency(typeof(Uri).Assembly);

            // Get the set of config assemblies for our context
            IDictionary configAssemblies = CompilationConfiguration.GetAssembliesFromContext(_context);

            if (configAssemblies == null)
            {
                return;
            }

            // Add dependencies to all the config assemblies
            foreach (Assembly a in configAssemblies.Values)
            {
                AddAssemblyDependency(a);
            }

            // Also, link in the global.asax assembly
            AddAssemblyDependency(HttpApplicationFactory.ApplicationType.Assembly);
        }
        /*
         * Compile a source file into an assembly, and import it
         */
        private void ImportSourceFile(string virtualPath)
        {
            // Get a full path to the source file
            string baseVirtualDir  = UrlPath.GetDirectory(_virtualPath);
            string fullVirtualPath = UrlPath.Combine(baseVirtualDir, virtualPath);
            string physicalPath    = _context.Request.MapPath(fullVirtualPath, null, false /*allowCrossAppMapping*/);

            // Add the source file to the list of files we depend on
            AddSourceDependency(physicalPath);

            CompilerInfo compilerInfo = CompilationConfiguration.GetCompilerInfoFromFileName(
                _context, physicalPath);

            CompilerParameters compilParams = compilerInfo.CompilParams;

            // Compile it into an assembly

            Assembly a = SourceCompiler.GetAssemblyFromSourceFile(_context, fullVirtualPath,
                                                                  null /*assemblies*/, compilerInfo.CompilerType, compilParams);

            // Add a dependency to the assembly
            AddAssemblyDependency(a);
        }
        /*
         * Process a <%@ %> block
         */
        private void ProcessDirective(string directiveName, IDictionary directive)
        {
            // Empty means default
            if (directiveName == "")
            {
                directiveName = DefaultDirectiveName;
            }

            // Check for the main directive
            if (string.Compare(directiveName, DefaultDirectiveName, true, CultureInfo.InvariantCulture) == 0)
            {
                // Make sure the main directive was not already specified
                if (_fFoundMainDirective)
                {
                    throw new HttpException(
                              HttpRuntime.FormatResourceString(SR.Only_one_directive_allowed, DefaultDirectiveName));
                }

                _fFoundMainDirective = true;

                // Since description is a no op, just remove it if it's there
                directive.Remove("description");

                // Similarily, ignore 'codebehind' attribute (ASURT 4591)
                directive.Remove("codebehind");

                string language = Util.GetAndRemoveNonEmptyAttribute(directive, "language");

                CompilerInfo compilerInfo;

                // Get the compiler for the specified language (if any)
                if (language != null)
                {
                    compilerInfo = CompilationConfiguration.GetCompilerInfoFromLanguage(
                        _context, language);
                }
                else
                {
                    // Get a default from config
                    compilerInfo = CompilationConfiguration.GetDefaultLanguageCompilerInfo(_context);
                }

                _compilerType = compilerInfo.CompilerType;
                _compilParams = compilerInfo.CompilParams;

                _className = Util.GetAndRemoveRequiredAttribute(directive, "class");

                if (_compilParams != null)
                {
                    ProcessCompilationParams(directive, _compilParams);
                }
            }
            else if (string.Compare(directiveName, "assembly", true) == 0)
            {
                // Assembly directive

                // Remove the attributes as we get them from the dictionary
                string assemblyName = Util.GetAndRemoveNonEmptyAttribute(directive, "name");
                string src          = Util.GetAndRemoveNonEmptyAttribute(directive, "src");

                if (assemblyName != null && src != null)
                {
                    throw new HttpException(
                              HttpRuntime.FormatResourceString(SR.Attributes_mutually_exclusive, "Name", "Src"));
                }

                if (assemblyName != null)
                {
                    AddAssemblyDependency(assemblyName);
                }
                // Is it a source file that needs to be compiled on the fly
                else if (src != null)
                {
                    ImportSourceFile(src);
                }
                else
                {
                    throw new HttpException(HttpRuntime.FormatResourceString(SR.Missing_attr, "name"));
                }
            }
            else
            {
                throw new HttpException(
                          HttpRuntime.FormatResourceString(SR.Unknown_directive, directiveName));
            }

            // If there are some attributes left, fail
            Util.CheckUnknownDirectiveAttributes(directiveName, directive);
        }
            private static void ProcessCompilersElement(CompilationConfiguration result, XmlNode node)
            {
                // reject attributes
                HandlerBase.CheckForUnrecognizedAttributes(node);

                string configFile = ConfigurationException.GetXmlNodeFilename(node);

                foreach (XmlNode child in node.ChildNodes)
                {
                    // skip whitespace and comments
                    // reject nonelements
                    if (HandlerBase.IsIgnorableAlsoCheckForNonElement(child))
                    {
                        continue;
                    }

                    if (child.Name != "compiler")
                    {
                        HandlerBase.ThrowUnrecognizedElement(child);
                    }

                    string languages = String.Empty;
                    HandlerBase.GetAndRemoveStringAttribute(child, "language", ref languages);
                    string extensions = String.Empty;
                    HandlerBase.GetAndRemoveStringAttribute(child, "extension", ref extensions);
                    string compilerTypeName = null;
                    HandlerBase.GetAndRemoveRequiredNonEmptyStringAttribute(child, "type", ref compilerTypeName);

                    // Create a CompilerParameters for this compiler.
                    CompilerParameters compilParams = new CompilerParameters();

                    int warningLevel = 0;
                    if (HandlerBase.GetAndRemoveNonNegativeIntegerAttribute(child, "warningLevel", ref warningLevel) != null)
                    {
                        compilParams.WarningLevel = warningLevel;

                        // Need to be false if the warning level is 0
                        compilParams.TreatWarningsAsErrors = (warningLevel > 0);
                    }
                    string compilerOptions = null;
                    if (HandlerBase.GetAndRemoveStringAttribute(child, "compilerOptions", ref compilerOptions) != null)
                    {
                        compilParams.CompilerOptions = compilerOptions;
                    }

                    HandlerBase.CheckForUnrecognizedAttributes(child);
                    HandlerBase.CheckForChildNodes(child);

                    // Create a CompilerInfo structure for this compiler
                    int          configFileLine = ConfigurationException.GetXmlNodeLineNumber(child);
                    CompilerInfo compilInfo     = new CompilerInfo(compilParams, compilerTypeName, configFile, configFileLine);

                    if (result._compilerLanguages == null)
                    {
                        result._compilerLanguages  = new Hashtable(SymbolHashCodeProvider.Default, SymbolEqualComparer.Default);
                        result._compilerExtensions = new Hashtable(SymbolHashCodeProvider.Default, SymbolEqualComparer.Default);
                    }

                    // Parse the semicolon separated lists
                    string[] languageList  = languages.Split(s_fieldSeparators);
                    string[] extensionList = extensions.Split(s_fieldSeparators);

                    foreach (string language in languageList)
                    {
                        result._compilerLanguages[language] = compilInfo;
                    }

                    foreach (string extension in extensionList)
                    {
                        result._compilerExtensions[extension] = compilInfo;
                    }
                }
            }
            private static void ProcessAssembliesElement(CompilationConfiguration result, XmlNode node)
            {
                // reject attributes
                HandlerBase.CheckForUnrecognizedAttributes(node);

                string configFile = ConfigurationException.GetXmlNodeFilename(node);

                Hashtable addEntries    = null;
                Hashtable removeEntries = null;
                bool      hasClear      = false;

                foreach (XmlNode child in node.ChildNodes)
                {
                    // skip whitespace and comments
                    // reject nonelements
                    if (HandlerBase.IsIgnorableAlsoCheckForNonElement(child))
                    {
                        continue;
                    }

                    // handle <add>, <remove>, <clear> tags

                    if (child.Name == "add")
                    {
                        string assemblyName = GetAssembly(child);

                        // Check for duplicate lines (ASURT 93151)
                        if (addEntries == null)
                        {
                            addEntries = new Hashtable(new CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture), new CaseInsensitiveComparer(CultureInfo.InvariantCulture));
                        }
                        if (addEntries.ContainsKey(assemblyName))
                        {
                            HandlerBase.ThrowDuplicateLineException(child);
                        }
                        addEntries[assemblyName] = null;

                        if (result._assemblies == null)
                        {
                            result._assemblies = new Hashtable(new CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture), new CaseInsensitiveComparer(CultureInfo.InvariantCulture));
                        }

                        // if key already exists then we might have already loaded it
                        if (result._assemblies.ContainsKey(assemblyName) == false)
                        {
                            if (assemblyName == "*")
                            {
                                AddAllAssembliesFromAppDomainBinDirectory(result, child);
                            }
                            else
                            {
                                // Remember the config file location info, in case an error
                                // occurs later when we try to load the assembly (ASURT 72183)
                                int configFileLine = ConfigurationException.GetXmlNodeLineNumber(child);
                                result._assemblies[assemblyName] = new object[]
                                { configFile, configFileLine, false /*starDirective*/ };
                            }
                        }
                    }
                    else if (child.Name == "remove")
                    {
                        string assemblyName = GetAssembly(child);

                        // Check for duplicate lines (ASURT 93151)
                        if (removeEntries == null)
                        {
                            removeEntries = new Hashtable(new CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture), new CaseInsensitiveComparer(CultureInfo.InvariantCulture));
                        }
                        if (removeEntries.ContainsKey(assemblyName))
                        {
                            HandlerBase.ThrowDuplicateLineException(child);
                        }
                        removeEntries[assemblyName] = null;

                        if (result._assemblies != null)
                        {
                            // If it's a '*' remove everything
                            if (assemblyName == "*")
                            {
                                result._assemblies.Clear();
                            }
                            else
                            {
                                // Otherwise, just remove the one assembly (if present)
                                result._assemblies.Remove(assemblyName);
                            }
                        }
                    }
                    else if (child.Name == "clear")
                    {
                        // Check for duplicate lines (ASURT 93151)
                        if (hasClear)
                        {
                            HandlerBase.ThrowDuplicateLineException(child);
                        }
                        hasClear = true;

                        HandlerBase.CheckForUnrecognizedAttributes(child);
                        HandlerBase.CheckForChildNodes(child);
                        if (result._assemblies != null)
                        {
                            result._assemblies.Clear();
                        }
                    }
                    else
                    {
                        HandlerBase.ThrowUnrecognizedElement(child);
                    }
                }
            }
            internal static object CreateStatic(object inheritedObject, XmlNode node)
            {
                CompilationConfiguration inherited = (CompilationConfiguration)inheritedObject;
                CompilationConfiguration result;

                if (inherited == null)
                {
                    result = new CompilationConfiguration();
                }
                else
                {
                    result = new CompilationConfiguration(inherited);
                }

                //
                // Handle attributes (if they exist)
                //   - tempDirectory - "[directory]"
                //   - debug="true/false"
                //   - strict="true/false"
                //   - explicit="true/false"
                //   - batch="true/false"
                //   - batchtimeout="[time in seconds]"
                //   - maxBatchGeneratedFileSize="[max combined size (in KB) of the generated source files per batched compilation]"
                //   - maxBatchSize="[max number of classes per batched compilation]"
                //   - numRecompilesBeforeAppRestart="[max number of recompilations before appdomain is cycled]"
                //   - defaultLanguage - must be in the list of languages
                //
                XmlNode a = HandlerBase.GetAndRemoveNonEmptyStringAttribute(
                    node, "tempDirectory", ref result._tempDirectory);

                if (a != null)
                {
                    if (!Path.IsPathRooted(result._tempDirectory))
                    {
                        throw new ConfigurationException(
                                  HttpRuntime.FormatResourceString(SR.Invalid_temp_directory), a);
                    }
                }

                HandlerBase.GetAndRemoveBooleanAttribute(node, "debug", ref result._debug);
                HandlerBase.GetAndRemoveBooleanAttribute(node, "strict", ref result._strict);
                HandlerBase.GetAndRemoveBooleanAttribute(node, "explicit", ref result._explicit);
                HandlerBase.GetAndRemoveBooleanAttribute(node, "batch", ref result._batch);
                HandlerBase.GetAndRemovePositiveIntegerAttribute(node, "batchTimeout", ref result._batchTimeout);
                HandlerBase.GetAndRemovePositiveIntegerAttribute(node, "maxBatchGeneratedFileSize", ref result._maxBatchGeneratedFileSize);
                HandlerBase.GetAndRemovePositiveIntegerAttribute(node, "maxBatchSize", ref result._maxBatchSize);
                HandlerBase.GetAndRemovePositiveIntegerAttribute(node, "numRecompilesBeforeAppRestart", ref result._recompilationsBeforeAppRestarts);
                HandlerBase.GetAndRemoveStringAttribute(node, "defaultLanguage", ref result._defaultLanguage);

                HandlerBase.CheckForUnrecognizedAttributes(node);

                //
                // Handle child elements (if they exist)
                //   - compilers
                //   - assemblies
                //
                foreach (XmlNode child in node.ChildNodes)
                {
                    // skip whitespace and comments
                    // reject nonelements
                    if (HandlerBase.IsIgnorableAlsoCheckForNonElement(child))
                    {
                        continue;
                    }

                    // handle <compilers> and <assemblies>
                    if (child.Name == "compilers")
                    {
                        ProcessCompilersElement(result, child);
                    }
                    else if (child.Name == "assemblies")
                    {
                        ProcessAssembliesElement(result, child);
                    }
                    else
                    {
                        HandlerBase.ThrowUnrecognizedElement(child);
                    }
                }

                return(result);
            }