context: //
  // System.Web.UI.TemplateControl.cs
  //
  // Authors:
  //   Duncan Mak  (duncan@ximian.com)
  //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
  //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
  //
  // (C) 2002 Ximian, Inc. (http://www.ximian.com)
  // Copyright (C) 2005-2010 Novell, Inc (http://www.novell.com)
  //
  // Permission is hereby granted, free of charge, to any person obtaining
  // a copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to
  // permit persons to whom the Software is furnished to do so, subject to
  // the following conditions:
  // 
  // The above copyright notice and this permission notice shall be
  // included in all copies or substantial portions of the Software.
  // 
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  //
  
  using System.Collections;
  using System.ComponentModel;
  using System.Reflection;
  using System.Security.Permissions;
  using System.Threading;
  using System.Web.Compilation;
  using System.Web.Util;
  using System.Xml;
  using System.IO;
  using System.Runtime.InteropServices;
  using System.Text;
  using System.Collections.Generic;
  using System.Collections.Concurrent;
  
  namespace System.Web.UI
  {
  	// CAS
  	[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  	[AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  	public abstract class TemplateControl : Control, INamingContainer, IFilterResolutionService
  	{
  		static readonly Assembly _System_Web_Assembly = typeof (TemplateControl).Assembly;
  		static object abortTransaction = new object ();
  		static object commitTransaction = new object ();
  		static object error = new object ();
  		static string [] methodNames = { "Page_Init",
  						 "Page_PreInit",
  						 "Page_PreLoad",
  						 "Page_LoadComplete",
  						 "Page_PreRenderComplete",
  						 "Page_SaveStateComplete",
  						 "Page_InitComplete",
  						 "Page_Load",
  						 "Page_DataBind",
  						 "Page_PreRender",
  						 "Page_Disposed",
  						 "Page_Error",
  						 "Page_Unload",
  						 "Page_AbortTransaction",
  						 "Page_CommitTransaction"};
  
  		const BindingFlags bflags = BindingFlags.Public |
  					    BindingFlags.NonPublic |
  					    BindingFlags.Instance;
  
  		string _appRelativeVirtualPath;
  		StringResourceData resource_data;
  		
  		#region Constructor
  		protected TemplateControl ()
  		{
  			TemplateControl = this;
  			Construct ();
  		}
  
  		#endregion
  
  		#region Properties
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		[Obsolete]
  		protected virtual int AutoHandlers {
  			get { return 0; }
  			set { }
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		protected virtual bool SupportAutoEvents {
  			get { return true; }
  		}
  
  		public string AppRelativeVirtualPath {
  			get { return _appRelativeVirtualPath; }
  			set { _appRelativeVirtualPath = value; }
  		}
  
  		#endregion
  
  		#region Methods
  
  		protected virtual void Construct ()
  		{
  		}
  
  		protected LiteralControl CreateResourceBasedLiteralControl (int offset, int size, bool fAsciiOnly)
  		{
  			if (resource_data == null)
  				return null;
  
  			if (offset > resource_data.MaxOffset - size)
  				throw new ArgumentOutOfRangeException ("size");
  
  			IntPtr ptr = AddOffset (resource_data.Ptr, offset);
  			return new ResourceBasedLiteralControl (ptr, size);
  		}
  
  		class EvtInfo {
  			public MethodInfo method;
  			public string methodName;
  			public EventInfo evt;
  			public bool noParams;
  		}
  
  		static SplitOrderedList<Type, ArrayList> auto_event_info = new SplitOrderedList<Type, ArrayList> (EqualityComparer<Type>.Default);
  
  		internal void WireupAutomaticEvents ()
  		{
  			if (!SupportAutoEvents || !AutoEventWireup)
  				return;
  
  			/* Avoid expensive reflection operations by computing the event info only once */
  			Type type = GetType ();
  			ArrayList events = auto_event_info.InsertOrGet ((uint)type.GetHashCode (), type, null, CollectAutomaticEventInfo);
  
  			for (int i = 0; i < events.Count; ++i) {
  				EvtInfo evinfo = (EvtInfo)events [i];
  				if (evinfo.noParams) {
  					NoParamsInvoker npi = new NoParamsInvoker (this, evinfo.method);
  					evinfo.evt.AddEventHandler (this, npi.FakeDelegate);
  				} else
  					evinfo.evt.AddEventHandler (this, Delegate.CreateDelegate (typeof (EventHandler), this, evinfo.method));
  			}
  		}
  
  		ArrayList CollectAutomaticEventInfo () {
  			ArrayList events = new ArrayList ();
  
  			foreach (string methodName in methodNames) {
  				MethodInfo method = null;
  				Type type;
  				for (type = GetType (); type.Assembly != _System_Web_Assembly; type = type.BaseType) {
  					method = type.GetMethod (methodName, bflags);
  					if (method != null)
  						break;
  				}
  				if (method == null)
  					continue;
  
  				if (method.DeclaringType != type) {
  					if (!method.IsPublic && !method.IsFamilyOrAssembly &&
  					    !method.IsFamilyAndAssembly && !method.IsFamily)
  						continue;
  				}
  
  				if (method.ReturnType != typeof (void))
  					continue;
  
  				ParameterInfo [] parms = method.GetParameters ();
  				int length = parms.Length;
  				bool noParams = (length == 0);
  				if (!noParams && (length != 2 ||
  				    parms [0].ParameterType != typeof (object) ||
  				    parms [1].ParameterType != typeof (EventArgs)))
  				    continue;
  
  				int pos = methodName.IndexOf ('_');
  				string eventName = methodName.Substring (pos + 1);
  				EventInfo evt = type.GetEvent (eventName);
  				if (evt == null) {
  					/* This should never happen */
  					continue;
  				}
  
  				EvtInfo evinfo = new EvtInfo ();
  				evinfo.method = method;
  				evinfo.methodName = methodName;
  				evinfo.evt = evt;
  				evinfo.noParams = noParams;
  
  				events.Add (evinfo);
  			}
  
  			return events;
  		}
  
  		[EditorBrowsable (EditorBrowsableState.Never)]
  		protected virtual void FrameworkInitialize ()
  		{
  		}
  
  		Type GetTypeFromControlPath (string virtualPath)
  		{
  			if (virtualPath == null)
  
gt: 				throw new ArgumentNullException ("virtualPath");