Performance improvements:
[mono.git] / mcs / class / System.Web / System.Web.UI / TemplateParser.cs
1 //
2 // System.Web.UI.TemplateParser
3 //
4 // Authors:
5 //      Duncan Mak (duncan@ximian.com)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //      Marek Habersack (mhabersack@novell.com)
8 //
9 // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
10 // Copyright (C) 2005-2008 Novell, Inc (http://www.novell.com)
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System.CodeDom.Compiler;
33 using System.Collections;
34 using System.ComponentModel;
35 using System.Globalization;
36 using System.IO;
37 using System.Reflection;
38 using System.Security.Permissions;
39 using System.Text;
40 using System.Threading;
41 using System.Web.Compilation;
42 using System.Web.Configuration;
43 using System.Web.Hosting;
44 using System.Web.Util;
45
46 #if NET_2_0
47 using System.Collections.Generic;
48 #endif
49
50 namespace System.Web.UI {
51         internal class ServerSideScript
52         {
53                 public readonly string Script;
54                 public readonly ILocation Location;
55                 
56                 public ServerSideScript (string script, ILocation location)
57                 {
58                         Script = script;
59                         Location = location;
60                 }
61         }
62         
63         // CAS
64         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
65         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
66         public abstract class TemplateParser : BaseParser
67         {
68 #if NET_2_0
69                 [Flags]
70                 internal enum OutputCacheParsedParams
71                 {
72                         Location               = 0x0001,
73                         CacheProfile           = 0x0002,
74                         NoStore                = 0x0004,
75                         SqlDependency          = 0x0008,
76                         VaryByCustom           = 0x0010,
77                         VaryByHeader           = 0x0020,
78                         VaryByControl          = 0x0040,
79                         VaryByContentEncodings = 0x0080
80                 }
81 #endif
82                 
83                 string inputFile;
84                 string text;
85                 Hashtable mainAttributes;
86                 ArrayList dependencies;
87                 ArrayList assemblies;
88                 Hashtable anames;
89 #if NET_2_0
90                 string[] binDirAssemblies;
91                 Dictionary <string, bool> namespacesCache;
92                 List <string> imports;
93                 List <string> interfaces;
94                 List <ServerSideScript> scripts;
95 #else
96                 ArrayList imports;
97                 ArrayList interfaces;
98                 ArrayList scripts;
99 #endif
100                 Type baseType;
101                 bool baseTypeIsGlobal = true;
102                 string className;
103                 RootBuilder rootBuilder;
104                 bool debug;
105                 string compilerOptions;
106                 string language;
107                 bool implicitLanguage;
108                 bool strictOn ;
109                 bool explicitOn;
110                 bool linePragmasOn = true;
111                 bool output_cache;
112                 int oc_duration;
113                 string oc_header, oc_custom, oc_param, oc_controls;
114 #if NET_2_0
115                 string oc_content_encodings, oc_cacheprofile, oc_sqldependency;
116                 bool oc_nostore;
117                 OutputCacheParsedParams oc_parsed_params = 0;
118 #endif
119                 bool oc_shared;
120                 OutputCacheLocation oc_location;
121 #if NET_2_0
122                 // Kludge needed to support pre-parsing of the main directive (see
123                 // AspNetGenerator.GetRootBuilderType)
124                 internal int allowedMainDirectives = 0;
125                 
126                 byte[] md5checksum;
127                 string src;
128                 bool srcIsLegacy;
129                 string partialClassName;
130                 string codeFileBaseClass;
131                 string metaResourceKey;
132                 Type codeFileBaseClassType;
133                 Type pageParserFilterType;
134                 PageParserFilter pageParserFilter;
135                 
136                 List <UnknownAttributeDescriptor> unknownMainAttributes;
137                 Stack <string> includeDirs;
138                 List <string> registeredTagNames;
139 #else
140                 Stack includeDirs;
141                 Assembly srcAssembly;           
142 #endif
143                 ILocation directiveLocation;
144                 
145                 int appAssemblyIndex = -1;
146
147                 internal TemplateParser ()
148                 {
149                         LoadConfigDefaults ();
150 #if NET_2_0
151                         imports = new List <string> ();
152                         AddNamespaces (imports);
153 #else
154                         imports = new ArrayList ();
155                         imports.Add ("System");
156                         imports.Add ("System.Collections");
157                         imports.Add ("System.Collections.Specialized");
158                         imports.Add ("System.Configuration");
159                         imports.Add ("System.Text");
160                         imports.Add ("System.Text.RegularExpressions");
161                         imports.Add ("System.Web");
162                         imports.Add ("System.Web.Caching");
163                         imports.Add ("System.Web.Security");
164                         imports.Add ("System.Web.SessionState");
165                         imports.Add ("System.Web.UI");
166                         imports.Add ("System.Web.UI.WebControls");
167                         imports.Add ("System.Web.UI.HtmlControls");
168 #endif
169
170                         assemblies = new ArrayList ();
171 #if NET_2_0
172                         CompilationSection compConfig = CompilationConfig;
173                         foreach (AssemblyInfo info in compConfig.Assemblies) {
174                                 if (info.Assembly != "*")
175                                         AddAssemblyByName (info.Assembly);
176                         }
177
178                         foreach (NamespaceInfo info in PagesConfig.Namespaces) {
179                                 imports.Add (info.Namespace);
180                         }
181 #else
182                         CompilationConfiguration compConfig = CompilationConfig;
183                         
184                         foreach (string a in compConfig.Assemblies)
185                                 AddAssemblyByName (a);
186                         if (compConfig.AssembliesInBin)
187                                 AddAssembliesInBin ();
188 #endif
189
190                         language = compConfig.DefaultLanguage;
191                         implicitLanguage = true;
192                 }
193
194                 internal virtual void LoadConfigDefaults ()
195                 {
196                         debug = CompilationConfig.Debug;
197                 }
198                 
199                 internal void AddApplicationAssembly ()
200                 {
201                         if (Context.ApplicationInstance == null)
202                                 return; // this may happen if we have Global.asax and have
203                                         // controls registered from Web.Config
204                         string location = Context.ApplicationInstance.AssemblyLocation;
205                         if (location != typeof (TemplateParser).Assembly.Location) {
206                                 appAssemblyIndex = assemblies.Add (location);
207                         }
208                 }
209
210                 protected abstract Type CompileIntoType ();
211
212 #if NET_2_0
213                 internal void AddControl (Type type, IDictionary attributes)
214                 {
215                         AspGenerator generator = AspGenerator;
216                         if (generator == null)
217                                 return;
218                         generator.AddControl (type, attributes);
219                 }
220                 
221                 void AddNamespaces (List <string> imports)
222                 {
223                         if (BuildManager.HaveResources)
224                                 imports.Add ("System.Resources");
225                         
226                         PagesSection pages = PagesConfig;
227                         if (pages == null)
228                                 return;
229
230                         NamespaceCollection namespaces = pages.Namespaces;
231                         if (namespaces == null || namespaces.Count == 0)
232                                 return;
233
234                         foreach (NamespaceInfo nsi in namespaces)
235                                 imports.Add (nsi.Namespace);
236                 }
237 #endif
238                 
239                 internal void RegisterCustomControl (string tagPrefix, string tagName, string src)
240                 {
241                         string realpath = null;
242                         bool fileExists = false;
243                         
244 #if NET_2_0
245                         VirtualFile vf = null;
246                         VirtualPathProvider vpp = HostingEnvironment.VirtualPathProvider;
247                         VirtualPath vp = new VirtualPath (src, BaseVirtualDir);
248                         string vpAbsolute = vp.Absolute;
249                         
250                         if (vpp.FileExists (vpAbsolute)) {
251                                 fileExists = true;
252                                 vf = vpp.GetFile (vpAbsolute);
253                                 if (vf != null)
254                                         realpath = MapPath (vf.VirtualPath);
255                         }
256 #else
257                         realpath = MapPath (src);
258                         fileExists = File.Exists (realpath);
259 #endif
260                         if (!fileExists)
261                                 ThrowParseFileNotFound (src);
262
263                         if (String.Compare (realpath, inputFile, false, Helpers.InvariantCulture) == 0)
264                                 return;
265                         
266 #if NET_2_0
267                         string vpath = vf.VirtualPath;
268 #else
269                         string vpath = VirtualPathUtility.Combine (BaseVirtualDir, src);
270                         if (VirtualPathUtility.IsAbsolute (vpath))
271                                 vpath = VirtualPathUtility.ToAppRelative (vpath);
272 #endif
273                         
274                         try {
275 #if NET_2_0
276                                 RegisterTagName (tagPrefix + ":" + tagName);
277                                 RootBuilder.Foundry.RegisterFoundry (tagPrefix, tagName, vpath);
278 #else
279                                 Type type = null;
280                                 ArrayList other_deps = new ArrayList ();
281                                 type = UserControlParser.GetCompiledType (vpath, realpath, other_deps, Context);
282                                 foreach (string s in other_deps)
283                                         AddDependency (s);
284                                 AddAssembly (type.Assembly, true);
285                                 RootBuilder.Foundry.RegisterFoundry (tagPrefix, tagName, type);
286 #endif
287                                 AddDependency (vpath);
288                         } catch (ParseException pe) {
289                                 if (this is UserControlParser)
290                                         throw new ParseException (Location, pe.Message, pe);
291                                 throw;
292                         }
293                 }
294
295                 internal void RegisterNamespace (string tagPrefix, string ns, string assembly)
296                 {
297                         AddImport (ns);
298                         Assembly ass = null;
299                         
300                         if (assembly != null && assembly.Length > 0)
301                                 ass = AddAssemblyByName (assembly);
302                         
303                         RootBuilder.Foundry.RegisterFoundry (tagPrefix, ass, ns);
304                 }
305
306                 internal virtual void HandleOptions (object obj)
307                 {
308                 }
309
310                 internal static string GetOneKey (Hashtable tbl)
311                 {
312                         foreach (object key in tbl.Keys)
313                                 return key.ToString ();
314
315                         return null;
316                 }
317                 
318                 internal virtual void AddDirective (string directive, Hashtable atts)
319                 {
320 #if NET_2_0
321                         var pageParserFilter = PageParserFilter;
322 #endif
323                         if (String.Compare (directive, DefaultDirectiveName, true, Helpers.InvariantCulture) == 0) {
324 #if NET_2_0
325                                 bool allowMainDirective = allowedMainDirectives > 0;
326 #else
327                                 bool allowMainDirective = false;
328 #endif
329                                 if (mainAttributes != null && !allowMainDirective)
330                                         ThrowParseException ("Only 1 " + DefaultDirectiveName + " is allowed");
331 #if NET_2_0
332                                 allowedMainDirectives--;
333                                 if (mainAttributes != null)
334                                         return;
335                                 
336                                 if (pageParserFilter != null)
337                                         pageParserFilter.PreprocessDirective (directive.ToLower (Helpers.InvariantCulture), atts);
338 #endif
339                                 
340                                 mainAttributes = atts;
341                                 ProcessMainAttributes (mainAttributes);
342                                 return;
343                         }
344 #if NET_2_0
345                         else if (pageParserFilter != null)
346                                 pageParserFilter.PreprocessDirective (directive.ToLower (Helpers.InvariantCulture), atts);
347 #endif
348                                 
349                         int cmp = String.Compare ("Assembly", directive, true, Helpers.InvariantCulture);
350                         if (cmp == 0) {
351                                 string name = GetString (atts, "Name", null);
352                                 string src = GetString (atts, "Src", null);
353
354                                 if (atts.Count > 0)
355                                         ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
356
357                                 if (name == null && src == null)
358                                         ThrowParseException ("You gotta specify Src or Name");
359                                         
360                                 if (name != null && src != null)
361                                         ThrowParseException ("Src and Name cannot be used together");
362
363                                 if (name != null) {
364                                         AddAssemblyByName (name);
365                                 } else {
366                                         GetAssemblyFromSource (src);
367                                 }
368
369                                 return;
370                         }
371
372                         cmp = String.Compare ("Import", directive, true, Helpers.InvariantCulture);
373                         if (cmp == 0) {
374                                 string namesp = GetString (atts, "Namespace", null);
375                                 if (atts.Count > 0)
376                                         ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
377                                 
378                                 AddImport (namesp);
379                                 return;
380                         }
381
382                         cmp = String.Compare ("Implements", directive, true, Helpers.InvariantCulture);
383                         if (cmp == 0) {
384                                 string ifacename = GetString (atts, "Interface", "");
385
386                                 if (atts.Count > 0)
387                                         ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
388                                 
389                                 Type iface = LoadType (ifacename);
390                                 if (iface == null)
391                                         ThrowParseException ("Cannot find type " + ifacename);
392
393                                 if (!iface.IsInterface)
394                                         ThrowParseException (iface + " is not an interface");
395
396                                 AddInterface (iface.FullName);
397                                 return;
398                         }
399
400                         cmp = String.Compare ("OutputCache", directive, true, Helpers.InvariantCulture);
401                         if (cmp == 0) {
402                                 HttpResponse response = HttpContext.Current.Response;
403                                 if (response != null)
404                                         response.Cache.SetValidUntilExpires (true);
405                                 
406                                 output_cache = true;
407                                 
408                                 if (atts ["Duration"] == null)
409                                         ThrowParseException ("The directive is missing a 'duration' attribute.");
410                                 if (atts ["VaryByParam"] == null && atts ["VaryByControl"] == null)
411                                         ThrowParseException ("This directive is missing 'VaryByParam' " +
412                                                         "or 'VaryByControl' attribute, which should be set to \"none\", \"*\", " +
413                                                         "or a list of name/value pairs.");
414
415                                 foreach (DictionaryEntry entry in atts) {
416                                         string key = (string) entry.Key;
417                                         if (key == null)
418                                                 continue;
419                                         
420                                         switch (key.ToLower (Helpers.InvariantCulture)) {
421                                                 case "duration":
422                                                         oc_duration = Int32.Parse ((string) entry.Value);
423                                                         if (oc_duration < 1)
424                                                                 ThrowParseException ("The 'duration' attribute must be set " +
425                                                                                      "to a positive integer value");
426                                                         break;
427 #if NET_2_0
428                                                 case "sqldependency":
429                                                         oc_sqldependency = (string) entry.Value;
430                                                         break;
431                                                         
432                                                 case "nostore":
433                                                         try {
434                                                                 oc_nostore = Boolean.Parse ((string) entry.Value);
435                                                                 oc_parsed_params |= OutputCacheParsedParams.NoStore;
436                                                         } catch {
437                                                                 ThrowParseException ("The 'NoStore' attribute is case sensitive" +
438                                                                                      " and must be set to 'true' or 'false'.");
439                                                         }
440                                                         break;
441
442                                                 case "cacheprofile":
443                                                         oc_cacheprofile = (string) entry.Value;
444                                                         oc_parsed_params |= OutputCacheParsedParams.CacheProfile;
445                                                         break;
446                                                         
447                                                 case "varybycontentencodings":
448                                                         oc_content_encodings = (string) entry.Value;
449                                                         oc_parsed_params |= OutputCacheParsedParams.VaryByContentEncodings;
450                                                         break;
451 #endif
452                                                 case "varybyparam":
453                                                         oc_param = (string) entry.Value;
454                                                         if (String.Compare (oc_param, "none", true, Helpers.InvariantCulture) == 0)
455                                                                 oc_param = null;
456                                                         break;
457                                                 case "varybyheader":
458                                                         oc_header = (string) entry.Value;
459 #if NET_2_0
460                                                         oc_parsed_params |= OutputCacheParsedParams.VaryByHeader;
461 #endif
462                                                         break;
463                                                 case "varybycustom":
464                                                         oc_custom = (string) entry.Value;
465 #if NET_2_0
466                                                         oc_parsed_params |= OutputCacheParsedParams.VaryByCustom;
467 #endif
468                                                         break;
469                                                 case "location":
470                                                         if (!(this is PageParser))
471                                                                 goto default;
472                                                 
473                                                         try {
474                                                                 oc_location = (OutputCacheLocation) Enum.Parse (
475                                                                         typeof (OutputCacheLocation), (string) entry.Value, true);
476 #if NET_2_0
477                                                                 oc_parsed_params |= OutputCacheParsedParams.Location;
478 #endif
479                                                         } catch {
480                                                                 ThrowParseException ("The 'location' attribute is case sensitive and " +
481                                                                                      "must be one of the following values: Any, Client, " +
482                                                                                      "Downstream, Server, None, ServerAndClient.");
483                                                         }
484                                                         break;
485                                                 case "varybycontrol":
486 #if ONLY_1_1
487                                                         if (this is PageParser)
488                                                                 goto default;
489 #endif
490                                                         oc_controls = (string) entry.Value;
491 #if NET_2_0
492                                                         oc_parsed_params |= OutputCacheParsedParams.VaryByControl;
493 #endif
494                                                         break;
495                                                 case "shared":
496                                                         if (this is PageParser)
497                                                                 goto default;
498
499                                                         try {
500                                                                 oc_shared = Boolean.Parse ((string) entry.Value);
501                                                         } catch {
502                                                                 ThrowParseException ("The 'shared' attribute is case sensitive" +
503                                                                                      " and must be set to 'true' or 'false'.");
504                                                         }
505                                                         break;
506                                                 default:
507                                                         ThrowParseException ("The '" + key + "' attribute is not " +
508                                                                              "supported by the 'Outputcache' directive.");
509                                                         break;
510                                         }
511                                         
512                                 }
513                                 
514                                 return;
515                         }
516
517                         ThrowParseException ("Unknown directive: " + directive);
518                 }
519
520                 internal Type LoadType (string typeName)
521                 {
522                         Type type = HttpApplication.LoadType (typeName);
523                         if (type == null)
524                                 return null;
525                         Assembly asm = type.Assembly;
526                         string location = asm.Location;
527                         
528                         string dirname = Path.GetDirectoryName (location);
529                         bool doAddAssembly = true;
530                         if (dirname == HttpApplication.BinDirectory)
531                                 doAddAssembly = false;
532
533                         if (doAddAssembly)
534                                 AddAssembly (asm, true);
535
536                         return type;
537                 }
538
539 #if !NET_2_0
540                 void AddAssembliesInBin ()
541                 {
542                         Assembly asm;
543                         foreach (string s in HttpApplication.BinDirectoryAssemblies) {
544                                 try {
545                                         asm = Assembly.LoadFrom (s);
546                                         assemblies.Add (asm.Location);
547                                 } catch (BadImageFormatException) {
548                                         // ignore silently
549                                 }
550                         }
551                 }
552 #endif
553                 
554                 internal virtual void AddInterface (string iface)
555                 {
556                         if (interfaces == null) {
557 #if NET_2_0
558                                 interfaces = new List <string> ();
559 #else
560                                 interfaces = new ArrayList ();
561 #endif
562                         }
563
564                         if (!interfaces.Contains (iface))
565                                 interfaces.Add (iface);
566                 }
567                 
568                 internal virtual void AddImport (string namesp)
569                 {
570                         if (namesp == null || namesp.Length == 0)
571                                 return;
572                         
573                         if (imports == null) {
574 #if NET_2_0
575                                 imports = new List <string> ();
576 #else
577                                 imports = new ArrayList ();
578 #endif
579                         }
580                         
581                         if (imports.Contains (namesp))
582                                 return;
583                         
584                         imports.Add (namesp);
585 #if NET_2_0
586                         AddAssemblyForNamespace (namesp);
587 #endif
588                 }
589
590 #if NET_2_0
591                 void AddAssemblyForNamespace (string namesp)
592                 {
593                         if (binDirAssemblies == null)
594                                 binDirAssemblies = HttpApplication.BinDirectoryAssemblies;
595                         if (binDirAssemblies.Length == 0)
596                                 return;
597
598                         if (namespacesCache == null)
599                                 namespacesCache = new Dictionary <string, bool> ();
600                         else if (namespacesCache.ContainsKey (namesp))
601                                 return;
602                         
603                         foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ())
604                                 if (FindNamespaceInAssembly (asm, namesp))
605                                         return;
606                         
607                         IList tla = BuildManager.TopLevelAssemblies;
608                         if (tla != null && tla.Count > 0) {
609                                 foreach (Assembly asm in tla) {
610                                         if (FindNamespaceInAssembly (asm, namesp))
611                                                 return;
612                                 }
613                         }
614
615                         Assembly a;
616                         foreach (string s in binDirAssemblies) {
617                                 a = Assembly.LoadFrom (s);
618                                 if (FindNamespaceInAssembly (a, namesp))
619                                         return;
620                         }
621                 }
622
623                 bool FindNamespaceInAssembly (Assembly asm, string namesp)
624                 {
625                         Type[] asmTypes;
626
627                         try {
628                                 asmTypes = asm.GetTypes ();
629                         } catch (ReflectionTypeLoadException) {
630                                 // ignore
631                                 return false;
632                         }
633                         
634                         foreach (Type type in asmTypes) {
635                                 if (String.Compare (type.Namespace, namesp, StringComparison.Ordinal) == 0) {
636                                         namespacesCache.Add (namesp, true);
637                                         AddAssembly (asm, true);
638                                         return true;
639                                 }
640                         }
641
642                         return false;
643                 }
644 #endif
645                 
646                 internal virtual void AddSourceDependency (string filename)
647                 {
648                         if (dependencies != null && dependencies.Contains (filename))
649                                 ThrowParseException ("Circular file references are not allowed. File: " + filename);
650
651                         AddDependency (filename);
652                 }
653
654                 internal virtual void AddDependency (string filename)
655                 {
656                         if (filename == null || filename == String.Empty)
657                                 return;
658
659                         if (dependencies == null)
660                                 dependencies = new ArrayList ();
661
662                         if (!dependencies.Contains (filename))
663                                 dependencies.Add (filename);
664                 }
665                 
666                 internal virtual void AddAssembly (Assembly assembly, bool fullPath)
667                 {
668                         if (assembly == null || assembly.Location == String.Empty)
669                                 return;
670
671                         if (anames == null)
672                                 anames = new Hashtable ();
673
674                         string name = assembly.GetName ().Name;
675                         string loc = assembly.Location;
676                         if (fullPath) {
677                                 if (!assemblies.Contains (loc)) {
678                                         assemblies.Add (loc);
679                                 }
680
681                                 anames [name] = loc;
682                                 anames [loc] = assembly;
683                         } else {
684                                 if (!assemblies.Contains (name)) {
685                                         assemblies.Add (name);
686                                 }
687
688                                 anames [name] = assembly;
689                         }
690                 }
691
692                 internal virtual Assembly AddAssemblyByFileName (string filename)
693                 {
694                         Assembly assembly = null;
695                         Exception error = null;
696
697                         try {
698                                 assembly = Assembly.LoadFrom (filename);
699                         } catch (Exception e) { error = e; }
700
701                         if (assembly == null)
702                                 ThrowParseException ("Assembly " + filename + " not found", error);
703
704                         AddAssembly (assembly, true);
705                         return assembly;
706                 }
707
708                 internal virtual Assembly AddAssemblyByName (string name)
709                 {
710                         if (anames == null)
711                                 anames = new Hashtable ();
712
713                         if (anames.Contains (name)) {
714                                 object o = anames [name];
715                                 if (o is string)
716                                         o = anames [o];
717
718                                 return (Assembly) o;
719                         }
720
721                         Assembly assembly = null;
722                         Exception error = null;
723                         try {
724                                 assembly = Assembly.Load (name);
725                         } catch (Exception e) { error = e; }
726
727                         if (assembly == null) {
728                                 try {
729                                         assembly = Assembly.LoadWithPartialName (name);
730                                 } catch (Exception e) { error = e; }
731                         }
732                         
733                         if (assembly == null)
734                                 ThrowParseException ("Assembly " + name + " not found", error);
735
736                         AddAssembly (assembly, true);
737                         return assembly;
738                 }
739                 
740                 internal virtual void ProcessMainAttributes (Hashtable atts)
741                 {
742                         directiveLocation = new System.Web.Compilation.Location (Location);
743                         
744 #if NET_2_0
745                         CompilationSection compConfig;
746 #else
747                         CompilationConfiguration compConfig;
748 #endif
749
750                         compConfig = CompilationConfig;
751                         
752                         atts.Remove ("Description"); // ignored
753 #if NET_1_1
754                         atts.Remove ("CodeBehind");  // ignored
755 #endif
756                         atts.Remove ("AspCompat"); // ignored
757                         
758                         debug = GetBool (atts, "Debug", compConfig.Debug);
759                         compilerOptions = GetString (atts, "CompilerOptions", "");
760                         language = GetString (atts, "Language", "");
761                         if (language.Length != 0)
762                                 implicitLanguage = false;
763                         else
764                                 language = compConfig.DefaultLanguage;
765                         
766                         strictOn = GetBool (atts, "Strict", compConfig.Strict);
767                         explicitOn = GetBool (atts, "Explicit", compConfig.Explicit);
768                         if (atts.ContainsKey ("LinePragmas"))
769                                 linePragmasOn = GetBool (atts, "LinePragmas", true);
770
771                         string inherits = GetString (atts, "Inherits", null);
772 #if NET_2_0
773                         string srcRealPath = null;
774                         
775                         // In ASP 2, the source file is actually integrated with
776                         // the generated file via the use of partial classes. This
777                         // means that the code file has to be confirmed, but not
778                         // used at this point.
779                         src = GetString (atts, "CodeFile", null);
780                         codeFileBaseClass = GetString (atts, "CodeFileBaseClass", null);
781
782                         if (src == null && codeFileBaseClass != null)
783                                 ThrowParseException ("The 'CodeFileBaseClass' attribute cannot be used without a 'CodeFile' attribute");
784
785                         string legacySrc = GetString (atts, "Src", null);
786                         if (legacySrc != null) {
787                                 legacySrc = UrlUtils.Combine (BaseVirtualDir, legacySrc);
788                                 GetAssemblyFromSource (legacySrc);
789
790                                 if (src == null) {
791                                         src = legacySrc;
792                                         legacySrc = MapPath (legacySrc, false);
793                                         srcRealPath = legacySrc;
794                                         if (!File.Exists (srcRealPath))
795                                                 ThrowParseException ("File " + src + " not found");
796                                         
797                                         srcIsLegacy = true;
798                                 } else 
799                                         legacySrc = MapPath (legacySrc, false);                         
800
801                                 AddDependency (legacySrc);
802                         }
803                         
804                         if (!srcIsLegacy && src != null && inherits != null) {
805                                 // Make sure the source exists
806                                 src = UrlUtils.Combine (BaseVirtualDir, src);
807                                 srcRealPath = MapPath (src, false);
808
809                                 if (!HostingEnvironment.VirtualPathProvider.FileExists (src))
810                                         ThrowParseException ("File " + src + " not found");
811
812                                 // We are going to create a partial class that shares
813                                 // the same name as the inherits tag, so reset the
814                                 // name. The base type is changed because it is the
815                                 // code file's responsibilty to extend the classes
816                                 // needed.
817                                 partialClassName = inherits;
818
819                                 // Add the code file as an option to the
820                                 // compiler. This lets both files be compiled at once.
821                                 compilerOptions += " \"" + srcRealPath + "\"";
822
823                                 if (codeFileBaseClass != null) {
824                                         try {
825                                                 codeFileBaseClassType = LoadType (codeFileBaseClass);
826                                         } catch (Exception) {
827                                         }
828
829                                         if (codeFileBaseClassType == null)
830                                                 ThrowParseException ("Could not load type '{0}'", codeFileBaseClass);
831                                 }
832                         } else if (inherits != null) {
833                                 // We just set the inherits directly because this is a
834                                 // Single-Page model.
835                                 SetBaseType (inherits);
836                         }
837 #else
838                         string src = GetString (atts, "Src", null);
839
840                         if (src != null)
841                                 srcAssembly = GetAssemblyFromSource (src);
842                         
843                         if (inherits != null)
844                                 SetBaseType (inherits);
845 #endif
846                         if (src != null) {
847                                 if (VirtualPathUtility.IsAbsolute (src))
848                                         src = VirtualPathUtility.ToAppRelative (src);
849                                 AddDependency (src);
850                         }
851                         
852                         className = GetString (atts, "ClassName", null);
853                         if (className != null) {
854 #if NET_2_0
855                                 string [] identifiers = className.Split ('.');
856                                 for (int i = 0; i < identifiers.Length; i++)
857                                         if (!CodeGenerator.IsValidLanguageIndependentIdentifier (identifiers [i]))
858                                                 ThrowParseException (String.Format ("'{0}' is not a valid "
859                                                         + "value for attribute 'classname'.", className));
860 #else
861                                 if (!CodeGenerator.IsValidLanguageIndependentIdentifier (className))
862                                         ThrowParseException (String.Format ("'{0}' is not a valid "
863                                                 + "value for attribute 'classname'.", className));
864 #endif
865                         }
866
867 #if NET_2_0
868                         if (this is TemplateControlParser)
869                                 metaResourceKey = GetString (atts, "meta:resourcekey", null);
870                         
871                         if (inherits != null && (this is PageParser || this is UserControlParser) && atts.Count > 0) {
872                                 if (unknownMainAttributes == null)
873                                         unknownMainAttributes = new List <UnknownAttributeDescriptor> ();
874                                 string key, val;
875                                 
876                                 foreach (DictionaryEntry de in atts) {
877                                         key = de.Key as string;
878                                         val = de.Value as string;
879                                         
880                                         if (String.IsNullOrEmpty (key) || String.IsNullOrEmpty (val))
881                                                 continue;
882                                         CheckUnknownAttribute (key, val, inherits);
883                                 }
884                                 return;
885                         }
886 #endif
887                         if (atts.Count > 0)
888                                 ThrowParseException ("Unknown attribute: " + GetOneKey (atts));
889                 }
890
891 #if NET_2_0
892                 void RegisterTagName (string tagName)
893                 {
894                         if (registeredTagNames == null)
895                                 registeredTagNames = new List <string> ();
896
897                         if (registeredTagNames.Contains (tagName))
898                                 return;
899
900                         registeredTagNames.Add (tagName);
901                 }
902                 
903                 void CheckUnknownAttribute (string name, string val, string inherits)
904                 {
905                         MemberInfo mi = null;
906                         bool missing = false;
907                         string memberName = name.Trim ().ToLower (Helpers.InvariantCulture);
908                         Type parent = codeFileBaseClassType;
909
910                         if (parent == null)
911                                 parent = baseType;
912                         
913                         try {
914                                 MemberInfo[] infos = parent.GetMember (memberName,
915                                                                        MemberTypes.Field | MemberTypes.Property,
916                                                                        BindingFlags.Public | BindingFlags.Instance |
917                                                                        BindingFlags.IgnoreCase | BindingFlags.Static);
918                                 if (infos.Length != 0) {
919                                         // prefer public properties to public methods (it's what MS.NET does)
920                                         foreach (MemberInfo tmp in infos) {
921                                                 if (tmp is PropertyInfo) {
922                                                         mi = tmp;
923                                                         break;
924                                                 }
925                                         }
926                                         if (mi == null)
927                                                 mi = infos [0];
928                                 } else
929                                         missing = true;
930                         } catch (Exception) {
931                                 missing = true;
932                         }
933                         if (missing)
934                                 ThrowParseException (
935                                         "Error parsing attribute '{0}': Type '{1}' does not have a public property named '{0}'",
936                                         memberName, inherits);
937                         
938                         Type memberType = null;
939                         if (mi is PropertyInfo) {
940                                 PropertyInfo pi = mi as PropertyInfo;
941                                 
942                                 if (!pi.CanWrite)
943                                         ThrowParseException (
944                                                 "Error parsing attribute '{0}': The '{0}' property is read-only and cannot be set.",
945                                                 memberName);
946                                 memberType = pi.PropertyType;
947                         } else if (mi is FieldInfo) {
948                                 memberType = ((FieldInfo)mi).FieldType;
949                         } else
950                                 ThrowParseException ("Could not determine member the kind of '{0}' in base type '{1}",
951                                                      memberName, inherits);
952                         TypeConverter converter = TypeDescriptor.GetConverter (memberType);
953                         bool convertible = true;
954                         object value = null;
955                         
956                         if (converter == null || !converter.CanConvertFrom (typeof (string)))
957                                 convertible = false;
958
959                         if (convertible) {
960                                 try {
961                                         value = converter.ConvertFromInvariantString (val);
962                                 } catch (Exception) {
963                                         convertible = false;
964                                 }
965                         }
966
967                         if (!convertible)
968                                 ThrowParseException ("Error parsing attribute '{0}': Cannot create an object of type '{1}' from its string representation '{2}' for the '{3}' property.",
969                                                      memberName, memberType, val, mi.Name);
970                         
971                         UnknownAttributeDescriptor desc = new UnknownAttributeDescriptor (mi, value);
972                         unknownMainAttributes.Add (desc);
973                 }
974 #endif
975                 
976                 internal void SetBaseType (string type)
977                 {
978                         Type parent;                    
979                         if (type == null || type == DefaultBaseTypeName)
980                                 parent = DefaultBaseType;
981                         else
982                                 parent = null;
983
984                         if (parent == null) {
985 #if NET_2_0                     
986                                 parent = LoadType (type);
987 #else
988                                 parent = null;
989                                 if (srcAssembly != null)
990                                         parent = srcAssembly.GetType (type);
991
992                                 if (parent == null)
993                                         parent = LoadType (type);
994 #endif                          
995
996                                 if (parent == null)
997                                         ThrowParseException ("Cannot find type " + type);
998
999                                 if (!DefaultBaseType.IsAssignableFrom (parent))
1000                                         ThrowParseException ("The parent type '" + type + "' does not derive from " + DefaultBaseType);
1001                         }
1002
1003 #if NET_2_0
1004                         var pageParserFilter = PageParserFilter;
1005                         if (pageParserFilter != null && !pageParserFilter.AllowBaseType (parent))
1006                                 throw new HttpException ("Base type '" + parent + "' is not allowed.");
1007 #endif
1008                         
1009                         baseType = parent;
1010                 }
1011
1012                 internal void SetLanguage (string language)
1013                 {
1014                         this.language = language;
1015                         implicitLanguage = false;
1016                 }
1017
1018                 internal void PushIncludeDir (string dir)
1019                 {
1020                         if (includeDirs == null) {
1021 #if NET_2_0
1022                                 includeDirs = new Stack <string> (1);
1023 #else
1024                                 includeDirs = new Stack (1);
1025 #endif
1026                         }
1027
1028                         includeDirs.Push (dir);
1029                 }
1030
1031                 internal string PopIncludeDir ()
1032                 {
1033                         if (includeDirs == null || includeDirs.Count == 0)
1034                                 return null;
1035
1036                         return includeDirs.Pop () as string;
1037                 }
1038                 
1039                 Assembly GetAssemblyFromSource (string vpath)
1040                 {                       
1041                         vpath = UrlUtils.Combine (BaseVirtualDir, vpath);
1042                         string realPath = MapPath (vpath, false);
1043                         if (!File.Exists (realPath))
1044                                 ThrowParseException ("File " + vpath + " not found");
1045
1046                         AddSourceDependency (vpath);
1047                         
1048                         CompilerResults result;
1049
1050 #if NET_2_0
1051                         string tmp;
1052                         CompilerParameters parameters;
1053                         CodeDomProvider provider = BaseCompiler.CreateProvider (HttpContext.Current, language, out parameters, out tmp);
1054                         if (provider == null)
1055                                 throw new HttpException ("Cannot find provider for language '" + language + "'.");
1056                         
1057                         AssemblyBuilder abuilder = new AssemblyBuilder (provider);
1058                         abuilder.CompilerOptions = parameters;
1059                         abuilder.AddAssemblyReference (BuildManager.GetReferencedAssemblies () as List <Assembly>);
1060                         abuilder.AddCodeFile (realPath);
1061                         result = abuilder.BuildAssembly (new VirtualPath (vpath));
1062 #else
1063                         result = CachingCompiler.Compile (language, realPath, realPath, assemblies, Debug);
1064 #endif
1065                         if (result.NativeCompilerReturnValue != 0) {
1066                                 using (StreamReader reader = new StreamReader (realPath)) {
1067                                         throw new CompilationException (realPath, result.Errors, reader.ReadToEnd ());
1068                                 }
1069                         }
1070
1071                         AddAssembly (result.CompiledAssembly, true);
1072                         return result.CompiledAssembly;
1073                 }               
1074
1075                 internal abstract string DefaultBaseTypeName { get; }
1076                 internal abstract string DefaultDirectiveName { get; }
1077
1078                 internal bool LinePragmasOn {
1079                         get { return linePragmasOn; }
1080                 }
1081                 
1082 #if NET_2_0
1083                 internal byte[] MD5Checksum {
1084                         get { return md5checksum; }
1085                         set { md5checksum = value; }
1086                 }
1087
1088                 internal PageParserFilter PageParserFilter {
1089                         get {
1090                                 if (pageParserFilter != null)
1091                                         return pageParserFilter;
1092
1093                                 Type t = PageParserFilterType;
1094                                 if (t == null)
1095                                         return null;
1096                                 
1097                                 pageParserFilter = Activator.CreateInstance (t) as PageParserFilter;
1098                                 pageParserFilter.Initialize (this);
1099
1100                                 return pageParserFilter;
1101                         }
1102                 }
1103                 
1104                 internal Type PageParserFilterType {
1105                         get {
1106                                 if (pageParserFilterType == null) {
1107                                         string typeName = PagesConfig.PageParserFilterType;
1108                                         if (String.IsNullOrEmpty (typeName))
1109                                                 return null;
1110                                         
1111                                         pageParserFilterType = HttpApplication.LoadType (typeName, true);
1112                                 }
1113                                 
1114                                 return pageParserFilterType;
1115                         }
1116                 }
1117 #endif
1118                 
1119                 internal Type DefaultBaseType {
1120                         get {
1121                                 Type type = Type.GetType (DefaultBaseTypeName, true);
1122
1123                                 return type;
1124                         }
1125                 }
1126                 
1127                 internal ILocation DirectiveLocation {
1128                         get { return directiveLocation; }
1129                 }
1130                 
1131                 internal string ParserDir {
1132                         get {
1133                                 if (includeDirs == null || includeDirs.Count == 0)
1134                                         return BaseDir;
1135
1136                                 return includeDirs.Peek () as string;
1137                         }
1138                 }
1139                 
1140                 internal string InputFile
1141                 {
1142                         get { return inputFile; }
1143                         set { inputFile = value; }
1144                 }
1145
1146 #if NET_2_0
1147                 internal bool IsPartial {
1148                         get { return (!srcIsLegacy && src != null); }
1149                 }
1150
1151                 internal string CodeBehindSource {
1152                         get {
1153                                 if (srcIsLegacy)
1154                                         return null;
1155                                 
1156                                 return src;
1157                         }
1158                 }
1159                         
1160                 internal string PartialClassName {
1161                         get { return partialClassName; }
1162                 }
1163
1164                 internal string CodeFileBaseClass {
1165                         get { return codeFileBaseClass; }
1166                 }
1167
1168                 internal string MetaResourceKey {
1169                         get { return metaResourceKey; }
1170                 }
1171                 
1172                 internal Type CodeFileBaseClassType
1173                 {
1174                         get { return codeFileBaseClassType; }
1175                 }
1176                 
1177                 internal List <UnknownAttributeDescriptor> UnknownMainAttributes
1178                 {
1179                         get { return unknownMainAttributes; }
1180                 }
1181 #endif
1182
1183                 internal string Text {
1184                         get { return text; }
1185                         set { text = value; }
1186                 }
1187
1188                 internal Type BaseType {
1189                         get {
1190                                 if (baseType == null)
1191                                         SetBaseType (DefaultBaseTypeName);
1192                                 
1193                                 return baseType;
1194                         }
1195                 }
1196                 
1197                 internal bool BaseTypeIsGlobal {
1198                         get { return baseTypeIsGlobal; }
1199                         set { baseTypeIsGlobal = value; }
1200                 }
1201
1202 #if NET_2_0
1203                 static long autoClassCounter = 0;
1204 #endif
1205
1206                 internal string EncodeIdentifier (string value)
1207                 {
1208                         if (value == null || value.Length == 0 || CodeGenerator.IsValidLanguageIndependentIdentifier (value))
1209                                 return value;
1210
1211                         StringBuilder ret = new StringBuilder ();
1212
1213                         char ch = value [0];
1214                         switch (Char.GetUnicodeCategory (ch)) {
1215                                 case UnicodeCategory.LetterNumber:
1216                                 case UnicodeCategory.LowercaseLetter:
1217                                 case UnicodeCategory.TitlecaseLetter:
1218                                 case UnicodeCategory.UppercaseLetter:
1219                                 case UnicodeCategory.OtherLetter:
1220                                 case UnicodeCategory.ModifierLetter:
1221                                 case UnicodeCategory.ConnectorPunctuation:
1222                                         ret.Append (ch);
1223                                         break;
1224
1225                                 case UnicodeCategory.DecimalDigitNumber:
1226                                         ret.Append ('_');
1227                                         ret.Append (ch);
1228                                         break;
1229                                         
1230                                 default:
1231                                         ret.Append ('_');
1232                                         break;
1233                         }
1234
1235                         for (int i = 1; i < value.Length; i++) {
1236                                 ch = value [i];
1237                                 switch (Char.GetUnicodeCategory (ch)) {
1238                                         case UnicodeCategory.LetterNumber:
1239                                         case UnicodeCategory.LowercaseLetter:
1240                                         case UnicodeCategory.TitlecaseLetter:
1241                                         case UnicodeCategory.UppercaseLetter:
1242                                         case UnicodeCategory.OtherLetter:
1243                                         case UnicodeCategory.ModifierLetter:
1244                                         case UnicodeCategory.ConnectorPunctuation:
1245                                         case UnicodeCategory.DecimalDigitNumber:
1246                                         case UnicodeCategory.NonSpacingMark:
1247                                         case UnicodeCategory.SpacingCombiningMark:
1248                                         case UnicodeCategory.Format:
1249                                                 ret.Append (ch);
1250                                                 break;
1251                                                 
1252                                         default:
1253                                                 ret.Append ('_');
1254                                                 break;
1255                                 }
1256                         }
1257
1258                         return ret.ToString ();
1259                 }
1260                 
1261                 internal string ClassName {
1262                         get {
1263                                 if (className != null)
1264                                         return className;
1265
1266 #if NET_2_0
1267                                 string physPath = HttpContext.Current.Request.PhysicalApplicationPath;
1268                                 string inFile;
1269                                 
1270                                 if (String.IsNullOrEmpty (inputFile)) {
1271                                         inFile = null;
1272                                         using (StreamReader sr = Reader as StreamReader) {
1273                                                 if (sr != null) {
1274                                                         FileStream fr = sr.BaseStream as FileStream;
1275                                                         if (fr != null)
1276                                                                 inFile = fr.Name;
1277                                                 }
1278                                         }
1279                                 } else
1280                                         inFile = inputFile;
1281
1282                                 if (String.IsNullOrEmpty (inFile)) {
1283                                         // generate a unique class name
1284                                         long suffix;
1285                                         suffix = Interlocked.Increment (ref autoClassCounter);
1286                                         className = String.Format ("autoclass_nosource_{0:x}", suffix);
1287                                         return className;
1288                                 }
1289                                 
1290                                 if (StrUtils.StartsWith (inFile, physPath))
1291                                         className = inputFile.Substring (physPath.Length).ToLower (Helpers.InvariantCulture);
1292                                 else
1293 #endif
1294                                         className = Path.GetFileName (inputFile);
1295                                 className = EncodeIdentifier (className);
1296                                 return className;
1297                         }
1298                 }
1299
1300 #if NET_2_0
1301                 internal List <ServerSideScript> Scripts {
1302                         get {
1303                                 if (scripts == null)
1304                                         scripts = new List <ServerSideScript> ();
1305
1306                                 return scripts;
1307                         }
1308                 }
1309
1310                 internal List <string> Imports {
1311                         get { return imports; }
1312                 }
1313
1314                 internal List <string> Interfaces {
1315                         get { return interfaces; }
1316                 }
1317 #else
1318                 internal ArrayList Scripts {
1319                         get {
1320                                 if (scripts == null)
1321                                         scripts = new ArrayList ();
1322
1323                                 return scripts;
1324                         }
1325                 }
1326
1327                 internal ArrayList Imports {
1328                         get { return imports; }
1329                 }
1330
1331                 internal ArrayList Interfaces {
1332                         get { return interfaces; }
1333                 }
1334 #endif
1335                 
1336                 internal ArrayList Assemblies {
1337                         get {
1338                                 if (appAssemblyIndex != -1) {
1339                                         object o = assemblies [appAssemblyIndex];
1340                                         assemblies.RemoveAt (appAssemblyIndex);
1341                                         assemblies.Add (o);
1342                                         appAssemblyIndex = -1;
1343                                 }
1344
1345                                 return assemblies;
1346                         }
1347                 }
1348
1349                 internal RootBuilder RootBuilder {
1350                         get {
1351 #if NET_2_0
1352                                 if (rootBuilder != null)
1353                                         return rootBuilder;
1354                                 AspGenerator generator = AspGenerator;
1355                                 if (generator != null)
1356                                         rootBuilder = generator.RootBuilder;
1357 #endif
1358                                 return rootBuilder;
1359                         }
1360                         set { rootBuilder = value; }
1361                 }
1362
1363                 internal ArrayList Dependencies {
1364                         get { return dependencies; }
1365                         set { dependencies = value; }
1366                 }
1367
1368                 internal string CompilerOptions {
1369                         get { return compilerOptions; }
1370                 }
1371
1372                 internal string Language {
1373                         get { return language; }
1374                 }
1375
1376                 internal bool ImplicitLanguage {
1377                         get { return implicitLanguage; }
1378                 }
1379                 
1380                 internal bool StrictOn {
1381                         get { return strictOn; }
1382                 }
1383
1384                 internal bool ExplicitOn {
1385                         get { return explicitOn; }
1386                 }
1387                 
1388                 internal bool Debug {
1389                         get { return debug; }
1390                 }
1391
1392                 internal bool OutputCache {
1393                         get { return output_cache; }
1394                 }
1395
1396                 internal int OutputCacheDuration {
1397                         get { return oc_duration; }
1398                 }
1399
1400 #if NET_2_0
1401                 internal OutputCacheParsedParams OutputCacheParsedParameters {
1402                         get { return oc_parsed_params; }
1403                 }
1404
1405                 internal string OutputCacheSqlDependency {
1406                         get { return oc_sqldependency; }
1407                 }
1408                 
1409                 internal string OutputCacheCacheProfile {
1410                         get { return oc_cacheprofile; }
1411                 }
1412                 
1413                 internal string OutputCacheVaryByContentEncodings {
1414                         get { return oc_content_encodings; }
1415                 }
1416
1417                 internal bool OutputCacheNoStore {
1418                         get { return oc_nostore; }
1419                 }
1420                 
1421                 internal virtual TextReader Reader {
1422                         get { return null; }
1423                         set { /* no-op */ }
1424                 }
1425 #endif
1426                 
1427                 internal string OutputCacheVaryByHeader {
1428                         get { return oc_header; }
1429                 }
1430
1431                 internal string OutputCacheVaryByCustom {
1432                         get { return oc_custom; }
1433                 }
1434
1435                 internal string OutputCacheVaryByControls {
1436                         get { return oc_controls; }
1437                 }
1438                 
1439                 internal bool OutputCacheShared {
1440                         get { return oc_shared; }
1441                 }
1442                 
1443                 internal OutputCacheLocation OutputCacheLocation {
1444                         get { return oc_location; }
1445                 }
1446
1447                 internal string OutputCacheVaryByParam {
1448                         get { return oc_param; }
1449                 }
1450
1451 #if NET_2_0
1452                 internal List <string> RegisteredTagNames {
1453                         get { return registeredTagNames; }
1454                 }
1455                 
1456                 internal PagesSection PagesConfig {
1457                         get { return GetConfigSection <PagesSection> ("system.web/pages") as PagesSection; }
1458                 }
1459
1460                 internal AspGenerator AspGenerator {
1461                         get;
1462                         set;
1463                 }
1464 #else
1465                 internal PagesConfiguration PagesConfig {
1466                         get { return PagesConfiguration.GetInstance (Context); }
1467                 }
1468 #endif
1469         }
1470 }