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