undo
[mono.git] / mcs / class / System.Web / System.Web.UI / TemplateParser.cs
index 409d8ac4166b2cb457bc308066617cc32244aa3f..c3bb9afb900a712e4104c4ad1ef67fb1fa45f393 100644 (file)
@@ -31,6 +31,7 @@
 
 using System.CodeDom.Compiler;
 using System.Collections;
+using System.Collections.Generic;
 using System.ComponentModel;
 using System.Globalization;
 using System.IO;
@@ -43,10 +44,6 @@ using System.Web.Configuration;
 using System.Web.Hosting;
 using System.Web.Util;
 
-#if NET_2_0
-using System.Collections.Generic;
-#endif
-
 namespace System.Web.UI {
        internal class ServerSideScript
        {
@@ -65,15 +62,30 @@ namespace System.Web.UI {
        [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public abstract class TemplateParser : BaseParser
        {
+               [Flags]
+               internal enum OutputCacheParsedParams
+               {
+                       Location               = 0x0001,
+                       CacheProfile           = 0x0002,
+                       NoStore                = 0x0004,
+                       SqlDependency          = 0x0008,
+                       VaryByCustom           = 0x0010,
+                       VaryByHeader           = 0x0020,
+                       VaryByControl          = 0x0040,
+                       VaryByContentEncodings = 0x0080
+               }
+               
                string inputFile;
                string text;
                Hashtable mainAttributes;
                ArrayList dependencies;
                ArrayList assemblies;
                Hashtable anames;
-               ArrayList imports;
-               ArrayList interfaces;
-               ArrayList scripts;
+               string[] binDirAssemblies;
+               Dictionary <string, bool> namespacesCache;
+               Dictionary <string, bool> imports;
+               List <string> interfaces;
+               List <ServerSideScript> scripts;
                Type baseType;
                bool baseTypeIsGlobal = true;
                string className;
@@ -88,13 +100,16 @@ namespace System.Web.UI {
                bool output_cache;
                int oc_duration;
                string oc_header, oc_custom, oc_param, oc_controls;
-#if NET_2_0
-               string oc_content_encodings;
-#endif
+               string oc_content_encodings, oc_cacheprofile, oc_sqldependency;
+               bool oc_nostore;
+               OutputCacheParsedParams oc_parsed_params = 0;
                bool oc_shared;
                OutputCacheLocation oc_location;
-               CultureInfo invariantCulture = CultureInfo.InvariantCulture;
-#if NET_2_0
+
+               // Kludge needed to support pre-parsing of the main directive (see
+               // AspNetGenerator.GetRootBuilderType)
+               internal int allowedMainDirectives = 0;
+               
                byte[] md5checksum;
                string src;
                bool srcIsLegacy;
@@ -102,69 +117,26 @@ namespace System.Web.UI {
                string codeFileBaseClass;
                string metaResourceKey;
                Type codeFileBaseClassType;
-               string pageParserFilterTypeName;
                Type pageParserFilterType;
                PageParserFilter pageParserFilter;
                
                List <UnknownAttributeDescriptor> unknownMainAttributes;
                Stack <string> includeDirs;
                List <string> registeredTagNames;
-#else
-               Stack includeDirs;
-               Assembly srcAssembly;           
-#endif
                ILocation directiveLocation;
                
                int appAssemblyIndex = -1;
 
                internal TemplateParser ()
                {
+                       imports = new Dictionary <string, bool> (StringComparer.Ordinal);
                        LoadConfigDefaults ();
-                       
-                       imports = new ArrayList ();
-#if NET_2_0
-                       AddNamespaces (imports);
-#else
-                       imports.Add ("System");
-                       imports.Add ("System.Collections");
-                       imports.Add ("System.Collections.Specialized");
-                       imports.Add ("System.Configuration");
-                       imports.Add ("System.Text");
-                       imports.Add ("System.Text.RegularExpressions");
-                       imports.Add ("System.Web");
-                       imports.Add ("System.Web.Caching");
-                       imports.Add ("System.Web.Security");
-                       imports.Add ("System.Web.SessionState");
-                       imports.Add ("System.Web.UI");
-                       imports.Add ("System.Web.UI.WebControls");
-                       imports.Add ("System.Web.UI.HtmlControls");
-#endif
-
                        assemblies = new ArrayList ();
-#if NET_2_0
                        CompilationSection compConfig = CompilationConfig;
-                       
-                       bool addAssembliesInBin = false;
                        foreach (AssemblyInfo info in compConfig.Assemblies) {
-                               if (info.Assembly == "*")
-                                       addAssembliesInBin = true;
-                               else
+                               if (info.Assembly != "*")
                                        AddAssemblyByName (info.Assembly);
                        }
-                       if (addAssembliesInBin)
-                               AddAssembliesInBin ();
-
-                       foreach (NamespaceInfo info in PagesConfig.Namespaces) {
-                               imports.Add (info.Namespace);
-                       }
-#else
-                       CompilationConfiguration compConfig = CompilationConfig;
-                       
-                       foreach (string a in compConfig.Assemblies)
-                               AddAssemblyByName (a);
-                       if (compConfig.AssembliesInBin)
-                               AddAssembliesInBin ();
-#endif
 
                        language = compConfig.DefaultLanguage;
                        implicitLanguage = true;
@@ -172,10 +144,8 @@ namespace System.Web.UI {
 
                internal virtual void LoadConfigDefaults ()
                {
+                       AddNamespaces (imports);
                        debug = CompilationConfig.Debug;
-#if NET_2_0
-                       pageParserFilterTypeName = PagesConfig.PageParserFilterType;
-#endif
                }
                
                internal void AddApplicationAssembly ()
@@ -191,7 +161,6 @@ namespace System.Web.UI {
 
                protected abstract Type CompileIntoType ();
 
-#if NET_2_0
                internal void AddControl (Type type, IDictionary attributes)
                {
                        AspGenerator generator = AspGenerator;
@@ -200,30 +169,32 @@ namespace System.Web.UI {
                        generator.AddControl (type, attributes);
                }
                
-               void AddNamespaces (ArrayList imports)
+               void AddNamespaces (Dictionary <string, bool> imports)
                {
                        if (BuildManager.HaveResources)
-                               imports.Add ("System.Resources");
+                               imports.Add ("System.Resources", true);
                        
-                       PagesSection pages = WebConfigurationManager.GetWebApplicationSection ("system.web/pages") as PagesSection;
+                       PagesSection pages = PagesConfig;
                        if (pages == null)
                                return;
 
                        NamespaceCollection namespaces = pages.Namespaces;
                        if (namespaces == null || namespaces.Count == 0)
                                return;
-
-                       foreach (NamespaceInfo nsi in namespaces)
-                               imports.Add (nsi.Namespace);
+                       
+                       foreach (NamespaceInfo nsi in namespaces) {
+                               string ns = nsi.Namespace;
+                               if (imports.ContainsKey (ns))
+                                       continue;
+                               
+                               imports.Add (ns, true);
+                       }
                }
-#endif
                
                internal void RegisterCustomControl (string tagPrefix, string tagName, string src)
                 {
                         string realpath = null;
                        bool fileExists = false;
-                       
-#if NET_2_0
                        VirtualFile vf = null;
                        VirtualPathProvider vpp = HostingEnvironment.VirtualPathProvider;
                        VirtualPath vp = new VirtualPath (src, BaseVirtualDir);
@@ -235,37 +206,18 @@ namespace System.Web.UI {
                                if (vf != null)
                                        realpath = MapPath (vf.VirtualPath);
                        }
-#else
-                       realpath = MapPath (src);
-                       fileExists = File.Exists (realpath);
-#endif
+
                        if (!fileExists)
                                ThrowParseFileNotFound (src);
 
-                       if (String.Compare (realpath, inputFile, false, invariantCulture) == 0)
+                       if (String.Compare (realpath, inputFile, false, Helpers.InvariantCulture) == 0)
                                 return;
                        
-#if NET_2_0
                        string vpath = vf.VirtualPath;
-#else
-                       string vpath = VirtualPathUtility.Combine (BaseVirtualDir, src);
-                       if (VirtualPathUtility.IsAbsolute (vpath))
-                               vpath = VirtualPathUtility.ToAppRelative (vpath);
-#endif
                         
                         try {
-#if NET_2_0
                                RegisterTagName (tagPrefix + ":" + tagName);
                                RootBuilder.Foundry.RegisterFoundry (tagPrefix, tagName, vpath);
-#else
-                               Type type = null;
-                               ArrayList other_deps = new ArrayList ();
-                                type = UserControlParser.GetCompiledType (vpath, realpath, other_deps, Context);
-                               foreach (string s in other_deps)
-                                        AddDependency (s);
-                               AddAssembly (type.Assembly, true);
-                               RootBuilder.Foundry.RegisterFoundry (tagPrefix, tagName, type);
-#endif
                                AddDependency (vpath);
                         } catch (ParseException pe) {
                                 if (this is UserControlParser)
@@ -299,21 +251,27 @@ namespace System.Web.UI {
                
                internal virtual void AddDirective (string directive, Hashtable atts)
                {
-#if NET_2_0
                        var pageParserFilter = PageParserFilter;
-                       if (pageParserFilter != null)
-                               pageParserFilter.PreprocessDirective (directive.ToLower (CultureInfo.InvariantCulture), atts);
-#endif
-                       if (String.Compare (directive, DefaultDirectiveName, true) == 0) {
-                               if (mainAttributes != null)
+                       if (String.Compare (directive, DefaultDirectiveName, true, Helpers.InvariantCulture) == 0) {
+                               bool allowMainDirective = allowedMainDirectives > 0;
+                               
+                               if (mainAttributes != null && !allowMainDirective)
                                        ThrowParseException ("Only 1 " + DefaultDirectiveName + " is allowed");
 
+                               allowedMainDirectives--;
+                               if (mainAttributes != null)
+                                       return;
+                               
+                               if (pageParserFilter != null)
+                                       pageParserFilter.PreprocessDirective (directive.ToLower (Helpers.InvariantCulture), atts);
+                               
                                mainAttributes = atts;
                                ProcessMainAttributes (mainAttributes);
                                return;
-                       }
-
-                       int cmp = String.Compare ("Assembly", directive, true);
+                       } else if (pageParserFilter != null)
+                               pageParserFilter.PreprocessDirective (directive.ToLower (Helpers.InvariantCulture), atts);
+                               
+                       int cmp = String.Compare ("Assembly", directive, true, Helpers.InvariantCulture);
                        if (cmp == 0) {
                                string name = GetString (atts, "Name", null);
                                string src = GetString (atts, "Src", null);
@@ -336,18 +294,17 @@ namespace System.Web.UI {
                                return;
                        }
 
-                       cmp = String.Compare ("Import", directive, true);
+                       cmp = String.Compare ("Import", directive, true, Helpers.InvariantCulture);
                        if (cmp == 0) {
                                string namesp = GetString (atts, "Namespace", null);
                                if (atts.Count > 0)
                                        ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
                                
-                               if (namesp != null && namesp != "")
-                                       AddImport (namesp);
+                               AddImport (namesp);
                                return;
                        }
 
-                       cmp = String.Compare ("Implements", directive, true);
+                       cmp = String.Compare ("Implements", directive, true, Helpers.InvariantCulture);
                        if (cmp == 0) {
                                string ifacename = GetString (atts, "Interface", "");
 
@@ -365,7 +322,7 @@ namespace System.Web.UI {
                                return;
                        }
 
-                       cmp = String.Compare ("OutputCache", directive, true);
+                       cmp = String.Compare ("OutputCache", directive, true, Helpers.InvariantCulture);
                        if (cmp == 0) {
                                HttpResponse response = HttpContext.Current.Response;
                                if (response != null)
@@ -382,28 +339,53 @@ namespace System.Web.UI {
 
                                foreach (DictionaryEntry entry in atts) {
                                        string key = (string) entry.Key;
-                                       switch (key.ToLower ()) {
+                                       if (key == null)
+                                               continue;
+                                       
+                                       switch (key.ToLower (Helpers.InvariantCulture)) {
                                                case "duration":
                                                        oc_duration = Int32.Parse ((string) entry.Value);
                                                        if (oc_duration < 1)
                                                                ThrowParseException ("The 'duration' attribute must be set " +
                                                                                     "to a positive integer value");
                                                        break;
-#if NET_2_0
+
+                                               case "sqldependency":
+                                                       oc_sqldependency = (string) entry.Value;
+                                                       break;
+                                                       
+                                               case "nostore":
+                                                       try {
+                                                               oc_nostore = Boolean.Parse ((string) entry.Value);
+                                                               oc_parsed_params |= OutputCacheParsedParams.NoStore;
+                                                       } catch {
+                                                               ThrowParseException ("The 'NoStore' attribute is case sensitive" +
+                                                                                    " and must be set to 'true' or 'false'.");
+                                                       }
+                                                       break;
+
+                                               case "cacheprofile":
+                                                       oc_cacheprofile = (string) entry.Value;
+                                                       oc_parsed_params |= OutputCacheParsedParams.CacheProfile;
+                                                       break;
+                                                       
                                                case "varybycontentencodings":
                                                        oc_content_encodings = (string) entry.Value;
+                                                       oc_parsed_params |= OutputCacheParsedParams.VaryByContentEncodings;
                                                        break;
-#endif
+
                                                case "varybyparam":
                                                        oc_param = (string) entry.Value;
-                                                       if (String.Compare (oc_param, "none") == 0)
+                                                       if (String.Compare (oc_param, "none", true, Helpers.InvariantCulture) == 0)
                                                                oc_param = null;
                                                        break;
                                                case "varybyheader":
                                                        oc_header = (string) entry.Value;
+                                                       oc_parsed_params |= OutputCacheParsedParams.VaryByHeader;
                                                        break;
                                                case "varybycustom":
                                                        oc_custom = (string) entry.Value;
+                                                       oc_parsed_params |= OutputCacheParsedParams.VaryByCustom;
                                                        break;
                                                case "location":
                                                        if (!(this is PageParser))
@@ -412,6 +394,7 @@ namespace System.Web.UI {
                                                        try {
                                                                oc_location = (OutputCacheLocation) Enum.Parse (
                                                                        typeof (OutputCacheLocation), (string) entry.Value, true);
+                                                               oc_parsed_params |= OutputCacheParsedParams.Location;
                                                        } catch {
                                                                ThrowParseException ("The 'location' attribute is case sensitive and " +
                                                                                     "must be one of the following values: Any, Client, " +
@@ -419,11 +402,8 @@ namespace System.Web.UI {
                                                        }
                                                        break;
                                                case "varybycontrol":
-#if ONLY_1_1
-                                                       if (this is PageParser)
-                                                               goto default;
-#endif
                                                        oc_controls = (string) entry.Value;
+                                                       oc_parsed_params |= OutputCacheParsedParams.VaryByControl;
                                                        break;
                                                case "shared":
                                                        if (this is PageParser)
@@ -469,16 +449,10 @@ namespace System.Web.UI {
                        return type;
                }
 
-               void AddAssembliesInBin ()
-               {
-                       foreach (string s in HttpApplication.BinDirectoryAssemblies)
-                               assemblies.Add (s);
-               }
-               
                internal virtual void AddInterface (string iface)
                {
                        if (interfaces == null)
-                               interfaces = new ArrayList ();
+                               interfaces = new List <string> ();
 
                        if (!interfaces.Contains (iface))
                                interfaces.Add (iface);
@@ -486,13 +460,73 @@ namespace System.Web.UI {
                
                internal virtual void AddImport (string namesp)
                {
+                       if (namesp == null || namesp.Length == 0)
+                               return;
+                       
                        if (imports == null)
-                               imports = new ArrayList ();
+                               imports = new Dictionary <string, bool> (StringComparer.Ordinal);
+                       
+                       if (imports.ContainsKey (namesp))
+                               return;
+                       
+                       imports.Add (namesp, true);
+                       AddAssemblyForNamespace (namesp);
+               }
+
+               void AddAssemblyForNamespace (string namesp)
+               {
+                       if (binDirAssemblies == null)
+                               binDirAssemblies = HttpApplication.BinDirectoryAssemblies;
+                       if (binDirAssemblies.Length == 0)
+                               return;
+
+                       if (namespacesCache == null)
+                               namespacesCache = new Dictionary <string, bool> ();
+                       else if (namespacesCache.ContainsKey (namesp))
+                               return;
+                       
+                       foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ())
+                               if (FindNamespaceInAssembly (asm, namesp))
+                                       return;
+                       
+                       IList tla = BuildManager.TopLevelAssemblies;
+                       if (tla != null && tla.Count > 0) {
+                               foreach (Assembly asm in tla) {
+                                       if (FindNamespaceInAssembly (asm, namesp))
+                                               return;
+                               }
+                       }
 
-                       if (!imports.Contains (namesp))
-                               imports.Add (namesp);
+                       Assembly a;
+                       foreach (string s in binDirAssemblies) {
+                               a = Assembly.LoadFrom (s);
+                               if (FindNamespaceInAssembly (a, namesp))
+                                       return;
+                       }
                }
 
+               bool FindNamespaceInAssembly (Assembly asm, string namesp)
+               {
+                       Type[] asmTypes;
+
+                       try {
+                               asmTypes = asm.GetTypes ();
+                       } catch (ReflectionTypeLoadException) {
+                               // ignore
+                               return false;
+                       }
+                       
+                       foreach (Type type in asmTypes) {
+                               if (String.Compare (type.Namespace, namesp, StringComparison.Ordinal) == 0) {
+                                       namespacesCache.Add (namesp, true);
+                                       AddAssembly (asm, true);
+                                       return true;
+                               }
+                       }
+
+                       return false;
+               }
+               
                internal virtual void AddSourceDependency (string filename)
                {
                        if (dependencies != null && dependencies.Contains (filename))
@@ -590,19 +624,12 @@ namespace System.Web.UI {
                internal virtual void ProcessMainAttributes (Hashtable atts)
                {
                        directiveLocation = new System.Web.Compilation.Location (Location);
-                       
-#if NET_2_0
                        CompilationSection compConfig;
-#else
-                       CompilationConfiguration compConfig;
-#endif
 
                        compConfig = CompilationConfig;
                        
                        atts.Remove ("Description"); // ignored
-#if NET_1_1
                        atts.Remove ("CodeBehind");  // ignored
-#endif
                        atts.Remove ("AspCompat"); // ignored
                        
                        debug = GetBool (atts, "Debug", compConfig.Debug);
@@ -617,9 +644,8 @@ namespace System.Web.UI {
                        explicitOn = GetBool (atts, "Explicit", compConfig.Explicit);
                        if (atts.ContainsKey ("LinePragmas"))
                                linePragmasOn = GetBool (atts, "LinePragmas", true);
-                       
+
                        string inherits = GetString (atts, "Inherits", null);
-#if NET_2_0
                        string srcRealPath = null;
                        
                        // In ASP 2, the source file is actually integrated with
@@ -684,15 +710,7 @@ namespace System.Web.UI {
                                // Single-Page model.
                                SetBaseType (inherits);
                        }
-#else
-                       string src = GetString (atts, "Src", null);
 
-                       if (src != null)
-                               srcAssembly = GetAssemblyFromSource (src);
-                       
-                       if (inherits != null)
-                               SetBaseType (inherits);
-#endif
                        if (src != null) {
                                if (VirtualPathUtility.IsAbsolute (src))
                                        src = VirtualPathUtility.ToAppRelative (src);
@@ -701,20 +719,13 @@ namespace System.Web.UI {
                        
                        className = GetString (atts, "ClassName", null);
                        if (className != null) {
-#if NET_2_0
                                string [] identifiers = className.Split ('.');
                                for (int i = 0; i < identifiers.Length; i++)
                                        if (!CodeGenerator.IsValidLanguageIndependentIdentifier (identifiers [i]))
                                                ThrowParseException (String.Format ("'{0}' is not a valid "
                                                        + "value for attribute 'classname'.", className));
-#else
-                               if (!CodeGenerator.IsValidLanguageIndependentIdentifier (className))
-                                       ThrowParseException (String.Format ("'{0}' is not a valid "
-                                               + "value for attribute 'classname'.", className));
-#endif
                        }
 
-#if NET_2_0
                        if (this is TemplateControlParser)
                                metaResourceKey = GetString (atts, "meta:resourcekey", null);
                        
@@ -733,12 +744,11 @@ namespace System.Web.UI {
                                }
                                return;
                        }
-#endif
+
                        if (atts.Count > 0)
                                ThrowParseException ("Unknown attribute: " + GetOneKey (atts));
                }
 
-#if NET_2_0
                void RegisterTagName (string tagName)
                {
                        if (registeredTagNames == null)
@@ -754,7 +764,7 @@ namespace System.Web.UI {
                {
                        MemberInfo mi = null;
                        bool missing = false;
-                       string memberName = name.Trim ().ToLower (CultureInfo.InvariantCulture);
+                       string memberName = name.Trim ().ToLower (Helpers.InvariantCulture);
                        Type parent = codeFileBaseClassType;
 
                        if (parent == null)
@@ -821,7 +831,6 @@ namespace System.Web.UI {
                        UnknownAttributeDescriptor desc = new UnknownAttributeDescriptor (mi, value);
                        unknownMainAttributes.Add (desc);
                }
-#endif
                
                internal void SetBaseType (string type)
                {
@@ -832,16 +841,7 @@ namespace System.Web.UI {
                                parent = null;
 
                        if (parent == null) {
-#if NET_2_0                    
                                parent = LoadType (type);
-#else
-                               parent = null;
-                               if (srcAssembly != null)
-                                       parent = srcAssembly.GetType (type);
-
-                               if (parent == null)
-                                       parent = LoadType (type);
-#endif                         
 
                                if (parent == null)
                                        ThrowParseException ("Cannot find type " + type);
@@ -850,11 +850,9 @@ namespace System.Web.UI {
                                        ThrowParseException ("The parent type '" + type + "' does not derive from " + DefaultBaseType);
                        }
 
-#if NET_2_0
                        var pageParserFilter = PageParserFilter;
                        if (pageParserFilter != null && !pageParserFilter.AllowBaseType (parent))
                                throw new HttpException ("Base type '" + parent + "' is not allowed.");
-#endif
                        
                        baseType = parent;
                }
@@ -867,13 +865,8 @@ namespace System.Web.UI {
 
                internal void PushIncludeDir (string dir)
                {
-                       if (includeDirs == null) {
-#if NET_2_0
+                       if (includeDirs == null)
                                includeDirs = new Stack <string> (1);
-#else
-                               includeDirs = new Stack (1);
-#endif
-                       }
 
                        includeDirs.Push (dir);
                }
@@ -896,8 +889,6 @@ namespace System.Web.UI {
                        AddSourceDependency (vpath);
                        
                        CompilerResults result;
-
-#if NET_2_0
                        string tmp;
                        CompilerParameters parameters;
                        CodeDomProvider provider = BaseCompiler.CreateProvider (HttpContext.Current, language, out parameters, out tmp);
@@ -909,9 +900,7 @@ namespace System.Web.UI {
                        abuilder.AddAssemblyReference (BuildManager.GetReferencedAssemblies () as List <Assembly>);
                        abuilder.AddCodeFile (realPath);
                        result = abuilder.BuildAssembly (new VirtualPath (vpath));
-#else
-                       result = CachingCompiler.Compile (language, realPath, realPath, assemblies, Debug);
-#endif
+
                        if (result.NativeCompilerReturnValue != 0) {
                                using (StreamReader reader = new StreamReader (realPath)) {
                                        throw new CompilationException (realPath, result.Errors, reader.ReadToEnd ());
@@ -929,40 +918,40 @@ namespace System.Web.UI {
                        get { return linePragmasOn; }
                }
                
-#if NET_2_0
                internal byte[] MD5Checksum {
                        get { return md5checksum; }
                        set { md5checksum = value; }
                }
 
-               internal string PageParserFilterTypeName {
-                       get { return pageParserFilterTypeName; }
-               }
-
                internal PageParserFilter PageParserFilter {
                        get {
                                if (pageParserFilter != null)
                                        return pageParserFilter;
-                               
-                               if (String.IsNullOrEmpty (pageParserFilterTypeName))
-                                       return null;
 
-                               pageParserFilter = Activator.CreateInstance (PageParserFilterType) as PageParserFilter;
-                               pageParserFilter.Initialize (VirtualPath, this);
+                               Type t = PageParserFilterType;
+                               if (t == null)
+                                       return null;
                                
+                               pageParserFilter = Activator.CreateInstance (t) as PageParserFilter;
+                               pageParserFilter.Initialize (this);
+
                                return pageParserFilter;
                        }
                }
                
                internal Type PageParserFilterType {
                        get {
-                               if (pageParserFilterType == null)
-                                       pageParserFilterType = Type.GetType (PageParserFilterTypeName, true);
-
+                               if (pageParserFilterType == null) {
+                                       string typeName = PagesConfig.PageParserFilterType;
+                                       if (String.IsNullOrEmpty (typeName))
+                                               return null;
+                                       
+                                       pageParserFilterType = HttpApplication.LoadType (typeName, true);
+                               }
+                               
                                return pageParserFilterType;
                        }
                }
-#endif
                
                internal Type DefaultBaseType {
                        get {
@@ -975,14 +964,7 @@ namespace System.Web.UI {
                internal ILocation DirectiveLocation {
                        get { return directiveLocation; }
                }
-
-#if NET_2_0
-               internal VirtualPath VirtualPath {
-                       get;
-                       set;
-               }
-#endif
-
+               
                internal string ParserDir {
                        get {
                                if (includeDirs == null || includeDirs.Count == 0)
@@ -998,7 +980,6 @@ namespace System.Web.UI {
                        set { inputFile = value; }
                }
 
-#if NET_2_0
                internal bool IsPartial {
                        get { return (!srcIsLegacy && src != null); }
                }
@@ -1033,7 +1014,6 @@ namespace System.Web.UI {
                {
                        get { return unknownMainAttributes; }
                }
-#endif
 
                internal string Text {
                        get { return text; }
@@ -1054,9 +1034,7 @@ namespace System.Web.UI {
                        set { baseTypeIsGlobal = value; }
                }
 
-#if NET_2_0
                static long autoClassCounter = 0;
-#endif
 
                internal string EncodeIdentifier (string value)
                {
@@ -1118,7 +1096,6 @@ namespace System.Web.UI {
                                if (className != null)
                                        return className;
 
-#if NET_2_0
                                string physPath = HttpContext.Current.Request.PhysicalApplicationPath;
                                string inFile;
                                
@@ -1143,28 +1120,31 @@ namespace System.Web.UI {
                                }
                                
                                if (StrUtils.StartsWith (inFile, physPath))
-                                       className = inputFile.Substring (physPath.Length).ToLower (CultureInfo.InvariantCulture);
+                                       className = inputFile.Substring (physPath.Length).ToLower (Helpers.InvariantCulture);
                                else
-#endif
                                        className = Path.GetFileName (inputFile);
                                className = EncodeIdentifier (className);
                                return className;
                        }
                }
 
-               internal ArrayList Scripts {
+               internal List <ServerSideScript> Scripts {
                        get {
                                if (scripts == null)
-                                       scripts = new ArrayList ();
+                                       scripts = new List <ServerSideScript> ();
 
                                return scripts;
                        }
                }
 
-               internal ArrayList Imports {
+               internal Dictionary <string, bool> Imports {
                        get { return imports; }
                }
 
+               internal List <string> Interfaces {
+                       get { return interfaces; }
+               }
+               
                internal ArrayList Assemblies {
                        get {
                                if (appAssemblyIndex != -1) {
@@ -1178,12 +1158,16 @@ namespace System.Web.UI {
                        }
                }
 
-               internal ArrayList Interfaces {
-                       get { return interfaces; }
-               }
-
                internal RootBuilder RootBuilder {
-                       get { return rootBuilder; }
+                       get {
+                               if (rootBuilder != null)
+                                       return rootBuilder;
+                               AspGenerator generator = AspGenerator;
+                               if (generator != null)
+                                       rootBuilder = generator.RootBuilder;
+
+                               return rootBuilder;
+                       }
                        set { rootBuilder = value; }
                }
 
@@ -1224,16 +1208,30 @@ namespace System.Web.UI {
                        get { return oc_duration; }
                }
 
-#if NET_2_0
+               internal OutputCacheParsedParams OutputCacheParsedParameters {
+                       get { return oc_parsed_params; }
+               }
+
+               internal string OutputCacheSqlDependency {
+                       get { return oc_sqldependency; }
+               }
+               
+               internal string OutputCacheCacheProfile {
+                       get { return oc_cacheprofile; }
+               }
+               
                internal string OutputCacheVaryByContentEncodings {
                        get { return oc_content_encodings; }
                }
 
+               internal bool OutputCacheNoStore {
+                       get { return oc_nostore; }
+               }
+               
                internal virtual TextReader Reader {
                        get { return null; }
                        set { /* no-op */ }
                }
-#endif
                
                internal string OutputCacheVaryByHeader {
                        get { return oc_header; }
@@ -1259,26 +1257,17 @@ namespace System.Web.UI {
                        get { return oc_param; }
                }
 
-#if NET_2_0
                internal List <string> RegisteredTagNames {
                        get { return registeredTagNames; }
                }
                
                internal PagesSection PagesConfig {
-                       get {
-                               return WebConfigurationManager.GetWebApplicationSection ("system.web/pages") as PagesSection;
-                       }
+                       get { return GetConfigSection <PagesSection> ("system.web/pages") as PagesSection; }
                }
 
                internal AspGenerator AspGenerator {
                        get;
                        set;
                }
-#else
-               internal PagesConfiguration PagesConfig {
-                       get { return PagesConfiguration.GetInstance (Context); }
-               }
-#endif
        }
-}
-
+}
\ No newline at end of file