Control.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / xsp / System / Web / UI / Control.cs / 1 / Control.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI { 
    using System.Text; 
    using System.ComponentModel;
    using System; 
    using System.Collections;
    using System.Collections.Specialized;
    using System.ComponentModel.Design;
    using System.ComponentModel.Design.Serialization; 
    using System.Globalization;
    using System.Reflection; 
    using System.IO; 
    using HttpException = System.Web.HttpException;
    using System.Web.Configuration; 
    using System.Web.UI.Adapters;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.Util; 
    using System.Web.Hosting;
    using System.Web.Caching; 
    using System.Security.Permissions; 

    // Delegate used for the compiled template 
    public delegate void RenderMethod(HtmlTextWriter output, Control container);

    public delegate Control BuildMethod();
 
    // Defines the properties, methods, and events that are shared by all server
    // controls in the Web Forms page framework. 
    [ 
    Bindable(true),
    DefaultProperty("ID"), 
    DesignerCategory("Code"),
    Designer("System.Web.UI.Design.ControlDesigner, " + AssemblyRef.SystemDesign),
    DesignerSerializer("Microsoft.VisualStudio.Web.WebForms.ControlCodeDomSerializer, " + AssemblyRef.MicrosoftVisualStudioWeb,  "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + AssemblyRef.SystemDesign),
    Themeable(false), 
    ToolboxItemFilter("System.Web.UI", ToolboxItemFilterType.Require),
    ToolboxItemAttribute("System.Web.UI.Design.WebControlToolboxItem, " + AssemblyRef.SystemDesign) 
    ] 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class Control : IComponent, IParserAccessor, IUrlResolutionService, IDataBindingsAccessor, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor {

        internal static readonly object EventDataBinding = new object();
        internal static readonly object EventInit = new object(); 
        internal static readonly object EventLoad = new object();
        internal static readonly object EventUnload = new object(); 
        internal static readonly object EventPreRender = new object(); 
        private static readonly object EventDisposed = new object();
 
        internal const bool EnableViewStateDefault = true;
        internal const char ID_SEPARATOR = '$';
        private const char ID_RENDER_SEPARATOR = '_';
        internal const char LEGACY_ID_SEPARATOR = ':'; 

        private string _id; 
        // allows us to reuse the id variable to store a calculated id w/o polluting the public getter 
        private string _cachedUniqueID;
        private Control _parent; 

        // fields related to being a container
        private ControlState _controlState;
        private StateBag _viewState; 

        // The naming container that this control leaves in.  Note that even if 
        // this ctrl is a naming container, it will not point to itself, but to 
        // the naming container that contains it.
        private Control _namingContainer; 
        internal Page _page;
        private OccasionalFields _occasionalFields;
        private TemplateControl _templateControl;
        // The virtual directory of the Page or UserControl that hosts this control. 
        private VirtualPath _templateSourceVirtualDirectory;
        internal ControlAdapter _adapter; 
 
        // const masks into the BitVector32
        private const int idNotCalculated           = 0x00000001; 
        private const int marked                    = 0x00000002;
        private const int disableViewState          = 0x00000004;
        private const int controlsCreated           = 0x00000008;
        private const int invisible                 = 0x00000010; 
        private const int visibleDirty              = 0x00000020;
        private const int idNotRequired             = 0x00000040; 
        private const int isNamingContainer         = 0x00000080; 
        private const int creatingControls          = 0x00000100;
        private const int notVisibleOnPage          = 0x00000200; 
        private const int themeApplied              = 0x00000400;
        private const int mustRenderID              = 0x00000800;
        private const int disableTheming            = 0x00001000;
        private const int enableThemingSet          = 0x00002000; 
        private const int styleSheetApplied         = 0x00004000;
        private const int controlAdapterResolved    = 0x00008000; 
        private const int designMode                = 0x00010000; 
        private const int designModeChecked         = 0x00020000;
        private const int disableChildControlState  = 0x00040000; 
        internal const int isWebControlDisabled     = 0x00080000;
        private const int controlStateApplied       = 0x00100000;
        private const int useGeneratedID            = 0x00200000;
        #pragma warning disable 0649 
        internal SimpleBitVector32 flags;
        #pragma warning restore 0649 
 
        private const string automaticIDPrefix = "ctl";
        private const string automaticLegacyIDPrefix = "_ctl"; 
        private const int automaticIDCount = 128;
        private static readonly string[] automaticIDs = new string [automaticIDCount] {
            "ctl00", "ctl01", "ctl02", "ctl03", "ctl04", "ctl05", "ctl06",
            "ctl07", "ctl08", "ctl09", "ctl10", "ctl11", "ctl12", "ctl13", 
            "ctl14", "ctl15", "ctl16", "ctl17", "ctl18", "ctl19", "ctl20",
            "ctl21", "ctl22", "ctl23", "ctl24", "ctl25", "ctl26", "ctl27", 
            "ctl28", "ctl29", "ctl30", "ctl31", "ctl32", "ctl33", "ctl34", 
            "ctl35", "ctl36", "ctl37", "ctl38", "ctl39", "ctl40", "ctl41",
            "ctl42", "ctl43", "ctl44", "ctl45", "ctl46", "ctl47", "ctl48", 
            "ctl49", "ctl50", "ctl51", "ctl52", "ctl53", "ctl54", "ctl55",
            "ctl56", "ctl57", "ctl58", "ctl59", "ctl60", "ctl61", "ctl62",
            "ctl63", "ctl64", "ctl65", "ctl66", "ctl67", "ctl68", "ctl69",
            "ctl70", "ctl71", "ctl72", "ctl73", "ctl74", "ctl75", "ctl76", 
            "ctl77", "ctl78", "ctl79", "ctl80", "ctl81", "ctl82", "ctl83",
            "ctl84", "ctl85", "ctl86", "ctl87", "ctl88", "ctl89", "ctl90", 
            "ctl91", "ctl92", "ctl93", "ctl94", "ctl95", "ctl96", "ctl97", 
            "ctl98", "ctl99",
            "ctl100", "ctl101", "ctl102", "ctl103", "ctl104", "ctl105", "ctl106", 
            "ctl107", "ctl108", "ctl109", "ctl110", "ctl111", "ctl112", "ctl113",
            "ctl114", "ctl115", "ctl116", "ctl117", "ctl118", "ctl119", "ctl120",
            "ctl121", "ctl122", "ctl123", "ctl124", "ctl125", "ctl126", "ctl127"
 
        };
 
        ///  
        /// Initializes a new instance of the  class.
        ///  
        public Control() {
            if (this is INamingContainer)
                flags.Set(isNamingContainer);
        } 

 
        ///  
        ///    Indicates the control identifier generated by the ASP.NET framework. This
        ///       property is read-only.  
        /// 
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_ClientID)
        ] 
        public virtual string ClientID { 
            // This property is required to render a unique client-friendly id.
            get { 
                // Ensure that ID is set. The assumption being made is that the caller
                // is likely to use the client ID in script, and to support that the
                // control should render out an ID attribute
                EnsureID(); 
                string uniqueID = UniqueID;
                if(uniqueID != null && uniqueID.IndexOf(IdSeparator) >= 0) { 
                    return uniqueID.Replace(IdSeparator, ID_RENDER_SEPARATOR); 
                }
                return uniqueID; 
            }
        }

        protected char ClientIDSeparator { 
            get {
                return ID_RENDER_SEPARATOR; 
            } 
        }
 
        /// 
        ///    [To be supplied.]
        /// 
        [ 
        WebSysDescription(SR.Control_OnDisposed)
        ] 
        public event EventHandler Disposed { 
            add {
                Events.AddHandler(EventDisposed, value); 
            }
            remove {
                Events.RemoveHandler(EventDisposed, value);
            } 
        }
 
        ///  
        /// Gets the  object of the current Web request. If
        ///    the control's context is , this will be the context of the 
        ///    control's parent, unless the parent control's context is .
        ///    If this is the case, this will be equal to the HttpContext property.
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        protected internal virtual HttpContext Context {
            //  Request context containing the intrinsics 
            get {
                Page page = Page;
                if(page != null) {
                    return page.Context; 
                }
                return HttpContext.Current; 
            } 
        }
 
        protected virtual ControlAdapter ResolveAdapter() {
            if(flags[controlAdapterResolved]) {
                return _adapter;
            } 
            if (DesignMode) {
                flags.Set(controlAdapterResolved); 
                return null; 
            }
 
            HttpContext context = Context;
            if (context != null) {
                _adapter = context.Request.Browser.GetAdapter(this);
            } 
            flags.Set(controlAdapterResolved);
            return _adapter; 
        } 

        ///  
        ///    Indicates the list of event handler delegates for the control. This property
        ///       is read-only.
        /// 
        protected ControlAdapter Adapter { 
            get {
                if(flags[controlAdapterResolved]) { 
                    return _adapter; 
                }
                _adapter = ResolveAdapter(); 
                flags.Set(controlAdapterResolved);
                return _adapter;
            }
        } 

        ///  
        /// Indicates whether a control is being used in the context of a design surface. 
        /// 
        protected internal bool DesignMode { 
            get {
                if(!flags[designModeChecked]) {
                    Page page = Page;
                    if(page != null )  { 
                        if(page.GetDesignModeInternal()) {
                            flags.Set(designMode); 
                        } 
                        else {
                            flags.Clear(designMode); 
                        }
                    }
                    else {
                        if(Site != null) { 
                            if(Site.DesignMode) {
                                flags.Set(designMode); 
                            } 
                            else {
                                flags.Clear(designMode); 
                            }
                        }
                        else if (Parent != null) {
                            if(Parent.DesignMode) { 
                                flags.Set(designMode);
                            } 
 
                            // VSWhidbey 535747: If Page, Site and Parent are all null, do not change the
                            // designMode flag since it might had been previously set by the controlBuilder. 
                            // This does not affect runtime since designMode is by-default false.
                            /*
                            else {
                                flags.Clear(designMode); 
                            }
                            */ 
                        } 
                    }
                    flags.Set(designModeChecked); 
                }
                return flags[designMode];

            } 
        }
 
        // Helper function to call validateEvent. 
        internal void ValidateEvent(string uniqueID) {
            ValidateEvent(uniqueID, String.Empty); 
        }

        // Helper function to call validateEvent.
        internal void ValidateEvent(string uniqueID, string eventArgument) { 
            if (Page != null && SupportsEventValidation) {
                Page.ClientScript.ValidateEvent(uniqueID, eventArgument); 
            } 
        }
 
        // Indicates whether the control supports event validation
        // By default, all web controls in System.Web assembly supports it but not custom controls.
        private bool SupportsEventValidation {
            get { 
                return SupportsEventValidationAttribute.SupportsEventValidation(this.GetType());
            } 
        } 

        ///  
        ///    Indicates the list of event handler delegates for the control. This property
        ///       is read-only.
        /// 
        protected EventHandlerList Events { 
            get {
                EnsureOccasionalFields(); 
                if(_occasionalFields.Events == null) { 
                    _occasionalFields.Events = new EventHandlerList();
                } 
                return _occasionalFields.Events;
            }
        }
 
        protected bool HasEvents() {
            return ((_occasionalFields != null) && (_occasionalFields.Events != null)); 
        } 

        ///  
        ///     Gets or sets the identifier for the control. Setting the
        ///       property on a control allows programmatic access to the control's properties. If
        ///       this property is not specified on a control, either declaratively or
        ///       programmatically, then you cannot write event handlers and the like for the control. 
        /// 
        [ 
        ParenthesizePropertyName(true), 
        MergableProperty(false),
        Filterable(false), 
        Themeable(false),
        WebSysDescription(SR.Control_ID)
        ]
        public virtual string ID { 
            get {
                if (!flags[idNotCalculated] && !flags[mustRenderID]) { 
                    return null; 
                }
                return _id; 
            }
            set {
                // allow the id to be unset
                if (value != null && value.Length == 0) 
                    value = null;
 
                string oldID = _id; 

                _id = value; 
                ClearCachedUniqueIDRecursive();
                flags.Set(idNotCalculated);
                flags.Clear(useGeneratedID);
 
                // Update the ID in the naming container
                if ((_namingContainer != null) && (oldID != null)) { 
                    _namingContainer.DirtyNameTable(); 
                }
            } 
        }


        ///  
        ///    Gets and sets a value indicating whether theme is enabled.
        ///  
        [ 
        Browsable(false),
        DefaultValue(true), 
        Themeable(false),
        WebCategory("Behavior"),
        WebSysDescription(SR.Control_EnableTheming)
        ] 
        public virtual bool EnableTheming {
            get { 
                if (flags[enableThemingSet]) { 
                    return !flags[disableTheming];
                } 

                if (Parent != null) {
                    return Parent.EnableTheming;
                } 

                return !flags[disableTheming]; 
            } 
            set {
                if ((_controlState >= ControlState.FrameworkInitialized) && !DesignMode) { 
                    throw new InvalidOperationException(SR.GetString(SR.PropertySetBeforePreInitOrAddToControls, "EnableTheming"));
                }

                if(!value) { 
                    flags.Set(disableTheming);
                } 
                else { 
                    flags.Clear(disableTheming);
                } 

                flags.Set(enableThemingSet);
            }
        } 

        // Serialzie the value if it's set explicitely. 
        internal bool ShouldSerializeEnableTheming() { 
            return flags[enableThemingSet];;
        } 

        internal bool IsBindingContainer {
            get {
                return this is INamingContainer && !(this is INonBindingContainer); 
            }
        } 
 
        protected internal bool IsChildControlStateCleared {
            get { 
                return flags[disableChildControlState];
            }
        }
 

        ///  
        ///    Gets and sets the skinID of the control. 
        /// 
        [ 
        Browsable(false),
        DefaultValue(""),
        Filterable(false),
        WebCategory("Behavior"), 
        WebSysDescription(SR.Control_SkinId),
        ] 
        public virtual string SkinID { 
            get {
                if(_occasionalFields != null) { 
                    return _occasionalFields.SkinId == null ? String.Empty : _occasionalFields.SkinId;
                }
                return String.Empty;
            } 
            set {
                if (!DesignMode) { 
                    if (flags[styleSheetApplied]) { 
                        throw new InvalidOperationException(SR.GetString(SR.PropertySetBeforeStyleSheetApplied, "SkinId"));
                    } 

                    if (_controlState >= ControlState.FrameworkInitialized) {
                        throw new InvalidOperationException(SR.GetString(SR.PropertySetBeforePreInitOrAddToControls, "SkinId"));
                    } 
                }
 
                EnsureOccasionalFields(); 
                _occasionalFields.SkinId = value;
            } 
        }

        private ControlRareFields RareFieldsEnsured {
            get { 
                EnsureOccasionalFields();
                ControlRareFields rareFields = _occasionalFields.RareFields; 
                if(rareFields == null) { 
                    rareFields = new ControlRareFields();
                    _occasionalFields.RareFields = rareFields; 
                }

                return rareFields;
            } 
        }
 
        private ControlRareFields RareFields { 
            get {
                if(_occasionalFields != null) { 
                    return _occasionalFields.RareFields;
                }
                return null;
            } 
        }
 
        private void EnsureOccasionalFields() { 
            if(_occasionalFields == null) {
                _occasionalFields = new OccasionalFields(); 
            }
        }

 
        /// 
        ///     
        ///       Gets or sets a value indicating whether the control should maintain its view 
        ///       state, and the view state of any child control in contains, when the current
        ///       page request ends. 
        ///    
        /// 
        [
        DefaultValue(EnableViewStateDefault), 
        Themeable(false),
        WebCategory("Behavior"), 
        WebSysDescription(SR.Control_MaintainState) 
        ]
        public virtual bool EnableViewState { 
            get {
                return !flags[disableViewState];
            }
            set { 
                SetEnableViewStateInternal(value);
            } 
        } 

        internal void SetEnableViewStateInternal(bool value) { 
            if (!value)
                flags.Set(disableViewState);
            else
                flags.Clear(disableViewState); 
        }
 
 
        /// 
        /// Gets a value indicating whether the control is maintaining its view 
        /// state, when the current page request ends by looking at its own EnableViewState
        /// value, and the value for all its parents.
        /// 
        protected internal bool IsViewStateEnabled { 
            get {
                Control current = this; 
                while (current != null) { 
                    if (current.EnableViewState == false) {
                        return false; 
                    }
                    current = current.Parent;
                }
                return true; 
            }
        } 
 

        ///  
        ///    Gets the reference to the current control's naming container.
        /// 
        [
        Bindable(false), 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_NamingContainer) 
        ]
        public virtual Control NamingContainer { 
            get {
                if (_namingContainer == null) {
                    if (Parent != null) {
                        // Search for the closest naming container in the tree 
                        if (Parent.flags[isNamingContainer])
                            _namingContainer = Parent; 
                        else 
                            _namingContainer = Parent.NamingContainer;
                    } 
                }

                return _namingContainer;
            } 
        }
 
        ///  
        /// 
        ///    Returns the databinding container of this control.  In most cases, 
        ///     this is the same as the NamingContainer. But when using LoadTemplate(),
        ///     we get into a situation where that is not the case (ASURT 94138)
        ///     The behavior is different than V1 that Usercontrol.BindingContainer is no
        ///     longer the UserControl but the control contains it. The behavior is consistent 
        ///     with LoadTemplate() case.
        ///  
        [ 
        Bindable(false),
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        public Control BindingContainer { 
            get {
                Control bindingContainer = NamingContainer; 
                while (bindingContainer is INonBindingContainer) { 
                    bindingContainer = bindingContainer.BindingContainer;
                } 

                return bindingContainer;
            }
        } 

        ///  
        ///  
        /// VSWhidbey 80467: Need to adapt id separator.
        ///  
        protected char IdSeparator {
            get {
                if (Page != null) {
                    return Page.IdSeparator; 
                }
                return IdSeparatorFromConfig; 
            } 
        }
 
        // VSWhidbey 475945: Use the old id separator if configured
        internal char IdSeparatorFromConfig {
            get {
                return ((EnableLegacyRendering) ? LEGACY_ID_SEPARATOR : ID_SEPARATOR); 
            }
        } 
 
        // VSWhidbey 244374: Allow controls to opt into loading view state by ID instead of index (perf hit)
        protected bool LoadViewStateByID { 
            get {
                return ViewStateModeByIdAttribute.IsEnabled(GetType());
            }
        } 

        ///  
        ///  Gets the  object that contains the 
        ///    current control.
        ///  
        [
        Bindable(false),
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_Page)
        ] 
        public virtual Page Page { 
            get {
                if (_page == null) { 
                    if (Parent != null) {
                        _page = Parent.Page;
                    }
                } 
                return _page;
            } 
 
            set {
                if (OwnerControl != null) { 
                    throw new InvalidOperationException();
                }
                // This is necessary because we need to set the page in generated
                // code before controls are added to the tree (ASURT 75330) 
                Debug.Assert(_page == null);
                Debug.Assert(Parent == null || Parent.Page == null); 
                _page = value; 
            }
        } 

        // VSWhidbey 244999
        internal virtual bool IsReloadable {
            get { 
                return false;
            } 
        } 

        // DevDiv 33149, 43258: A backward compat. switch for Everett rendering 
        internal bool EnableLegacyRendering {
            get {
                Page page = Page;
                if (page != null) { 
                    return (page.XhtmlConformanceMode == XhtmlConformanceMode.Legacy);
                } 
                else if (DesignMode || Adapter != null) { 
                    return false;
                } 
                else {
                    return (GetXhtmlConformanceSection().Mode == XhtmlConformanceMode.Legacy);
                }
            } 
        }
 
        internal XhtmlConformanceSection GetXhtmlConformanceSection() { 
            HttpContext context = Context;
            XhtmlConformanceSection xhtmlConformanceSection; 
            if (context != null) {
                // if context is available, use the most efficient way to get the section
                xhtmlConformanceSection = RuntimeConfig.GetConfig(context).XhtmlConformance;
            } 
            else {
                xhtmlConformanceSection = RuntimeConfig.GetConfig().XhtmlConformance; 
            } 
            Debug.Assert(xhtmlConformanceSection != null);
            return xhtmlConformanceSection; 
        }

#if ORCAS
 
        /// 
        ///  Gets the  object that 
        /// paginates the current control. 
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.Control_Pager)
        ] 
        public virtual ContentPager ContentPager {
            get { 
                ControlRareFields rareFields = RareFieldsEnsured; 

                if (rareFields.ContentPager == null) { 
                    if (Parent != null) {
                        rareFields.ContentPager = Parent.ContentPager;
                    }
                } 
                return rareFields.ContentPager;
            } 
            set { 
                RareFieldsEnsured.ContentPager = value;
            } 
        }
#endif

 
        /// 
        ///    Gets the reference to the  
        ///    that hosts the control. 
        /// 
        internal virtual TemplateControl GetTemplateControl() { 
            if(_templateControl == null) {
                if (Parent != null) {
                    _templateControl = Parent.GetTemplateControl();
                } 
            }
            return _templateControl; 
        } 

 
        /// 
        ///    Gets the reference to the 
        ///    that hosts the control.
        ///  
        [
        Bindable(false), 
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.Control_TemplateControl) 
        ]
        public TemplateControl TemplateControl {
            get {
                return GetTemplateControl(); 
            }
 
            [EditorBrowsable(EditorBrowsableState.Never)] 
            set {
                // This setter is necessary so that controls inside templates are based on 
                // hosting pages not where the templates are used.
                _templateControl = value;
            }
        } 

        /* 
         * Determine whether this control is a descendent of the passed in control 
         */
        internal bool IsDescendentOf(Control ancestor) { 
            Control current = this;
            while (current != ancestor && current.Parent != null) {
                current = current.Parent;
            } 
            return (current == ancestor);
        } 
 

        ///  
        ///     Gets the current control's parent control in the UI hierarchy.
        /// 
        [
        Bindable(false), 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_Parent) 
        ]
        public virtual Control Parent { 
            get {
                return _parent;
            }
        } 

        internal bool IsParentedToUpdatePanel { 
            get { 
                Control parent = Parent;
                while (parent != null) { 
                    if (parent is IUpdatePanel) {
                        return true;
                    }
                    parent = parent.Parent; 
                }
                return false; 
            } 
        }
 
        /// 
        ///     Gets the virtual directory of the Page or UserControl that contains this control.
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_TemplateSourceDirectory) 
        ]
        public virtual string TemplateSourceDirectory { 
            get {
                if (TemplateControlVirtualDirectory == null)
                    return String.Empty;
 
                return TemplateControlVirtualDirectory.VirtualPathStringNoTrailingSlash;
            } 
        } 

 
        /// 
        ///     Gets the virtual directory of the Page or UserControl that contains this control.
        ///         Unlike TemplateSourceDirectory, this returns an app relative path (e.g. "~/sub")
        ///  
        [
        Browsable(false), 
        EditorBrowsable(EditorBrowsableState.Advanced), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.Control_TemplateSourceDirectory) 
        ]
        public string AppRelativeTemplateSourceDirectory {
            get {
                return VirtualPath.GetAppRelativeVirtualPathStringOrEmpty(TemplateControlVirtualDirectory); 
            }
 
            [EditorBrowsable(EditorBrowsableState.Never)] 
            set {
                // This setter is necessary so that skins are based on hosting skin file. 
                this.TemplateControlVirtualDirectory = VirtualPath.CreateNonRelativeAllowNull(value);
            }
        }
 
        internal VirtualPath TemplateControlVirtualDirectory {
            get { 
                if (_templateSourceVirtualDirectory != null) 
                    return _templateSourceVirtualDirectory;
 
                TemplateControl control = TemplateControl;
                if (control == null) {
                    HttpContext context = Context;
                    if (context != null) { 
                        _templateSourceVirtualDirectory = context.Request.CurrentExecutionFilePathObject.Parent;
                    } 
                    return _templateSourceVirtualDirectory; 
                }
                // Prevent recursion if this is the TemplateControl 
                if (control != this) {
                    _templateSourceVirtualDirectory = control.TemplateControlVirtualDirectory;
                }
                return _templateSourceVirtualDirectory; 
            }
 
            set { 
                // This setter is necessary so that skins are based on hosting skin file.
                _templateSourceVirtualDirectory = value; 
            }
        }

        internal ControlState ControlState { 
            get { return _controlState; }
            set { _controlState = value; } 
        } 

 
        /// 
        ///    Indicates the site information for the control.
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        EditorBrowsable(EditorBrowsableState.Advanced), 
        WebSysDescription(SR.Control_Site)
        ] 
        public ISite Site {
            get {
                if (OwnerControl != null) {
                    return OwnerControl.Site; 
                }
 
                if (RareFields != null) { 
                    return RareFields.Site;
                } 
                return null;
            }
            set {
                if (OwnerControl != null) { 
                    throw new InvalidOperationException(SR.GetString(SR.Substitution_SiteNotAllowed));
                } 
 
                RareFieldsEnsured.Site = value;
                flags.Clear(designModeChecked); 
            }
        }

 
        /// 
        ///     
        ///       Gets or sets a value that indicates whether a control should be rendered on 
        ///       the page.
        ///     
        /// 
        [
        Bindable(true),
        DefaultValue(true), 
        WebCategory("Behavior"),
        WebSysDescription(SR.Control_Visible) 
        ] 
        public virtual bool Visible {
            get { 
                if (flags[invisible])
                    return false;
#if ORCAS
                if (NotVisibleOnPage) 
                    return false;
#endif 
                else if ((_parent != null) && !DesignMode) 
                    return _parent.Visible;
                else 
                    return true;
            }
            set {
                if (flags[marked]) { 
                    bool visible = !flags[invisible];
                    if (visible != value) { 
                        flags.Set(visibleDirty); 
                    }
                } 

                if(!value) {
                    flags.Set(invisible);
                } 
                else {
                    flags.Clear(invisible); 
                } 
            }
        } 

#if ORCAS
        internal bool ExplicitlyInvisible {
            get { 
                return flags[invisible];
            } 
        } 
#endif
 


        /// 
        /// Do not remove or change the signature. It is called via reflection. 
        /// This allows for correct serialization, since Visible is implemented as a
        /// recursive property. 
        ///  
        private void ResetVisible() {
            Visible = true; 
        }


        ///  
        /// Do not remove or change the signature. It is called via reflection.
        /// This allows for correct serialization, since Visible is implemented as a 
        /// recursive property. 
        /// 
        private bool ShouldSerializeVisible() { 
            return flags[invisible];
        }

 
        /// 
        ///     Gets the unique, hierarchically-qualified identifier for 
        ///       a control. This is different from the ID property, in that the fully-qualified 
        ///       identifier includes the identifier for the control's naming container.
        ///  
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.Control_UniqueID) 
        ]
        public virtual string UniqueID { 
            get { 
                if (_cachedUniqueID != null) {
                    return _cachedUniqueID; 
                }

                Control namingContainer = NamingContainer;
                if (namingContainer != null) { 
                    // if the ID is null at this point, we need to have one created and the control added to the
                    // naming container. 
                    if (_id == null) { 
                        GenerateAutomaticID();
                    } 

                    if (Page == namingContainer) {
                        _cachedUniqueID = _id;
                    } 
                    else {
                        string uniqueIDPrefix = namingContainer.GetUniqueIDPrefix(); 
                        if (uniqueIDPrefix.Length == 0) { 
                            // In this case, it is probably a naming container that is not sited, so we don't want to cache it
                            return _id; 
                        }
                        else {
                            _cachedUniqueID = uniqueIDPrefix + _id;
                        } 
                    }
 
                    return _cachedUniqueID; 
                }
                else { 
                    // no naming container
                    return _id;
                }
            } 
        }
 
        #if SHIPPINGADAPTERS 
        // Used by adapters in delegating rendering (e.g., a Button for a LinkButton for scriptless devices).
        // The UniqueID of the new control has to be set to match the UniqueID of the original. 
        internal void SetUniqueID(string val) {
            _cachedUniqueID = val;
        }
        #endif 

 
        ///  
        ///    Occurs when the control binds to a data source. Notifies the control to perform any data binding during this event.
        ///  
        [
        WebCategory("Data"),
        WebSysDescription(SR.Control_OnDataBind)
        ] 
        public event EventHandler DataBinding {
            add { 
                Events.AddHandler(EventDataBinding, value); 
            }
            remove { 
                Events.RemoveHandler(EventDataBinding, value);
            }
        }
 

        ///  
        ///    Occurs when the control is initialized, the first step in the page lifecycle. Controls should 
        ///       perform any initialization steps that are required to create and set up an
        ///       instantiation. 
        /// 
        [
        WebSysDescription(SR.Control_OnInit)
        ] 
        public event EventHandler Init {
            add { 
                Events.AddHandler(EventInit, value); 
            }
            remove { 
                Events.RemoveHandler(EventInit, value);
            }
        }
 

        ///  
        /// Occurs when the control is loaded to the  object. Notifies the control to perform any steps that 
        ///    need to occur on each page request.
        ///  
        [
        WebSysDescription(SR.Control_OnLoad)
        ]
        public event EventHandler Load { 
            add {
                Events.AddHandler(EventLoad, value); 
            } 
            remove {
                Events.RemoveHandler(EventLoad, value); 
            }
        }

 
        /// 
        ///    Occurs when the control is about to render. Controls 
        ///       should perform any pre-rendering steps necessary before saving view state and 
        ///       rendering content to the  object.
        ///  
        [
        WebSysDescription(SR.Control_OnPreRender)
        ]
        public event EventHandler PreRender { 
            add {
                Events.AddHandler(EventPreRender, value); 
            } 
            remove {
                Events.RemoveHandler(EventPreRender, value); 
            }
        }

 
        /// 
        ///    Occurs when the control is unloaded from memory. Controls should perform any 
        ///       final cleanup before this instance of it is  
        /// 
        [ 
        WebSysDescription(SR.Control_OnUnload)
        ]
        public event EventHandler Unload {
            add { 
                Events.AddHandler(EventUnload, value);
            } 
            remove { 
                Events.RemoveHandler(EventUnload, value);
            } 
        }

        /// 
        /// Apply stylesheet skin on the control. 
        /// 
        [ 
        EditorBrowsable(EditorBrowsableState.Advanced), 
        ]
        public virtual void ApplyStyleSheetSkin(Page page) { 
            // Nothing to do if the control is not in a Page.
            if (page == null) {
                return;
            } 

            // Only apply stylesheet if not already applied. 
            if (flags[styleSheetApplied]) { 
                throw new InvalidOperationException(SR.GetString(SR.StyleSheetAreadyAppliedOnControl));
            } 

            if (page.ApplyControlStyleSheet(this)) {
                flags.Set(styleSheetApplied);
            } 
        }
 
        ///  
        /// Apply theme on the control.
        ///  
        private void ApplySkin(Page page) {
            if (page == null) {
                throw new ArgumentNullException("page");
            } 

            if (flags[themeApplied]) { 
                return; 
            }
 
            if (ThemeableAttribute.IsTypeThemeable(this.GetType())) {
                page.ApplyControlSkin(this);
                flags.Set(themeApplied);
            } 
        }
 
 
        /// 
        /// Raises the  event. This 
        ///    notifies a control to perform any data binding logic that is associated with it.
        /// 
        protected virtual void OnDataBinding(EventArgs e) {
            if(HasEvents()) { 
                EventHandler handler = _occasionalFields.Events[EventDataBinding] as EventHandler;
                if(handler != null) { 
                    handler(this, e); 
                }
            } 
        }


        ///  
        ///     Causes data binding to occur on the invoked control and all of its child
        ///       controls. 
        ///  
        public virtual void DataBind() {
            DataBind(true); 
        }

        /// 
        ///     Causes the invoked controls' context to be pushed on the stack, 
        ///       then conditionally call OnDataBinging on the invoked control, and databind all of its child
        ///       controls.  A control would call this with false if it overrides DataBind without calling 
        ///       Control.DataBind, but still wants to be an IDataItemContainer.  FormView and DetailsView 
        ///       are good examples of this.
        ///  
        protected virtual void DataBind(bool raiseOnDataBinding) {
            bool inDataBind = false;

            if (IsBindingContainer) { 
                bool foundDataItem;
 
                object dataItem = DataBinder.GetDataItem(this, out foundDataItem); 

                if (foundDataItem && (Page != null)) { 
                    Page.PushDataBindingContext(dataItem);
                    inDataBind = true;
                }
            } 
            try {
                if (raiseOnDataBinding) { 
                    // Do our own databinding 
                    OnDataBinding(EventArgs.Empty);
                } 

                // Do all of our children's databinding
                DataBindChildren();
            } 
            finally {
                if (inDataBind) { 
                    Page.PopDataBindingContext(); 
                }
            } 
        }


        ///  
        ///  Causes data binding to occur on all of the child controls.
        ///  
        protected virtual void DataBindChildren() { 
            if (HasControls()) {
                EnsureOccasionalFields(); 
                string oldmsg = _occasionalFields.Controls.SetCollectionReadOnly(SR.Parent_collections_readonly);

                try {
                    try { 
                        int controlCount = _occasionalFields.Controls.Count;
                        for (int i=0; i < controlCount; i++) 
                            _occasionalFields.Controls[i].DataBind(); 
                    }
                    finally { 
                        _occasionalFields.Controls.SetCollectionReadOnly(oldmsg);
                    }
                }
                catch { 
                    throw;
                } 
            } 
        }
 
        internal void PreventAutoID() {
            // controls that are also naming containers must always get an id
            if (flags[isNamingContainer] == false) {
                flags.Set(idNotRequired); 
            }
        } 
 

        ///  
        ///    Notifies the control that an element, XML or HTML, was parsed, and adds it to
        ///       the control.
        /// 
        protected virtual void AddParsedSubObject(object obj) { 
            Control control = obj as Control;
            if (control != null) { 
                Controls.Add(control); 
            }
        } 

        private void UpdateNamingContainer(Control namingContainer) {
            // Remove the cached uniqueID if the control already had a namingcontainer
            // and the namingcontainer is changed. 
            if (_namingContainer != null && _namingContainer != namingContainer) {
                ClearCachedUniqueIDRecursive(); 
            } 

            _namingContainer = namingContainer; 
        }

        private void ClearCachedUniqueIDRecursive() {
            _cachedUniqueID = null; 

            if (_occasionalFields != null) { 
                _occasionalFields.UniqueIDPrefix = null; 

                if (_occasionalFields.Controls != null) { 
                    int controlCount = _occasionalFields.Controls.Count;
                    for (int i = 0; i < controlCount; i++) {
                        _occasionalFields.Controls[i].ClearCachedUniqueIDRecursive();
                    } 
                }
            } 
        } 

        protected void EnsureID() { 
            if (_namingContainer != null) {
                if (_id == null) {
                    GenerateAutomaticID();
                } 
                flags.Set(mustRenderID);
            } 
        } 

        private void GenerateAutomaticID() { 
            Debug.Assert(_namingContainer != null);
            Debug.Assert(_id == null);

            // Remember that a generated ID is used for this control. 
            flags.Set(useGeneratedID);
 
            // Calculate the automatic ID. For performance and memory reasons 
            // we look up a static table entry if possible
            _namingContainer.EnsureOccasionalFields(); 
            int idNo = _namingContainer._occasionalFields.NamedControlsID++;
            if (EnableLegacyRendering) {
                // VSWhidbey 517118
                _id = automaticLegacyIDPrefix + idNo.ToString(NumberFormatInfo.InvariantInfo); 
            }
            else { 
                if (idNo < automaticIDCount) { 
                    _id = automaticIDs[idNo];
                } 
                else {
                    _id = automaticIDPrefix + idNo.ToString(NumberFormatInfo.InvariantInfo);
                }
            } 

            _namingContainer.DirtyNameTable(); 
        } 

        internal virtual string GetUniqueIDPrefix() { 
            EnsureOccasionalFields();

            if (_occasionalFields.UniqueIDPrefix == null) {
                string uniqueID = UniqueID; 
                if (!String.IsNullOrEmpty(uniqueID)) {
                    _occasionalFields.UniqueIDPrefix = uniqueID + IdSeparator; 
                } 
                else {
                    _occasionalFields.UniqueIDPrefix = String.Empty; 
                }
            }

            return _occasionalFields.UniqueIDPrefix; 
        }
 
        ///  
        /// Raises the  event. This notifies the control to perform
        ///    any steps necessary for its creation on a page request. 
        /// 
        protected internal virtual void OnInit(EventArgs e) {
            if(HasEvents()) {
                EventHandler handler = _occasionalFields.Events[EventInit] as EventHandler; 
                if(handler != null) {
                    handler(this, e); 
                } 
            }
        } 

        internal virtual void InitRecursive(Control namingContainer) {
            ResolveAdapter();
            if (_occasionalFields != null && _occasionalFields.Controls != null) { 
                if (flags[isNamingContainer]) {
                    namingContainer = this; 
                } 
                string oldmsg = _occasionalFields.Controls.SetCollectionReadOnly(SR.Parent_collections_readonly);
 
                int controlCount = _occasionalFields.Controls.Count;
                for (int i = 0; i < controlCount; i++) {
                    Control control = _occasionalFields.Controls[i];
 
                    // Propagate the page and namingContainer
                    control.UpdateNamingContainer(namingContainer); 
 
                    if ((control._id == null) && (namingContainer != null) && !control.flags[idNotRequired]) {
                        control.GenerateAutomaticID(); 
                    }
                    control._page = Page;

                    control.InitRecursive(namingContainer); 
                }
                _occasionalFields.Controls.SetCollectionReadOnly(oldmsg); 
 
            }
 
            // Only make the actual call if it hasn't already happened (ASURT 111303)
            if (_controlState < ControlState.Initialized) {
                _controlState = ControlState.ChildrenInitialized; // framework also initialized
 
                if ((Page != null) && !DesignMode) {
                    if (Page.ContainsTheme && EnableTheming) { 
                        ApplySkin(Page); 
                    }
                } 

                if (_adapter != null) {
                    _adapter.OnInit(EventArgs.Empty);
                } 
                else {
                    OnInit(EventArgs.Empty); 
                } 

                _controlState = ControlState.Initialized; 
            }

            // track all subsequent state changes
            TrackViewState(); 

#if DEBUG 
            ControlInvariant(); 
#endif
        } 

#if DEBUG

        ///  
        ///    This should be used to assert internal state about the control
        ///  
        internal void ControlInvariant() { 

            // If the control is initialized, the naming container and page should have been pushed in 
            if (_controlState >= ControlState.Initialized) {
                if (DesignMode) {
                    // Top-level UserControls do not have a page or a naming container in the designer
                    // hence the special casing. 

                    Debug.Assert((_namingContainer != null) || (this is Page) || (this is UserControl)); 
 
                    //
 


                }
                else { 
                    if (!(this is Page)) {
                        Debug.Assert(_namingContainer != null); 
                    } 
                    Debug.Assert(Page != null);
                } 
            }
            // If naming container is set and the name table exists, the ID should exist in it.

            if(_namingContainer != null && 
               _namingContainer._occasionalFields != null &&
               _namingContainer._occasionalFields.NamedControls != null && 
               _id != null) { 
                Debug.Assert(_namingContainer._occasionalFields.NamedControls.Contains(_id));
            } 
        }

        // Collect some statistic about the number of controls with occasional and
        // rare fields. 
        internal void GetRareFieldStatistics(ref int totalControls,
            ref int withOccasionalFields, ref int withRareFields) { 
            totalControls++; 
            if (_occasionalFields != null) {
                withOccasionalFields++; 
                if (_occasionalFields.RareFields != null)
                    withRareFields++;

                // No children: we're done 
                if (_occasionalFields.Controls == null)
                    return; 
 
                int controlCount = _occasionalFields.Controls.Count;
                for (int i = 0; i < controlCount; i++) { 
                    Control control = _occasionalFields.Controls[i];

                    control.GetRareFieldStatistics(ref totalControls, ref withOccasionalFields,
                        ref withRareFields); 
                }
            } 
        } 
#endif
 
        protected void ClearChildState() {
            ClearChildControlState();
            ClearChildViewState();
        } 

        protected void ClearChildControlState() { 
            //VSWhidbey 242621 to be consistent with ClearChildViewState, ignore calls before and during Init 
            if (ControlState < ControlState.Initialized) {
                return; 
            }
            flags.Set(disableChildControlState);
            if (Page != null) {
                Page.RegisterRequiresClearChildControlState(this); 
            }
        } 
 

        ///  
        ///    Deletes the view state information for all of the current control's child
        ///       controls.
        /// 
        protected void ClearChildViewState() { 
            if(_occasionalFields != null) {
                _occasionalFields.ControlsViewState = null; 
            } 
        }
 

        /// 
        ///    Indicates whether the current control's children have any saved view state
        ///       information. This property is read-only. 
        /// 
        protected bool HasChildViewState { 
            get { 
                return ((_occasionalFields != null) &&
                        (_occasionalFields.ControlsViewState != null) && 
                        (_occasionalFields.ControlsViewState.Count > 0));
            }
        }
 

        ///  
        /// Sets initial focus on the control 
        /// 
        public virtual void Focus() { 
            Page.SetFocus(this);
        }

        internal void LoadControlStateInternal(object savedStateObj) { 
            // Do not load the control state if it has been applied.
            if (flags[controlStateApplied]) { 
                return; 
            }
 
            flags.Set(controlStateApplied);

            Pair savedState = (Pair)savedStateObj;
            if (savedState == null) { 
                return;
            } 
            Page page = Page; 
            if (page != null && !page.ShouldLoadControlState(this)) {
                return; 
            }
            // VSWhidbey160650: Only call LoadControlState with non null savedState
            if (savedState.First != null) {
                LoadControlState(savedState.First); 
            }
            // VSWhidbey356804: Only call LoadAdapterControlState with non null savedState 
            if (_adapter == null || savedState.Second == null) { 
                return;
            } 
            _adapter.LoadAdapterControlState(savedState.Second);
        }

 
        /// 
        /// Load the control state, which is the essential state information needed even if view state is disabled. 
        ///  
        protected internal virtual void LoadControlState(object savedState) {
        } 


        /// 
        ///    Restores the view state information from a previous page 
        ///       request that was saved by the Control.SavedState method.
        ///  
        protected virtual void LoadViewState(object savedState) { 
            if (savedState != null) {
                ViewState.LoadViewState(savedState); 

                // Load values cached out of view state
                object visible = ViewState["Visible"];
                if (visible != null) { 
                    if(!(bool)visible) {
                        flags.Set(invisible); 
                    } 
                    else {
                        flags.Clear(invisible); 
                    }
                    flags.Set(visibleDirty);
                }
            } 
        }
 
        internal void LoadViewStateRecursive(object savedState) { 
            // nothing to do if we have no state
            if (savedState == null || flags[disableViewState]) 
                return;

            if (Page != null && Page.IsPostBack) {
                object controlState = null; 
                object adapterState = null;
                ArrayList childState = null; 
 
                Pair allSavedState = savedState as Pair;
                if (allSavedState != null) { 
                    controlState = allSavedState.First;
                    childState = (ArrayList)allSavedState.Second;
                }
                else { 
                    Debug.Assert(savedState is Triplet);
                    Triplet t = (Triplet)savedState; 
 
                    controlState = t.First;
                    adapterState = t.Second; 
                    childState = (ArrayList)t.Third;
                }

                try { 
                    if ((adapterState != null) && (_adapter != null)) {
                        _adapter.LoadAdapterViewState(adapterState); 
                    } 

                    if (controlState != null) { 
                        LoadViewState(controlState);
                    }

                    if (childState != null) { 
                        if (LoadViewStateByID) {
                            LoadChildViewStateByID(childState); 
                        } 
                        else {
                            LoadChildViewStateByIndex(childState); 
                        }
                    }
                }
                catch (InvalidCastException) { 
                    // catch all viewstate loading problems with casts.  They are most likely changed control trees.
                    throw new HttpException(SR.GetString(SR.Controls_Cant_Change_Between_Posts)); 
                } 
                catch (IndexOutOfRangeException) {
                    // catch all viewstate loading problems with indeces.  They are most likely changed control trees. 
                    throw new HttpException(SR.GetString(SR.Controls_Cant_Change_Between_Posts));
                }
            }
 
            _controlState = ControlState.ViewStateLoaded;
        } 
 
        internal void LoadChildViewStateByID(ArrayList childState) {
            int childStateCount = childState.Count; 
            for (int i = 0; i < childStateCount; i += 2) {
                // first element is index or ID of control with state and the
                // next element is state of the control
                string controlId = (string)childState[i]; 
                object state = childState[i + 1];
 
                Control childControl = FindControl(controlId); 
                if (childControl != null) {
                    childControl.LoadViewStateRecursive(state); 
                }
                else {
                    // couldn't find a control for this state blob, save it for later
                    EnsureOccasionalFields(); 
                    if (_occasionalFields.ControlsViewState == null) {
                        _occasionalFields.ControlsViewState = new Hashtable(); 
                    } 
                    _occasionalFields.ControlsViewState[controlId] = state;
                } 
            }
        }

        internal void LoadChildViewStateByIndex(ArrayList childState) { 
            ControlCollection ctrlColl = Controls;
            int ctrlCount = ctrlColl.Count; 
 
            int childStateCount = childState.Count;
            for (int i = 0; i < childStateCount; i += 2) { 
                // first element is index of control with state and the
                // next element is state of the control
                int controlIndex = (int)childState[i];
                object state = childState[i + 1]; 

                if (controlIndex < ctrlCount) { 
                    // we have a control for this state blob 
                    ctrlColl[controlIndex].LoadViewStateRecursive(state);
                } 
                else {
                    // couldn't find a control for this state blob, save it for later
                    EnsureOccasionalFields();
                    if (_occasionalFields.ControlsViewState == null) { 
                        _occasionalFields.ControlsViewState = new Hashtable();
                    } 
                    _occasionalFields.ControlsViewState[controlIndex] = state; 
                }
            } 
        }

        ///
        /// Figure out if a path is physical or virtual.  This is useful because a number of our controls 
        /// accept either type of path for the same attribute.
        /// 
        internal void ResolvePhysicalOrVirtualPath(string path, out VirtualPath virtualPath, out string physicalPath) { 
            if (System.Web.Util.UrlPath.IsAbsolutePhysicalPath(path)) {
                physicalPath = path; 
                virtualPath = null;
            }
            else {
                physicalPath = null; 

                // It could be relative, so resolve it 
                virtualPath = TemplateControlVirtualDirectory.Combine(VirtualPath.Create(path)); 
            }
        } 


        /// 
        ///  
        ///   This function takes a virtual path, that is a relative or root relative URL without a protocol.
        ///   It returns the mapped physcial file name relative to the template source. It throws an exception if 
        ///   there is insufficient security access to read or investigate the mapped result. This should be used 
        ///   by controls that can read files and live in fully trusted DLLs such as System.Web.dll to prevent
        ///   security issues. The exception thrown does not give away information about the mapping.  For absolute 
        ///   physical paths, this function checks permission
        /// 
        /// 
        protected internal string MapPathSecure(string virtualPath) { 
            if (String.IsNullOrEmpty(virtualPath)) {
                throw new ArgumentNullException("virtualPath", SR.GetString(SR.VirtualPath_Length_Zero)); 
            } 

            string physicalPath; 
            VirtualPath virtualPathObject;
            ResolvePhysicalOrVirtualPath(virtualPath, out virtualPathObject, out physicalPath);
            if (physicalPath == null) {
                physicalPath = virtualPathObject.MapPathInternal(TemplateControlVirtualDirectory, 
                    true /*allowCrossAppMapping*/);
            } 
 
            // Security check
            HttpRuntime.CheckFilePermission(physicalPath); 

            return physicalPath;
        }
 

        ///  
        ///  
        ///   This function takes a virtual path, that is a relative or root relative URL without a protocol.
        ///   It can also take a physical path, either local (c:\) or UNC. 
        ///   It returns a stream used to read to contents of the file. It throws an exception if
        ///   there is insufficient security access to read or investigate the mapped result. This should be used
        ///   by controls that can read files and live in fully trusted DLLs such as System.Web.dll to prevent
        ///   security issues. The exception thrown does not give away information about the mapping.  For absolute 
        ///   physical paths, this function checks permission
        ///  
        ///  
        protected internal Stream OpenFile(string path) {
 
            string physicalPath = null;
            VirtualFile vfile = null;

            // Need to Trim it since MapPath no longer allows trailing space (VSWhidbey 441210) 
            path = path.Trim();
 
            if (UrlPath.IsAbsolutePhysicalPath(path)) { 
                // Absolute physical path
                physicalPath = path; 
            }
            else {
                vfile = HostingEnvironment.VirtualPathProvider.GetFile(path);
                MapPathBasedVirtualFile mapPathVFile = vfile as MapPathBasedVirtualFile; 
                if (mapPathVFile != null) {
                    physicalPath = mapPathVFile.PhysicalPath; 
                } 
            }
 
            // If we got a physical path, make sure the user has access to it
            if (physicalPath != null) {
                HttpRuntime.CheckFilePermission(physicalPath);
            } 

            if (vfile != null) { 
                return vfile.Open(); 
            }
            else { 
                return new FileStream(physicalPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            }
        }
 
        ///
        /// Open a stream from either a virtual or physical path, and if possible get a CacheDependency 
        /// for the resulting Stream. 
        ///
        internal Stream OpenFileAndGetDependency(VirtualPath virtualPath, string physicalPath, out CacheDependency dependency) { 

            // Only one of the paths should be non-null
            Debug.Assert((virtualPath == null) != (physicalPath == null));
 
            // If we got a virtual path, and we're using the default VPP, call MapPath
            if (physicalPath == null && HostingEnvironment.UsingMapPathBasedVirtualPathProvider) { 
                physicalPath = virtualPath.MapPathInternal(TemplateControlVirtualDirectory, 
                    true /*allowCrossAppMapping*/);
            } 

            Stream stream;
            if (physicalPath != null) {
                // Security check 
                HttpRuntime.CheckFilePermission(physicalPath);
 
                // Work directly with the physical file, bypassing the VPP 
                stream = new FileStream(physicalPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                dependency = new CacheDependency(0, physicalPath); 
            }
            else {
                // It's non file system based, so go though the VirtualPathProvider
                stream = virtualPath.OpenFile(); 
                dependency = VirtualPathProvider.GetCacheDependency(virtualPath);
            } 
 
            return stream;
        } 


        /// 
        /// Raises the  
        /// event. This notifies the control that it should perform any work that needs to
        /// occur for each page request. 
        ///  
        protected internal virtual void OnLoad(EventArgs e) {
            if(HasEvents()) { 
                EventHandler handler = _occasionalFields.Events[EventLoad] as EventHandler;
                if(handler != null) {
                    handler(this, e);
                } 
            }
        } 
 
        internal virtual void LoadRecursive() {
 
            // Only make the actual call if it hasn't already happened (ASURT 111303)
            if (_controlState < ControlState.Loaded) {
                if(_adapter != null) {
                    _adapter.OnLoad(EventArgs.Empty); 
                }
                else { 
                    OnLoad(EventArgs.Empty); 
                }
            } 

            // Call Load on all our children
            if (_occasionalFields != null && _occasionalFields.Controls != null) {
                string oldmsg = _occasionalFields.Controls.SetCollectionReadOnly(SR.Parent_collections_readonly); 

                int controlCount = _occasionalFields.Controls.Count; 
                for (int i = 0; i < controlCount; i++) { 
                    _occasionalFields.Controls[i].LoadRecursive();
                } 

                _occasionalFields.Controls.SetCollectionReadOnly(oldmsg);
            }
 
            if (_controlState < ControlState.Loaded)
                _controlState = ControlState.Loaded; 
        } 

 
        /// 
        /// Raises the  event. This method uses event arguments
        ///    to pass the event data to the control.
        ///  
        protected internal virtual void OnPreRender(EventArgs e) {
            if(HasEvents()) { 
                EventHandler handler = _occasionalFields.Events[EventPreRender] as EventHandler; 
                if (handler != null) {
                    handler(this, e); 
                }
            }
        }
 
        internal virtual void PreRenderRecursiveInternal() {
            // Call Visible property and cache value in !flags[invisible] to allow Visible to be overridden. 
            // This avoids unnecessary virtual property calls in SaveViewState and Render. 
            bool visible = Visible;
            if(!visible) { 
                flags.Set(invisible);
            }
            else {
                flags.Clear(invisible); 
                EnsureChildControls();
 
                if(_adapter != null) { 
                    _adapter.OnPreRender(EventArgs.Empty);
                } 
                else {
                    OnPreRender(EventArgs.Empty);
                }
 
                if (_occasionalFields != null && _occasionalFields.Controls != null) {
                    string oldmsg = _occasionalFields.Controls.SetCollectionReadOnly(SR.Parent_collections_readonly); 
 
                    int controlCount = _occasionalFields.Controls.Count;
                    for (int i=0; i < controlCount; i++) { 
                        _occasionalFields.Controls[i].PreRenderRecursiveInternal();
                    }
                    _occasionalFields.Controls.SetCollectionReadOnly(oldmsg);
                } 
            }
            _controlState = ControlState.PreRendered; 
        } 

        internal int EstimateStateSize(object state) { 
            if(state == null) {
                return 0;
            }
            return Util.SerializeWithAssert(new ObjectStateFormatter(), state).Length; 
        }
 
        /* 
         * Walk the tree and fill in profile information
         */ 

        /// 
        /// 
        /// Gathers information about the control and delivers it to the  
        /// property to be displayed when tracing is enabled for the page.
        ///  
        protected void BuildProfileTree(string parentId, bool calcViewState) { 
            // estimate the viewstate size.
            calcViewState = calcViewState && (!flags[disableViewState]); 
            int viewstatesize;
            if (calcViewState)
                viewstatesize = EstimateStateSize(SaveViewState());
            else 
                viewstatesize = 0;
 
            int controlstatesize = 0; 
            if(Page != null && Page._registeredControlsRequiringControlState != null && Page._registeredControlsRequiringControlState.Contains(this)) {
                controlstatesize = EstimateStateSize(SaveControlStateInternal()); 
            }

            // give it all to the profiler
            Page.Trace.AddNewControl(UniqueID, parentId, this.GetType().FullName, viewstatesize, controlstatesize); 

            if (_occasionalFields != null && _occasionalFields.Controls != null) { 
                int controlCount = _occasionalFields.Controls.Count; 
                for (int i = 0; i < controlCount; i++) {
                    _occasionalFields.Controls[i].BuildProfileTree(UniqueID, calcViewState); 
                }
            }
        }
 

        internal object SaveControlStateInternal() { 
            object controlState = SaveControlState(); 
            object adapterControlState = null;
            if (_adapter != null) { 
                adapterControlState = _adapter.SaveAdapterControlState();
            }
            if (controlState != null || adapterControlState != null) {
                return new Pair(controlState, adapterControlState); 
            }
            return null; 
        } 

 
        /// 
        /// Save the control state, which is the essential state information needed even if view state is disabled.
        /// 
        protected internal virtual object SaveControlState() { 
            return null;
        } 
 
        // Save modified state the control would like restored on the postback.
        // Return null if there is no state to save. 

        /// 
        ///    
        ///       Saves view state for use with a later  
        ///       request.
        ///     
        ///  
        protected virtual object SaveViewState() {
            // Save values cached out of view state 
            if (flags[visibleDirty]) {
                ViewState["Visible"] = !flags[invisible];
            }
            if (_viewState != null) 
                return _viewState.SaveViewState();
 
            return null; 
        }
 
        // Answer any state this control or its descendants want to save on freeze.
        // The format for saving is Triplet(myState, ArrayList childIDs, ArrayList childStates),
        // where myState or childStates and childIDs may be null.
        internal object SaveViewStateRecursive() { 
            if (flags[disableViewState])
                return null; 
 
            object adapterState = null;
            if (_adapter != null) { 
                adapterState = _adapter.SaveAdapterViewState();
            }

            object controlSavedState = SaveViewState(); 

            ArrayList childStates = null; 
            if (HasControls()) { 
                ControlCollection occasionalFieldControls = _occasionalFields.Controls;
                int occasionalFieldControlCount = occasionalFieldControls.Count; 

                bool useId = LoadViewStateByID;
                for (int i = 0; i < occasionalFieldControlCount; i++) {
                    Control child = occasionalFieldControls[i]; 
                    object childState = child.SaveViewStateRecursive();
                    if (childState != null) { 
                        if (childStates == null) { 
                            childStates = new ArrayList(occasionalFieldControlCount);
                        } 

                        if (useId) {
                            child.EnsureID();
                            childStates.Add(child.ID); 
                        }
                        else { 
                            childStates.Add(i); 
                        }
                        childStates.Add(childState); 
                    }
                }
            }
 
            if (_adapter != null) {
                if ((controlSavedState != null) || (adapterState != null) || (childStates != null)) { 
                    return new Triplet(controlSavedState, adapterState, childStates); 
                }
            } 
            else {
                if ((controlSavedState != null) || (childStates != null)) {
                    return new Pair(controlSavedState, childStates);
                } 
            }
 
            return null; 
        }
 

        /// 
        /// Outputs control content to a provided HTMLTextWriter
        /// output stream. 
        /// 
        protected internal virtual void Render(HtmlTextWriter writer) { 
            RenderChildren(writer); 
        }
 
        internal void RenderChildrenInternal(HtmlTextWriter writer, ICollection children) {
            // If we have a delegate, use it for the rendering.
            // This happens when there is some ASP code.  See also Whidbey 33012.
            if(RareFields != null && RareFields.RenderMethod != null ) { 
                writer.BeginRender();
                RareFields.RenderMethod(writer, this); 
                writer.EndRender(); 
                return;
            } 
            if (children != null) {
                foreach (Control child in children) {
                    child.RenderControl(writer);
                } 
            }
        } 
 
        protected internal virtual void RenderChildren(HtmlTextWriter writer) {
            ICollection children = (_occasionalFields == null) ? null : _occasionalFields.Controls; 
            RenderChildrenInternal(writer, children);
        }

        ///  
        ///    [To be supplied.]
        ///  
        public virtual void RenderControl(HtmlTextWriter writer) { 
            //use the Adapter property to ensure it is resolved
            RenderControl(writer, Adapter); 
        }

        /// 
        ///    Used for MobilePage implementation. 
        /// 
        protected void RenderControl(HtmlTextWriter writer, ControlAdapter adapter) { 
            if (!flags[invisible] && !flags[notVisibleOnPage]) { 
                HttpContext context = (Page == null) ? null : Page._context;
                if (context  != null && context.TraceIsEnabled) { 
                    int presize = context.Response.GetBufferedLength();
                    RenderControlInternal(writer, adapter);
                    int postsize = context.Response.GetBufferedLength();
                    context.Trace.AddControlSize(UniqueID, postsize - presize); 
                }
                else { 
                    RenderControlInternal(writer, adapter); 
                }
            } 
        }

        private void RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) {
            if (adapter != null) { 
                //
                adapter.BeginRender(writer); 
                adapter.Render(writer); 
                adapter.EndRender(writer);
            } 
            else {
                Render(writer);
            }
        } 

 
        ///  
        ///    [To be supplied.]
        ///  
        protected internal virtual void OnUnload(EventArgs e) {
            if(HasEvents()) {
                EventHandler handler = _occasionalFields.Events[EventUnload] as EventHandler;
                if (handler != null) { 
                    handler(this, e);
                } 
            } 
        }
 

        /// 
        ///    Enables a control to perform final cleanup.
        ///  
        public virtual void Dispose() {
            IContainer container = null; 
 
            if (Site != null) {
                container = (IContainer)Site.GetService(typeof(IContainer)); 
                if (container != null) {
                    container.Remove(this);
                    EventHandler disp = Events[EventDisposed] as EventHandler;
                    if (disp != null) 
                        disp(this, EventArgs.Empty);
                } 
            } 

            if (_occasionalFields != null) { 
                _occasionalFields.Dispose();
                //do not null out for backwards compat, VSWhidbey 475940
                //_occasionalFields = null;
            } 
        }
 
 
        internal virtual void UnloadRecursive(bool dispose) {
            Page page = Page; 
            if (page != null && page.RequiresControlState(this)) {
                page.UnregisterRequiresControlState(this);
                RareFieldsEnsured.RequiredControlState = true;
            } 

            // Remove the generated ID so it will be assigned a different ID next time. 
            if (flags[useGeneratedID]) { 
                _id = null;
                flags.Clear(useGeneratedID); 
            }

            if (_occasionalFields != null && _occasionalFields.Controls != null) {
                string oldmsg = _occasionalFields.Controls.SetCollectionReadOnly(SR.Parent_collections_readonly); 

                int controlCount = _occasionalFields.Controls.Count; 
                for (int i = 0; i < controlCount; i++) 
                    _occasionalFields.Controls[i].UnloadRecursive(dispose);
 
                _occasionalFields.Controls.SetCollectionReadOnly(oldmsg);
            }

            if(_adapter != null) { 
                _adapter.OnUnload(EventArgs.Empty);
            } 
            else { 
                OnUnload(EventArgs.Empty);
            } 

            //
            if (dispose)
                Dispose(); 

            // VSWhidbey 244999: Everett behavior doesn't reset the control state. 
            // But for control which requires its OnInit method to be called again 
            // to properly initialize when the control is removed and added back
            // to Page's control tree, the control can override IsReloadable 
            // to true so the control state is reset.  e.g. Validator, see bug
            if (IsReloadable) {
                _controlState = ControlState.Constructed;
            } 
        }
 
 
        /// 
        ///    Assigns an sources of the event and its information up the page control 
        ///       hierarchy until they reach the top of the control tree. 
        /// 
        protected void RaiseBubbleEvent(object source, EventArgs args) {
            Control currentTarget = Parent; 
            while (currentTarget != null) {
                if (currentTarget.OnBubbleEvent(source, args)) { 
                    return; 
                }
                currentTarget = currentTarget.Parent; 
            }
        }

 
        /// 
        ///    Determines whether the event for the control should be passed up the page's 
        ///       control hierarchy. 
        /// 
        protected virtual bool OnBubbleEvent(object source, EventArgs args) { 
            return false;
        }

 
        // Members related to being a container
 
 
        /// 
        ///     Gets a ControlCollection object that represents the child controls for a specified control in the 
        ///       UI hierarchy.
        /// 
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.Control_Controls) 
        ] 
        public virtual ControlCollection Controls {
            get { 
                if (_occasionalFields == null || _occasionalFields.Controls == null) {
                    EnsureOccasionalFields();
                    _occasionalFields.Controls = CreateControlCollection();
                } 
                return _occasionalFields.Controls;
            } 
        } 

 
        /// 
        ///    Indicates a dictionary of state information that allows you to save and restore
        ///       the state of a control across multiple requests for the same page.
        ///  
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_State)
        ] 
        protected virtual StateBag ViewState {
            get {
                if (_viewState != null) {   // create a StateBag on demand; WebControl makes its case sensitive
                    return _viewState; 
                }
 
                _viewState = new StateBag(ViewStateIgnoresCase); 
                if (IsTrackingViewState)
                    _viewState.TrackViewState(); 
                return _viewState;
            }
        }
 
        // fast enough that we cam always use it.
 
        ///  
        /// Indicates whether the  object is case-insensitive.
        ///  
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        ] 
        protected virtual bool ViewStateIgnoresCase {
            get { 
                return false; 
            }
        } 


        /// 
        ///  
        protected internal virtual void AddedControl(Control control, int index) {
            if (control.OwnerControl != null) { 
                throw new InvalidOperationException(SR.GetString(SR.Substitution_NotAllowed)); 
            }
 
            if (control._parent != null) {
                control._parent.Controls.Remove(control);
            }
 
            control._parent = this;
            control._page = Page; 
            control.flags.Clear(designModeChecked); 

            // We only add to naming container if it is available. Otherwise, it will be pushed through 
            // during InitRecursive
            Control namingContainer = flags[isNamingContainer] ? this : _namingContainer;
            if (namingContainer != null) {
                control.UpdateNamingContainer(namingContainer); 
                if (control._id == null && !control.flags[idNotRequired]) {
                    // this will also dirty the name table in the naming container 
                    control.GenerateAutomaticID(); 
                }
                else if (control._id != null || (control._occasionalFields != null && control._occasionalFields.Controls != null)) { 
                    // If the control has and ID, or has children (which *may* themselves
                    // have ID's), we need to dirty the name table (ASURT 100557)
                    namingContainer.DirtyNameTable();
                } 
            }
 
            /* 
             * The following is for times when AddChild is called after CreateChildControls. This
             * allows users to add children at any time in the creation process without having 
             * to understand the underlying machinery.
             * Note that if page is null, it means we haven't been attached to a container ourselves.
             * If this is true, when we are, our children will be recursively set up.
             */ 
            if (_controlState >= ControlState.ChildrenInitialized) {
 
                Debug.Assert(namingContainer != null); 
                control.InitRecursive(namingContainer);
 
                // VSWhidbey 396372: We need to reregister the control state if the control is reparented because the control
                // is unregistered during unload, but its already been inited once, so it will not get its Init called again
                // which is where most controls call RegisterRequiresControlState
                if (control._controlState >= ControlState.Initialized && 
                    control.RareFields != null &&
                    control.RareFields.RequiredControlState) { 
                    Page.RegisterRequiresControlState(control); 
                }
 
                if (_controlState >= ControlState.ViewStateLoaded) {
                    object viewState = null;
                    if(_occasionalFields != null && _occasionalFields.ControlsViewState != null) {
                        viewState = _occasionalFields.ControlsViewState[index]; 
                        // This solution takes the conservative approach that once viewstate has been
                        // applied to a child control, it is thrown away.  This eliminates inadvertently 
                        // setting viewstate on the wrong control, which can occur in scenarios where 
                        // the child control collection is being manipulated via code.  Probably need
                        // to provide a feature where programmer can control whether to reapply viewstate 
                        // or not.
                        if (LoadViewStateByID) {
                            control.EnsureID();
                            viewState = _occasionalFields.ControlsViewState[control.ID]; 
                            _occasionalFields.ControlsViewState.Remove(control.ID);
                        } 
                        else { 
                            viewState = _occasionalFields.ControlsViewState[index];
                            _occasionalFields.ControlsViewState.Remove(index); 
                        }
                    }

                    control.LoadViewStateRecursive(viewState); 

                    if (_controlState >= ControlState.Loaded) { 
                        control.LoadRecursive(); 

                        if (_controlState >= ControlState.PreRendered) 
                            control.PreRenderRecursiveInternal();
                    }
                }
            } 
        }
 
 
        /// 
        ///    [To be supplied.] 
        /// 
        protected virtual ControlCollection CreateControlCollection() {
            return new ControlCollection(this);
        } 

 
        ///  
        ///    
        ///       Notifies any controls that use composition-based implementation to create any 
        ///       child controls they contain in preperation for postback or rendering.
        ///    
        /// 
        protected internal virtual void CreateChildControls() { 
        }
 
 

        ///  
        ///    Indicates whether the control's child controls have been created.
        /// 
        protected bool ChildControlsCreated {
            get { 
                return flags[controlsCreated];
            } 
            set { 
                if (!value && flags[controlsCreated]) {
                    Controls.Clear(); 
                }
                if(value) {
                    flags.Set(controlsCreated);
                } 
                else {
                    flags.Clear(controlsCreated); 
                } 
            }
        } 


        /// 
        ///    Make a URL absolute using the AppRelativeTemplateSourceDirectory.  The returned URL is for 
        ///        client use, and will contain the session cookie if appropriate.
        ///  
        public string ResolveUrl(string relativeUrl) { 
            if (relativeUrl == null) {
                throw new ArgumentNullException("relativeUrl"); 
            }

            // check if its empty or already absolute
            if ((relativeUrl.Length == 0) || (UrlPath.IsRelativeUrl(relativeUrl) == false)) { 
                return relativeUrl;
            } 
 
            string baseUrl = AppRelativeTemplateSourceDirectory;
            if (String.IsNullOrEmpty(baseUrl)) { 
                return relativeUrl;
            }

            // first make it absolute 
            string url = UrlPath.Combine(baseUrl, relativeUrl);
 
            // include the session cookie if available (ASURT 47658) 
            // As a side effect, this will change an app relative path (~/...) to app absolute
            return Context.Response.ApplyAppPathModifier(url); 
        }


        ///  
        ///     Return a URL that is suitable for use on the client.
        ///     If the URL is absolute, return it unchanged.  If it is relative, turn it into a 
        ///     relative URL that is correct from the point of view of the current request path 
        ///     (which is what the browser uses for resolution).
        ///  
        public string ResolveClientUrl(string relativeUrl) {
            if (DesignMode && Page != null && Page.Site != null) {
                IUrlResolutionService resolutionService = (IUrlResolutionService)Page.Site.GetService(typeof(IUrlResolutionService));
                if (resolutionService != null) { 
                    return resolutionService.ResolveClientUrl(relativeUrl);
                } 
            } 

            if (relativeUrl == null) { 
                throw new ArgumentNullException("relativeUrl");
            }

            // Get the app absolute TemplateSourceDirectory (not app relative) 
            string tplSourceDir = VirtualPath.GetVirtualPathString(TemplateControlVirtualDirectory);
            if (String.IsNullOrEmpty(tplSourceDir)) 
                return relativeUrl; 

            string baseRequestDir = Context.Request.ClientBaseDir.VirtualPathString; 

            // If the path is app relative (~/...), we cannot take shortcuts, since
            // the ~ is meaningless on the client, and must be resolved
            if (!UrlPath.IsAppRelativePath(relativeUrl)) { 

                // If the template source directory is the same as the directory of the request, 
                // we don't need to do any adjustments to the input path 
                if (StringUtil.EqualsIgnoreCase(baseRequestDir, tplSourceDir))
                    return relativeUrl; 

                // check if it's empty or absolute
                if ((relativeUrl.Length == 0) || (!UrlPath.IsRelativeUrl(relativeUrl))) {
                    return relativeUrl; 
                }
            } 
 
            // first make it absolute
            string url = UrlPath.Combine(tplSourceDir, relativeUrl); 

            // Make sure the path ends with a slash before calling MakeRelative
            baseRequestDir = UrlPath.AppendSlashToPathIfNeeded(baseRequestDir);
 
            // Now, make it relative to the current request, so that the client will
            // compute the correct path 
            return HttpUtility.UrlPathEncode(UrlPath.MakeRelative(baseRequestDir, url)); 
        }
 
        internal void DirtyNameTable() {
            Debug.Assert(this is INamingContainer);
            if(_occasionalFields != null) {
                _occasionalFields.NamedControls = null; 
            }
        } 
 
        private void EnsureNamedControlsTable() {
            Debug.Assert(this is INamingContainer); 
            Debug.Assert(HasControls());
            Debug.Assert(_occasionalFields != null);
            Debug.Assert(_occasionalFields.NamedControls == null);
 
            _occasionalFields.NamedControls = new HybridDictionary(/*initialSize*/ _occasionalFields.NamedControlsID, /*caseInsensitive*/ true);
            FillNamedControlsTable(this, _occasionalFields.Controls); 
        } 

        private void FillNamedControlsTable(Control namingContainer, ControlCollection controls) { 
            Debug.Assert(namingContainer._occasionalFields != null);
            Debug.Assert(namingContainer._occasionalFields.NamedControls != null);
            Debug.Assert((controls != null) && (controls.Count != 0));
 
            int controlCount = controls.Count;
            for (int i=0; i < controlCount; i++) { 
                Control control = controls[i]; 
                if (control._id != null) {
#if DEBUG 
                    if (control._namingContainer != null) {
                        Debug.Assert(control._namingContainer == namingContainer);
                    }
#endif // DEBUG 
                    try {
                        namingContainer.EnsureOccasionalFields(); 
                        namingContainer._occasionalFields.NamedControls.Add(control._id, control); 
                    }
                    catch { 
                        throw new HttpException(SR.GetString(SR.Duplicate_id_used, control._id, "FindControl"));
                    }
                }
                if (control.HasControls() && (control.flags[isNamingContainer] == false)) { 
                    FillNamedControlsTable(namingContainer, control.Controls);
                } 
            } 
        }
 

        /// 
        ///    Searches the current naming container for a control with
        ///       the specified  . 
        /// 
        public virtual Control FindControl(String id) { 
            return FindControl(id, 0); 
        }
 

        /// 
        /// 
        ///    Searches the current naming container for a control with the specified 
        ///     and an offset to aid in the
        ///       search. 
        ///  
        protected virtual Control FindControl(String id, int pathOffset) {
            string childID; 

            EnsureChildControls();

            // If we're not the naming container, let it do the job 
            if (!(flags[isNamingContainer])) {
                Control namingContainer = NamingContainer; 
                if (namingContainer != null) { 
                    return namingContainer.FindControl(id, pathOffset);
                } 
                return null;
            }

            // No registered control, demand create the named controls table 
            //call HasControls ensuress _occasionalFields != null
            if(HasControls() && _occasionalFields.NamedControls == null) { 
                EnsureNamedControlsTable(); 
            }
            if (_occasionalFields == null || _occasionalFields.NamedControls == null) { 
                return null;
            }

            // Need to support ':' for V1 backward compatibility. 
            char[] findControlSeparators = { ID_SEPARATOR, LEGACY_ID_SEPARATOR };
 
            // Is it a hierarchical name? 
            int newPathOffset = id.IndexOfAny(findControlSeparators, pathOffset);
 
            // If not, handle it here
            if (newPathOffset == -1) {
                childID = id.Substring(pathOffset);
                return _occasionalFields.NamedControls[childID] as Control; 
            }
 
            // Get the name of the child, and try to locate it 
            childID = id.Substring(pathOffset, newPathOffset - pathOffset);
            Control child =  _occasionalFields.NamedControls[childID] as Control; 

            // Child doesn't exist: fail
            if (child == null)
                return null; 

            return child.FindControl(id, newPathOffset + 1); 
        } 

        /* 
         * Called when the controls of a naming container are cleared.
         */
        internal void ClearNamingContainer() {
            Debug.Assert(this is INamingContainer); 

            EnsureOccasionalFields(); 
            _occasionalFields.NamedControlsID = 0; 
            DirtyNameTable();
        } 


        /// 
        ///  
        /// 
        [SecurityPermission(SecurityAction.Demand, Unrestricted = true)] 
        protected virtual IDictionary GetDesignModeState() { 
            ControlRareFields rareFields = RareFieldsEnsured;
            if (rareFields.DesignModeState == null) { 
                rareFields.DesignModeState = new HybridDictionary();
            }
            return rareFields.DesignModeState;
        } 

 
        ///  
        ///    Determines if the current control contains any child
        ///       controls. Since this method simply deteremines if any child controls exist at 
        ///       all, it can enhance performance by avoiding a call to the Count property,
        ///       inherited from the  class, on the 
        ///       property.
        ///  
        public virtual bool HasControls() {
            return _occasionalFields != null && _occasionalFields.Controls != null && _occasionalFields.Controls.Count > 0; 
        } 

        /* 
         * Check if a Control either has children or has a compiled render method.
         * This is to address issues like ASURT 94127
         */
        internal bool HasRenderingData() { 
            return HasControls() || HasRenderDelegate();
        } 
 
        /*
         * Check if a Control either has children or has a compiled render method. 
         * This is to address issues like ASURT 94127
         */
        internal bool HasRenderDelegate() {
            if(RareFields != null) { 
                return (RareFields.RenderMethod != null );
            } 
            return false; 
        }
 
        /*
         * Returns true if the container contains just a static string, i.e.,
         * when the Controls collection has a single LiteralControl.
         */ 

        ///  
        ///    Determines if the container holds literal content only. 
        ///       When this method returns 
        ///       , the container collection only holds a single literal control. The 
        ///       content is then passed to the requesting browser as HTML.
        /// 
        protected bool IsLiteralContent() {
            return (_occasionalFields != null && _occasionalFields.Controls != null) && (_occasionalFields.Controls.Count == 1) && 
            ((_occasionalFields.Controls[0] is LiteralControl));
        } 
 

        ///  
        ///    Determines if view state changes to the
        ///    
        ///    are being saved. 
        ///  
        protected bool IsTrackingViewState {
            get { 
                return flags[marked]; 
            }
        } 


        /// 
        ///    Turns on tracking of view state changes to the control 
        ///       so that they can be stored in the 
        ///       object. 
        ///  
        protected virtual void TrackViewState() {
            if (_viewState != null) 
                _viewState.TrackViewState();

            flags.Set(marked);
        } 

 
        ///  
        ///    Checks that the control contains child controls; if it does not, it creates
        ///       them. This includes any literal content being parsed as a  
        ///       object. 
        /// 
        protected virtual void EnsureChildControls() {
            if (!ChildControlsCreated && !flags[creatingControls]) { 
                flags.Set(creatingControls);
                try { 
                    ResolveAdapter(); 
                    if(_adapter != null) {
                        _adapter.CreateChildControls(); 
                    }
                    else {
                        CreateChildControls();
                    } 

                    // Only set ChildControlsCreated = true if CreateChildControls() did not throw 
                    // an exception (VSWhidbey 465798). 
                    ChildControlsCreated = true;
                } 
                finally {
                    flags.Clear(creatingControls);
                }
            } 
        }
 
        ///  
        /// Used internally to store a ControlBuilder reference for the control.
        /// The builder will be used at design-time to help persist all the filtered properties 
        /// of the control.
        /// 
        internal void SetControlBuilder(ControlBuilder controlBuilder) {
            RareFieldsEnsured.ControlBuilder = controlBuilder; 
        }
 
 
        /// 
        ///  
        protected internal virtual void RemovedControl(Control control) {
            if (control.OwnerControl != null) {
                throw new InvalidOperationException(SR.GetString(SR.Substitution_NotAllowed));
            } 

            if ((_namingContainer != null) && (control._id != null)) { 
                _namingContainer.DirtyNameTable(); 
            }
 
            // Controls may need to do their own cleanup.
            control.UnloadRecursive(false);

            control._parent = null; 
            control._page = null;
            control._namingContainer = null; 
 
            // Don't reset _templateSourceVirtualDirectory on TemplateControl's, because
            // the path is their own, not their parent. i.e. it doesn't change no matter 
            // where in the tree they end up.
            if (!(control is TemplateControl))
                control._templateSourceVirtualDirectory = null;
 
            control._templateControl = null;
 
            control.flags.Clear(mustRenderID); 
            control.ClearCachedUniqueIDRecursive();
        } 

        internal void SetDesignMode() {
            flags.Set(designMode);
            flags.Set(designModeChecked); 
        }
 
 
        /// 
        ///  
        /// 
        protected virtual void SetDesignModeState(IDictionary data) {
        }
 
        // Set the delegate to the render method
 
        ///  
        /// 
        ///    Assigns any event handler delegates for the control to match the parameters 
        ///       defined in the . 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        public void SetRenderMethodDelegate(RenderMethod renderMethod) { 
            RareFieldsEnsured.RenderMethod = renderMethod;
 
            // Make the collection readonly if there are code blocks (ASURT 78810) 
            Controls.SetCollectionReadOnly(SR.Collection_readonly_Codeblocks);
        } 


        /// 
        ///  
        ///    Returns whether the control contains any data binding logic. This method is
        ///       only accessed by RAD designers. 
        ///  
        bool IDataBindingsAccessor.HasDataBindings {
            get { 
                return ((RareFields != null) && (RareFields.DataBindings != null) && (RareFields.DataBindings.Count != 0));
            }
        }
 

        ///  
        ///  
        /// Indicates a collection of all data bindings on the control. This property is
        /// read-only. 
        /// 
        DataBindingCollection IDataBindingsAccessor.DataBindings {
            get {
                ControlRareFields rareFields = RareFieldsEnsured; 
                if (rareFields.DataBindings == null) {
                    rareFields.DataBindings = new DataBindingCollection(); 
                } 
                return rareFields.DataBindings;
            } 
        }


        // IParserAccessor interface 
        // A sub-object tag was parsed by the parser; add it to this control.
 
        ///  
        /// 
        /// Notifies the control that an element, XML or HTML, was parsed, and adds it to 
        /// the control.
        /// 
        void IParserAccessor.AddParsedSubObject(object obj) {
            AddParsedSubObject(obj); 
        }
 
        internal string SpacerImageUrl { 
            get {
                EnsureOccasionalFields(); 
                if (_occasionalFields.SpacerImageUrl == null) {
                    _occasionalFields.SpacerImageUrl = Page.ClientScript.GetWebResourceUrl(typeof(WebControl), "Spacer.gif");
                }
                return _occasionalFields.SpacerImageUrl; 
            }
        } 
 
        private Control OwnerControl {
            get { 
                if (RareFields == null) {
                    return null;
                }
 
                return RareFields.OwnerControl;
            } 
            set { 
                RareFieldsEnsured.OwnerControl = value;
            } 
        }

        internal IPostBackDataHandler PostBackDataHandler {
            get { 
                IPostBackDataHandler pbdh = _adapter as IPostBackDataHandler;
                if(pbdh != null) 
                    return pbdh; 
                pbdh = this as IPostBackDataHandler;
                return pbdh; 
            }
        }

        internal IPostBackEventHandler PostBackEventHandler { 
            get {
                IPostBackEventHandler pbeh = _adapter as IPostBackEventHandler; 
                if(pbeh != null) 
                    return pbeh;
                pbeh = this as IPostBackEventHandler; 
                return pbeh;
            }
        }
 
#if ORCAS
        internal bool NotVisibleOnPage { 
            get { 
                return flags[notVisibleOnPage];
            } 

            set {
                if(value) {
                    flags.Set(notVisibleOnPage); 
                }
                else { 
                    flags.Clear(notVisibleOnPage); 
                }
            } 
        }

        internal int VirtualStartPage {
            get { 
                return RareFields != null ? RareFields.VirtualStartPage : -1;
            } 
            set { 
                RareFieldsEnsured.VirtualStartPage = value;
            } 
        }

        internal int VirtualEndPage {
            get { 
                return RareFields != null ? RareFields.VirtualEndPage : -1;
            } 
 
            set {
                RareFieldsEnsured.VirtualEndPage = value; 
            }
        }
#endif
 
        #region IControlDesignerAccessor implementation
 
        ///  
        IDictionary IControlDesignerAccessor.UserData {
            get { 
                ControlRareFields rareFields = RareFieldsEnsured;
                if (rareFields.ControlDesignerAccessorUserData == null) {
                    rareFields.ControlDesignerAccessorUserData = new HybridDictionary();
                } 
                return rareFields.ControlDesignerAccessorUserData;
            } 
        } 

        ///  
        /// 
        /// 
        IDictionary IControlDesignerAccessor.GetDesignModeState() {
            return GetDesignModeState(); 
        }
 
 
        /// 
        ///  
        /// 
        void IControlDesignerAccessor.SetDesignModeState(IDictionary data) {
            SetDesignModeState(data);
        } 

        void IControlDesignerAccessor.SetOwnerControl(Control owner) { 
            if (owner == this) { 
                throw new ArgumentException(SR.GetString(SR.Control_CannotOwnSelf), "owner");
            } 
            OwnerControl = owner;
            _parent = owner.Parent;
            _page = owner.Page;
        } 
        #endregion
 
        #region IControlBuilderAccessor implementation 

        ///  
        /// 
        /// A reference to the ControlBuilder that was used to construct this control (if there was one)
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        ControlBuilder IControlBuilderAccessor.ControlBuilder {
            get { 
                return RareFields != null ? RareFields.ControlBuilder : null;
            }
        }
        #endregion IControlBuilderAccessor implementation 

        #region IExpressionsAccessor 
 

        ///  
        bool IExpressionsAccessor.HasExpressions {
            get {
                if (RareFields == null) {
                    return false; 
                }
                ExpressionBindingCollection expressions = RareFields.ExpressionBindings; 
                return ((expressions != null) && (expressions.Count > 0)); 
            }
        } 


        /// 
        ExpressionBindingCollection IExpressionsAccessor.Expressions { 
            get {
                ExpressionBindingCollection expressions = RareFieldsEnsured.ExpressionBindings; 
                if (expressions == null) { 
                    expressions = new ExpressionBindingCollection();
                    RareFields.ExpressionBindings = expressions; 
                }
                return expressions;
            }
        } 
        #endregion
 
        private sealed class ControlRareFields : IDisposable { 

            internal ControlRareFields() { 
            }
            public ISite Site;
            public RenderMethod RenderMethod;
            // Reference to the templateControl that hosts this control. 
#if ORCAS
            public int VirtualStartPage = -1; 
            public int VirtualEndPage = -1; 
            public ContentPager ContentPager;
#endif 
            // Reference to the ControlBuilder used to build this control
            public ControlBuilder ControlBuilder;
            public DataBindingCollection DataBindings;
            public Control OwnerControl; 
            public ExpressionBindingCollection ExpressionBindings;
            public bool RequiredControlState = false; 
 
            // These fields are only used in the designer so we
            // keep them here to prevent memory bloat at runtime 
            public IDictionary ControlDesignerAccessorUserData;
            public IDictionary DesignModeState;

            public void Dispose() { 
                //do not null out for backwards compat, VSWhidbey 475940
                //Site = null; 
                //RenderMethod = null; 
                //DataBindings = null;
                //OwnerControl = null; 
                //ExpressionBindings = null;
                ControlBuilder = null;
                if (OwnerControl != null)
                { 
                    OwnerControl.Dispose();
                } 
                ControlDesignerAccessorUserData = null; 
                DesignModeState = null;
 
#if ORCAS
                ContentPager = null;
#endif
            } 
        }
 
        private sealed class OccasionalFields : IDisposable { 
            internal OccasionalFields() {
            } 

            public string SkinId;
            // Events
            public EventHandlerList Events; 
            public IDictionary ControlsViewState;
            public ControlCollection Controls; 
            public int NamedControlsID; 
            // Only used if we are a naming container.  It contains all the controls
            // in the namespace. 
            public IDictionary NamedControls;
            public ControlRareFields RareFields;
            public String UniqueIDPrefix;
 
            public string SpacerImageUrl;
 
            public void Dispose() { 
                if (Events != null) {
                    Events.Dispose(); 
                    Events = null;
                }
                if (RareFields != null) {
                    RareFields.Dispose(); 
                }
 
                ControlsViewState = null; 
                //do not null out for backwards compat, VSWhidbey 475940
                //Controls = null; 
                //NamedControls = null;
                //UniqueIDPrefix = null;
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI { 
    using System.Text; 
    using System.ComponentModel;
    using System; 
    using System.Collections;
    using System.Collections.Specialized;
    using System.ComponentModel.Design;
    using System.ComponentModel.Design.Serialization; 
    using System.Globalization;
    using System.Reflection; 
    using System.IO; 
    using HttpException = System.Web.HttpException;
    using System.Web.Configuration; 
    using System.Web.UI.Adapters;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.Util; 
    using System.Web.Hosting;
    using System.Web.Caching; 
    using System.Security.Permissions; 

    // Delegate used for the compiled template 
    public delegate void RenderMethod(HtmlTextWriter output, Control container);

    public delegate Control BuildMethod();
 
    // Defines the properties, methods, and events that are shared by all server
    // controls in the Web Forms page framework. 
    [ 
    Bindable(true),
    DefaultProperty("ID"), 
    DesignerCategory("Code"),
    Designer("System.Web.UI.Design.ControlDesigner, " + AssemblyRef.SystemDesign),
    DesignerSerializer("Microsoft.VisualStudio.Web.WebForms.ControlCodeDomSerializer, " + AssemblyRef.MicrosoftVisualStudioWeb,  "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + AssemblyRef.SystemDesign),
    Themeable(false), 
    ToolboxItemFilter("System.Web.UI", ToolboxItemFilterType.Require),
    ToolboxItemAttribute("System.Web.UI.Design.WebControlToolboxItem, " + AssemblyRef.SystemDesign) 
    ] 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] 
    public class Control : IComponent, IParserAccessor, IUrlResolutionService, IDataBindingsAccessor, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor {

        internal static readonly object EventDataBinding = new object();
        internal static readonly object EventInit = new object(); 
        internal static readonly object EventLoad = new object();
        internal static readonly object EventUnload = new object(); 
        internal static readonly object EventPreRender = new object(); 
        private static readonly object EventDisposed = new object();
 
        internal const bool EnableViewStateDefault = true;
        internal const char ID_SEPARATOR = '$';
        private const char ID_RENDER_SEPARATOR = '_';
        internal const char LEGACY_ID_SEPARATOR = ':'; 

        private string _id; 
        // allows us to reuse the id variable to store a calculated id w/o polluting the public getter 
        private string _cachedUniqueID;
        private Control _parent; 

        // fields related to being a container
        private ControlState _controlState;
        private StateBag _viewState; 

        // The naming container that this control leaves in.  Note that even if 
        // this ctrl is a naming container, it will not point to itself, but to 
        // the naming container that contains it.
        private Control _namingContainer; 
        internal Page _page;
        private OccasionalFields _occasionalFields;
        private TemplateControl _templateControl;
        // The virtual directory of the Page or UserControl that hosts this control. 
        private VirtualPath _templateSourceVirtualDirectory;
        internal ControlAdapter _adapter; 
 
        // const masks into the BitVector32
        private const int idNotCalculated           = 0x00000001; 
        private const int marked                    = 0x00000002;
        private const int disableViewState          = 0x00000004;
        private const int controlsCreated           = 0x00000008;
        private const int invisible                 = 0x00000010; 
        private const int visibleDirty              = 0x00000020;
        private const int idNotRequired             = 0x00000040; 
        private const int isNamingContainer         = 0x00000080; 
        private const int creatingControls          = 0x00000100;
        private const int notVisibleOnPage          = 0x00000200; 
        private const int themeApplied              = 0x00000400;
        private const int mustRenderID              = 0x00000800;
        private const int disableTheming            = 0x00001000;
        private const int enableThemingSet          = 0x00002000; 
        private const int styleSheetApplied         = 0x00004000;
        private const int controlAdapterResolved    = 0x00008000; 
        private const int designMode                = 0x00010000; 
        private const int designModeChecked         = 0x00020000;
        private const int disableChildControlState  = 0x00040000; 
        internal const int isWebControlDisabled     = 0x00080000;
        private const int controlStateApplied       = 0x00100000;
        private const int useGeneratedID            = 0x00200000;
        #pragma warning disable 0649 
        internal SimpleBitVector32 flags;
        #pragma warning restore 0649 
 
        private const string automaticIDPrefix = "ctl";
        private const string automaticLegacyIDPrefix = "_ctl"; 
        private const int automaticIDCount = 128;
        private static readonly string[] automaticIDs = new string [automaticIDCount] {
            "ctl00", "ctl01", "ctl02", "ctl03", "ctl04", "ctl05", "ctl06",
            "ctl07", "ctl08", "ctl09", "ctl10", "ctl11", "ctl12", "ctl13", 
            "ctl14", "ctl15", "ctl16", "ctl17", "ctl18", "ctl19", "ctl20",
            "ctl21", "ctl22", "ctl23", "ctl24", "ctl25", "ctl26", "ctl27", 
            "ctl28", "ctl29", "ctl30", "ctl31", "ctl32", "ctl33", "ctl34", 
            "ctl35", "ctl36", "ctl37", "ctl38", "ctl39", "ctl40", "ctl41",
            "ctl42", "ctl43", "ctl44", "ctl45", "ctl46", "ctl47", "ctl48", 
            "ctl49", "ctl50", "ctl51", "ctl52", "ctl53", "ctl54", "ctl55",
            "ctl56", "ctl57", "ctl58", "ctl59", "ctl60", "ctl61", "ctl62",
            "ctl63", "ctl64", "ctl65", "ctl66", "ctl67", "ctl68", "ctl69",
            "ctl70", "ctl71", "ctl72", "ctl73", "ctl74", "ctl75", "ctl76", 
            "ctl77", "ctl78", "ctl79", "ctl80", "ctl81", "ctl82", "ctl83",
            "ctl84", "ctl85", "ctl86", "ctl87", "ctl88", "ctl89", "ctl90", 
            "ctl91", "ctl92", "ctl93", "ctl94", "ctl95", "ctl96", "ctl97", 
            "ctl98", "ctl99",
            "ctl100", "ctl101", "ctl102", "ctl103", "ctl104", "ctl105", "ctl106", 
            "ctl107", "ctl108", "ctl109", "ctl110", "ctl111", "ctl112", "ctl113",
            "ctl114", "ctl115", "ctl116", "ctl117", "ctl118", "ctl119", "ctl120",
            "ctl121", "ctl122", "ctl123", "ctl124", "ctl125", "ctl126", "ctl127"
 
        };
 
        ///  
        /// Initializes a new instance of the  class.
        ///  
        public Control() {
            if (this is INamingContainer)
                flags.Set(isNamingContainer);
        } 

 
        ///  
        ///    Indicates the control identifier generated by the ASP.NET framework. This
        ///       property is read-only.  
        /// 
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_ClientID)
        ] 
        public virtual string ClientID { 
            // This property is required to render a unique client-friendly id.
            get { 
                // Ensure that ID is set. The assumption being made is that the caller
                // is likely to use the client ID in script, and to support that the
                // control should render out an ID attribute
                EnsureID(); 
                string uniqueID = UniqueID;
                if(uniqueID != null && uniqueID.IndexOf(IdSeparator) >= 0) { 
                    return uniqueID.Replace(IdSeparator, ID_RENDER_SEPARATOR); 
                }
                return uniqueID; 
            }
        }

        protected char ClientIDSeparator { 
            get {
                return ID_RENDER_SEPARATOR; 
            } 
        }
 
        /// 
        ///    [To be supplied.]
        /// 
        [ 
        WebSysDescription(SR.Control_OnDisposed)
        ] 
        public event EventHandler Disposed { 
            add {
                Events.AddHandler(EventDisposed, value); 
            }
            remove {
                Events.RemoveHandler(EventDisposed, value);
            } 
        }
 
        ///  
        /// Gets the  object of the current Web request. If
        ///    the control's context is , this will be the context of the 
        ///    control's parent, unless the parent control's context is .
        ///    If this is the case, this will be equal to the HttpContext property.
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        protected internal virtual HttpContext Context {
            //  Request context containing the intrinsics 
            get {
                Page page = Page;
                if(page != null) {
                    return page.Context; 
                }
                return HttpContext.Current; 
            } 
        }
 
        protected virtual ControlAdapter ResolveAdapter() {
            if(flags[controlAdapterResolved]) {
                return _adapter;
            } 
            if (DesignMode) {
                flags.Set(controlAdapterResolved); 
                return null; 
            }
 
            HttpContext context = Context;
            if (context != null) {
                _adapter = context.Request.Browser.GetAdapter(this);
            } 
            flags.Set(controlAdapterResolved);
            return _adapter; 
        } 

        ///  
        ///    Indicates the list of event handler delegates for the control. This property
        ///       is read-only.
        /// 
        protected ControlAdapter Adapter { 
            get {
                if(flags[controlAdapterResolved]) { 
                    return _adapter; 
                }
                _adapter = ResolveAdapter(); 
                flags.Set(controlAdapterResolved);
                return _adapter;
            }
        } 

        ///  
        /// Indicates whether a control is being used in the context of a design surface. 
        /// 
        protected internal bool DesignMode { 
            get {
                if(!flags[designModeChecked]) {
                    Page page = Page;
                    if(page != null )  { 
                        if(page.GetDesignModeInternal()) {
                            flags.Set(designMode); 
                        } 
                        else {
                            flags.Clear(designMode); 
                        }
                    }
                    else {
                        if(Site != null) { 
                            if(Site.DesignMode) {
                                flags.Set(designMode); 
                            } 
                            else {
                                flags.Clear(designMode); 
                            }
                        }
                        else if (Parent != null) {
                            if(Parent.DesignMode) { 
                                flags.Set(designMode);
                            } 
 
                            // VSWhidbey 535747: If Page, Site and Parent are all null, do not change the
                            // designMode flag since it might had been previously set by the controlBuilder. 
                            // This does not affect runtime since designMode is by-default false.
                            /*
                            else {
                                flags.Clear(designMode); 
                            }
                            */ 
                        } 
                    }
                    flags.Set(designModeChecked); 
                }
                return flags[designMode];

            } 
        }
 
        // Helper function to call validateEvent. 
        internal void ValidateEvent(string uniqueID) {
            ValidateEvent(uniqueID, String.Empty); 
        }

        // Helper function to call validateEvent.
        internal void ValidateEvent(string uniqueID, string eventArgument) { 
            if (Page != null && SupportsEventValidation) {
                Page.ClientScript.ValidateEvent(uniqueID, eventArgument); 
            } 
        }
 
        // Indicates whether the control supports event validation
        // By default, all web controls in System.Web assembly supports it but not custom controls.
        private bool SupportsEventValidation {
            get { 
                return SupportsEventValidationAttribute.SupportsEventValidation(this.GetType());
            } 
        } 

        ///  
        ///    Indicates the list of event handler delegates for the control. This property
        ///       is read-only.
        /// 
        protected EventHandlerList Events { 
            get {
                EnsureOccasionalFields(); 
                if(_occasionalFields.Events == null) { 
                    _occasionalFields.Events = new EventHandlerList();
                } 
                return _occasionalFields.Events;
            }
        }
 
        protected bool HasEvents() {
            return ((_occasionalFields != null) && (_occasionalFields.Events != null)); 
        } 

        ///  
        ///     Gets or sets the identifier for the control. Setting the
        ///       property on a control allows programmatic access to the control's properties. If
        ///       this property is not specified on a control, either declaratively or
        ///       programmatically, then you cannot write event handlers and the like for the control. 
        /// 
        [ 
        ParenthesizePropertyName(true), 
        MergableProperty(false),
        Filterable(false), 
        Themeable(false),
        WebSysDescription(SR.Control_ID)
        ]
        public virtual string ID { 
            get {
                if (!flags[idNotCalculated] && !flags[mustRenderID]) { 
                    return null; 
                }
                return _id; 
            }
            set {
                // allow the id to be unset
                if (value != null && value.Length == 0) 
                    value = null;
 
                string oldID = _id; 

                _id = value; 
                ClearCachedUniqueIDRecursive();
                flags.Set(idNotCalculated);
                flags.Clear(useGeneratedID);
 
                // Update the ID in the naming container
                if ((_namingContainer != null) && (oldID != null)) { 
                    _namingContainer.DirtyNameTable(); 
                }
            } 
        }


        ///  
        ///    Gets and sets a value indicating whether theme is enabled.
        ///  
        [ 
        Browsable(false),
        DefaultValue(true), 
        Themeable(false),
        WebCategory("Behavior"),
        WebSysDescription(SR.Control_EnableTheming)
        ] 
        public virtual bool EnableTheming {
            get { 
                if (flags[enableThemingSet]) { 
                    return !flags[disableTheming];
                } 

                if (Parent != null) {
                    return Parent.EnableTheming;
                } 

                return !flags[disableTheming]; 
            } 
            set {
                if ((_controlState >= ControlState.FrameworkInitialized) && !DesignMode) { 
                    throw new InvalidOperationException(SR.GetString(SR.PropertySetBeforePreInitOrAddToControls, "EnableTheming"));
                }

                if(!value) { 
                    flags.Set(disableTheming);
                } 
                else { 
                    flags.Clear(disableTheming);
                } 

                flags.Set(enableThemingSet);
            }
        } 

        // Serialzie the value if it's set explicitely. 
        internal bool ShouldSerializeEnableTheming() { 
            return flags[enableThemingSet];;
        } 

        internal bool IsBindingContainer {
            get {
                return this is INamingContainer && !(this is INonBindingContainer); 
            }
        } 
 
        protected internal bool IsChildControlStateCleared {
            get { 
                return flags[disableChildControlState];
            }
        }
 

        ///  
        ///    Gets and sets the skinID of the control. 
        /// 
        [ 
        Browsable(false),
        DefaultValue(""),
        Filterable(false),
        WebCategory("Behavior"), 
        WebSysDescription(SR.Control_SkinId),
        ] 
        public virtual string SkinID { 
            get {
                if(_occasionalFields != null) { 
                    return _occasionalFields.SkinId == null ? String.Empty : _occasionalFields.SkinId;
                }
                return String.Empty;
            } 
            set {
                if (!DesignMode) { 
                    if (flags[styleSheetApplied]) { 
                        throw new InvalidOperationException(SR.GetString(SR.PropertySetBeforeStyleSheetApplied, "SkinId"));
                    } 

                    if (_controlState >= ControlState.FrameworkInitialized) {
                        throw new InvalidOperationException(SR.GetString(SR.PropertySetBeforePreInitOrAddToControls, "SkinId"));
                    } 
                }
 
                EnsureOccasionalFields(); 
                _occasionalFields.SkinId = value;
            } 
        }

        private ControlRareFields RareFieldsEnsured {
            get { 
                EnsureOccasionalFields();
                ControlRareFields rareFields = _occasionalFields.RareFields; 
                if(rareFields == null) { 
                    rareFields = new ControlRareFields();
                    _occasionalFields.RareFields = rareFields; 
                }

                return rareFields;
            } 
        }
 
        private ControlRareFields RareFields { 
            get {
                if(_occasionalFields != null) { 
                    return _occasionalFields.RareFields;
                }
                return null;
            } 
        }
 
        private void EnsureOccasionalFields() { 
            if(_occasionalFields == null) {
                _occasionalFields = new OccasionalFields(); 
            }
        }

 
        /// 
        ///     
        ///       Gets or sets a value indicating whether the control should maintain its view 
        ///       state, and the view state of any child control in contains, when the current
        ///       page request ends. 
        ///    
        /// 
        [
        DefaultValue(EnableViewStateDefault), 
        Themeable(false),
        WebCategory("Behavior"), 
        WebSysDescription(SR.Control_MaintainState) 
        ]
        public virtual bool EnableViewState { 
            get {
                return !flags[disableViewState];
            }
            set { 
                SetEnableViewStateInternal(value);
            } 
        } 

        internal void SetEnableViewStateInternal(bool value) { 
            if (!value)
                flags.Set(disableViewState);
            else
                flags.Clear(disableViewState); 
        }
 
 
        /// 
        /// Gets a value indicating whether the control is maintaining its view 
        /// state, when the current page request ends by looking at its own EnableViewState
        /// value, and the value for all its parents.
        /// 
        protected internal bool IsViewStateEnabled { 
            get {
                Control current = this; 
                while (current != null) { 
                    if (current.EnableViewState == false) {
                        return false; 
                    }
                    current = current.Parent;
                }
                return true; 
            }
        } 
 

        ///  
        ///    Gets the reference to the current control's naming container.
        /// 
        [
        Bindable(false), 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_NamingContainer) 
        ]
        public virtual Control NamingContainer { 
            get {
                if (_namingContainer == null) {
                    if (Parent != null) {
                        // Search for the closest naming container in the tree 
                        if (Parent.flags[isNamingContainer])
                            _namingContainer = Parent; 
                        else 
                            _namingContainer = Parent.NamingContainer;
                    } 
                }

                return _namingContainer;
            } 
        }
 
        ///  
        /// 
        ///    Returns the databinding container of this control.  In most cases, 
        ///     this is the same as the NamingContainer. But when using LoadTemplate(),
        ///     we get into a situation where that is not the case (ASURT 94138)
        ///     The behavior is different than V1 that Usercontrol.BindingContainer is no
        ///     longer the UserControl but the control contains it. The behavior is consistent 
        ///     with LoadTemplate() case.
        ///  
        [ 
        Bindable(false),
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        EditorBrowsable(EditorBrowsableState.Never)
        ]
        public Control BindingContainer { 
            get {
                Control bindingContainer = NamingContainer; 
                while (bindingContainer is INonBindingContainer) { 
                    bindingContainer = bindingContainer.BindingContainer;
                } 

                return bindingContainer;
            }
        } 

        ///  
        ///  
        /// VSWhidbey 80467: Need to adapt id separator.
        ///  
        protected char IdSeparator {
            get {
                if (Page != null) {
                    return Page.IdSeparator; 
                }
                return IdSeparatorFromConfig; 
            } 
        }
 
        // VSWhidbey 475945: Use the old id separator if configured
        internal char IdSeparatorFromConfig {
            get {
                return ((EnableLegacyRendering) ? LEGACY_ID_SEPARATOR : ID_SEPARATOR); 
            }
        } 
 
        // VSWhidbey 244374: Allow controls to opt into loading view state by ID instead of index (perf hit)
        protected bool LoadViewStateByID { 
            get {
                return ViewStateModeByIdAttribute.IsEnabled(GetType());
            }
        } 

        ///  
        ///  Gets the  object that contains the 
        ///    current control.
        ///  
        [
        Bindable(false),
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_Page)
        ] 
        public virtual Page Page { 
            get {
                if (_page == null) { 
                    if (Parent != null) {
                        _page = Parent.Page;
                    }
                } 
                return _page;
            } 
 
            set {
                if (OwnerControl != null) { 
                    throw new InvalidOperationException();
                }
                // This is necessary because we need to set the page in generated
                // code before controls are added to the tree (ASURT 75330) 
                Debug.Assert(_page == null);
                Debug.Assert(Parent == null || Parent.Page == null); 
                _page = value; 
            }
        } 

        // VSWhidbey 244999
        internal virtual bool IsReloadable {
            get { 
                return false;
            } 
        } 

        // DevDiv 33149, 43258: A backward compat. switch for Everett rendering 
        internal bool EnableLegacyRendering {
            get {
                Page page = Page;
                if (page != null) { 
                    return (page.XhtmlConformanceMode == XhtmlConformanceMode.Legacy);
                } 
                else if (DesignMode || Adapter != null) { 
                    return false;
                } 
                else {
                    return (GetXhtmlConformanceSection().Mode == XhtmlConformanceMode.Legacy);
                }
            } 
        }
 
        internal XhtmlConformanceSection GetXhtmlConformanceSection() { 
            HttpContext context = Context;
            XhtmlConformanceSection xhtmlConformanceSection; 
            if (context != null) {
                // if context is available, use the most efficient way to get the section
                xhtmlConformanceSection = RuntimeConfig.GetConfig(context).XhtmlConformance;
            } 
            else {
                xhtmlConformanceSection = RuntimeConfig.GetConfig().XhtmlConformance; 
            } 
            Debug.Assert(xhtmlConformanceSection != null);
            return xhtmlConformanceSection; 
        }

#if ORCAS
 
        /// 
        ///  Gets the  object that 
        /// paginates the current control. 
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.Control_Pager)
        ] 
        public virtual ContentPager ContentPager {
            get { 
                ControlRareFields rareFields = RareFieldsEnsured; 

                if (rareFields.ContentPager == null) { 
                    if (Parent != null) {
                        rareFields.ContentPager = Parent.ContentPager;
                    }
                } 
                return rareFields.ContentPager;
            } 
            set { 
                RareFieldsEnsured.ContentPager = value;
            } 
        }
#endif

 
        /// 
        ///    Gets the reference to the  
        ///    that hosts the control. 
        /// 
        internal virtual TemplateControl GetTemplateControl() { 
            if(_templateControl == null) {
                if (Parent != null) {
                    _templateControl = Parent.GetTemplateControl();
                } 
            }
            return _templateControl; 
        } 

 
        /// 
        ///    Gets the reference to the 
        ///    that hosts the control.
        ///  
        [
        Bindable(false), 
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.Control_TemplateControl) 
        ]
        public TemplateControl TemplateControl {
            get {
                return GetTemplateControl(); 
            }
 
            [EditorBrowsable(EditorBrowsableState.Never)] 
            set {
                // This setter is necessary so that controls inside templates are based on 
                // hosting pages not where the templates are used.
                _templateControl = value;
            }
        } 

        /* 
         * Determine whether this control is a descendent of the passed in control 
         */
        internal bool IsDescendentOf(Control ancestor) { 
            Control current = this;
            while (current != ancestor && current.Parent != null) {
                current = current.Parent;
            } 
            return (current == ancestor);
        } 
 

        ///  
        ///     Gets the current control's parent control in the UI hierarchy.
        /// 
        [
        Bindable(false), 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_Parent) 
        ]
        public virtual Control Parent { 
            get {
                return _parent;
            }
        } 

        internal bool IsParentedToUpdatePanel { 
            get { 
                Control parent = Parent;
                while (parent != null) { 
                    if (parent is IUpdatePanel) {
                        return true;
                    }
                    parent = parent.Parent; 
                }
                return false; 
            } 
        }
 
        /// 
        ///     Gets the virtual directory of the Page or UserControl that contains this control.
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_TemplateSourceDirectory) 
        ]
        public virtual string TemplateSourceDirectory { 
            get {
                if (TemplateControlVirtualDirectory == null)
                    return String.Empty;
 
                return TemplateControlVirtualDirectory.VirtualPathStringNoTrailingSlash;
            } 
        } 

 
        /// 
        ///     Gets the virtual directory of the Page or UserControl that contains this control.
        ///         Unlike TemplateSourceDirectory, this returns an app relative path (e.g. "~/sub")
        ///  
        [
        Browsable(false), 
        EditorBrowsable(EditorBrowsableState.Advanced), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.Control_TemplateSourceDirectory) 
        ]
        public string AppRelativeTemplateSourceDirectory {
            get {
                return VirtualPath.GetAppRelativeVirtualPathStringOrEmpty(TemplateControlVirtualDirectory); 
            }
 
            [EditorBrowsable(EditorBrowsableState.Never)] 
            set {
                // This setter is necessary so that skins are based on hosting skin file. 
                this.TemplateControlVirtualDirectory = VirtualPath.CreateNonRelativeAllowNull(value);
            }
        }
 
        internal VirtualPath TemplateControlVirtualDirectory {
            get { 
                if (_templateSourceVirtualDirectory != null) 
                    return _templateSourceVirtualDirectory;
 
                TemplateControl control = TemplateControl;
                if (control == null) {
                    HttpContext context = Context;
                    if (context != null) { 
                        _templateSourceVirtualDirectory = context.Request.CurrentExecutionFilePathObject.Parent;
                    } 
                    return _templateSourceVirtualDirectory; 
                }
                // Prevent recursion if this is the TemplateControl 
                if (control != this) {
                    _templateSourceVirtualDirectory = control.TemplateControlVirtualDirectory;
                }
                return _templateSourceVirtualDirectory; 
            }
 
            set { 
                // This setter is necessary so that skins are based on hosting skin file.
                _templateSourceVirtualDirectory = value; 
            }
        }

        internal ControlState ControlState { 
            get { return _controlState; }
            set { _controlState = value; } 
        } 

 
        /// 
        ///    Indicates the site information for the control.
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        EditorBrowsable(EditorBrowsableState.Advanced), 
        WebSysDescription(SR.Control_Site)
        ] 
        public ISite Site {
            get {
                if (OwnerControl != null) {
                    return OwnerControl.Site; 
                }
 
                if (RareFields != null) { 
                    return RareFields.Site;
                } 
                return null;
            }
            set {
                if (OwnerControl != null) { 
                    throw new InvalidOperationException(SR.GetString(SR.Substitution_SiteNotAllowed));
                } 
 
                RareFieldsEnsured.Site = value;
                flags.Clear(designModeChecked); 
            }
        }

 
        /// 
        ///     
        ///       Gets or sets a value that indicates whether a control should be rendered on 
        ///       the page.
        ///     
        /// 
        [
        Bindable(true),
        DefaultValue(true), 
        WebCategory("Behavior"),
        WebSysDescription(SR.Control_Visible) 
        ] 
        public virtual bool Visible {
            get { 
                if (flags[invisible])
                    return false;
#if ORCAS
                if (NotVisibleOnPage) 
                    return false;
#endif 
                else if ((_parent != null) && !DesignMode) 
                    return _parent.Visible;
                else 
                    return true;
            }
            set {
                if (flags[marked]) { 
                    bool visible = !flags[invisible];
                    if (visible != value) { 
                        flags.Set(visibleDirty); 
                    }
                } 

                if(!value) {
                    flags.Set(invisible);
                } 
                else {
                    flags.Clear(invisible); 
                } 
            }
        } 

#if ORCAS
        internal bool ExplicitlyInvisible {
            get { 
                return flags[invisible];
            } 
        } 
#endif
 


        /// 
        /// Do not remove or change the signature. It is called via reflection. 
        /// This allows for correct serialization, since Visible is implemented as a
        /// recursive property. 
        ///  
        private void ResetVisible() {
            Visible = true; 
        }


        ///  
        /// Do not remove or change the signature. It is called via reflection.
        /// This allows for correct serialization, since Visible is implemented as a 
        /// recursive property. 
        /// 
        private bool ShouldSerializeVisible() { 
            return flags[invisible];
        }

 
        /// 
        ///     Gets the unique, hierarchically-qualified identifier for 
        ///       a control. This is different from the ID property, in that the fully-qualified 
        ///       identifier includes the identifier for the control's naming container.
        ///  
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.Control_UniqueID) 
        ]
        public virtual string UniqueID { 
            get { 
                if (_cachedUniqueID != null) {
                    return _cachedUniqueID; 
                }

                Control namingContainer = NamingContainer;
                if (namingContainer != null) { 
                    // if the ID is null at this point, we need to have one created and the control added to the
                    // naming container. 
                    if (_id == null) { 
                        GenerateAutomaticID();
                    } 

                    if (Page == namingContainer) {
                        _cachedUniqueID = _id;
                    } 
                    else {
                        string uniqueIDPrefix = namingContainer.GetUniqueIDPrefix(); 
                        if (uniqueIDPrefix.Length == 0) { 
                            // In this case, it is probably a naming container that is not sited, so we don't want to cache it
                            return _id; 
                        }
                        else {
                            _cachedUniqueID = uniqueIDPrefix + _id;
                        } 
                    }
 
                    return _cachedUniqueID; 
                }
                else { 
                    // no naming container
                    return _id;
                }
            } 
        }
 
        #if SHIPPINGADAPTERS 
        // Used by adapters in delegating rendering (e.g., a Button for a LinkButton for scriptless devices).
        // The UniqueID of the new control has to be set to match the UniqueID of the original. 
        internal void SetUniqueID(string val) {
            _cachedUniqueID = val;
        }
        #endif 

 
        ///  
        ///    Occurs when the control binds to a data source. Notifies the control to perform any data binding during this event.
        ///  
        [
        WebCategory("Data"),
        WebSysDescription(SR.Control_OnDataBind)
        ] 
        public event EventHandler DataBinding {
            add { 
                Events.AddHandler(EventDataBinding, value); 
            }
            remove { 
                Events.RemoveHandler(EventDataBinding, value);
            }
        }
 

        ///  
        ///    Occurs when the control is initialized, the first step in the page lifecycle. Controls should 
        ///       perform any initialization steps that are required to create and set up an
        ///       instantiation. 
        /// 
        [
        WebSysDescription(SR.Control_OnInit)
        ] 
        public event EventHandler Init {
            add { 
                Events.AddHandler(EventInit, value); 
            }
            remove { 
                Events.RemoveHandler(EventInit, value);
            }
        }
 

        ///  
        /// Occurs when the control is loaded to the  object. Notifies the control to perform any steps that 
        ///    need to occur on each page request.
        ///  
        [
        WebSysDescription(SR.Control_OnLoad)
        ]
        public event EventHandler Load { 
            add {
                Events.AddHandler(EventLoad, value); 
            } 
            remove {
                Events.RemoveHandler(EventLoad, value); 
            }
        }

 
        /// 
        ///    Occurs when the control is about to render. Controls 
        ///       should perform any pre-rendering steps necessary before saving view state and 
        ///       rendering content to the  object.
        ///  
        [
        WebSysDescription(SR.Control_OnPreRender)
        ]
        public event EventHandler PreRender { 
            add {
                Events.AddHandler(EventPreRender, value); 
            } 
            remove {
                Events.RemoveHandler(EventPreRender, value); 
            }
        }

 
        /// 
        ///    Occurs when the control is unloaded from memory. Controls should perform any 
        ///       final cleanup before this instance of it is  
        /// 
        [ 
        WebSysDescription(SR.Control_OnUnload)
        ]
        public event EventHandler Unload {
            add { 
                Events.AddHandler(EventUnload, value);
            } 
            remove { 
                Events.RemoveHandler(EventUnload, value);
            } 
        }

        /// 
        /// Apply stylesheet skin on the control. 
        /// 
        [ 
        EditorBrowsable(EditorBrowsableState.Advanced), 
        ]
        public virtual void ApplyStyleSheetSkin(Page page) { 
            // Nothing to do if the control is not in a Page.
            if (page == null) {
                return;
            } 

            // Only apply stylesheet if not already applied. 
            if (flags[styleSheetApplied]) { 
                throw new InvalidOperationException(SR.GetString(SR.StyleSheetAreadyAppliedOnControl));
            } 

            if (page.ApplyControlStyleSheet(this)) {
                flags.Set(styleSheetApplied);
            } 
        }
 
        ///  
        /// Apply theme on the control.
        ///  
        private void ApplySkin(Page page) {
            if (page == null) {
                throw new ArgumentNullException("page");
            } 

            if (flags[themeApplied]) { 
                return; 
            }
 
            if (ThemeableAttribute.IsTypeThemeable(this.GetType())) {
                page.ApplyControlSkin(this);
                flags.Set(themeApplied);
            } 
        }
 
 
        /// 
        /// Raises the  event. This 
        ///    notifies a control to perform any data binding logic that is associated with it.
        /// 
        protected virtual void OnDataBinding(EventArgs e) {
            if(HasEvents()) { 
                EventHandler handler = _occasionalFields.Events[EventDataBinding] as EventHandler;
                if(handler != null) { 
                    handler(this, e); 
                }
            } 
        }


        ///  
        ///     Causes data binding to occur on the invoked control and all of its child
        ///       controls. 
        ///  
        public virtual void DataBind() {
            DataBind(true); 
        }

        /// 
        ///     Causes the invoked controls' context to be pushed on the stack, 
        ///       then conditionally call OnDataBinging on the invoked control, and databind all of its child
        ///       controls.  A control would call this with false if it overrides DataBind without calling 
        ///       Control.DataBind, but still wants to be an IDataItemContainer.  FormView and DetailsView 
        ///       are good examples of this.
        ///  
        protected virtual void DataBind(bool raiseOnDataBinding) {
            bool inDataBind = false;

            if (IsBindingContainer) { 
                bool foundDataItem;
 
                object dataItem = DataBinder.GetDataItem(this, out foundDataItem); 

                if (foundDataItem && (Page != null)) { 
                    Page.PushDataBindingContext(dataItem);
                    inDataBind = true;
                }
            } 
            try {
                if (raiseOnDataBinding) { 
                    // Do our own databinding 
                    OnDataBinding(EventArgs.Empty);
                } 

                // Do all of our children's databinding
                DataBindChildren();
            } 
            finally {
                if (inDataBind) { 
                    Page.PopDataBindingContext(); 
                }
            } 
        }


        ///  
        ///  Causes data binding to occur on all of the child controls.
        ///  
        protected virtual void DataBindChildren() { 
            if (HasControls()) {
                EnsureOccasionalFields(); 
                string oldmsg = _occasionalFields.Controls.SetCollectionReadOnly(SR.Parent_collections_readonly);

                try {
                    try { 
                        int controlCount = _occasionalFields.Controls.Count;
                        for (int i=0; i < controlCount; i++) 
                            _occasionalFields.Controls[i].DataBind(); 
                    }
                    finally { 
                        _occasionalFields.Controls.SetCollectionReadOnly(oldmsg);
                    }
                }
                catch { 
                    throw;
                } 
            } 
        }
 
        internal void PreventAutoID() {
            // controls that are also naming containers must always get an id
            if (flags[isNamingContainer] == false) {
                flags.Set(idNotRequired); 
            }
        } 
 

        ///  
        ///    Notifies the control that an element, XML or HTML, was parsed, and adds it to
        ///       the control.
        /// 
        protected virtual void AddParsedSubObject(object obj) { 
            Control control = obj as Control;
            if (control != null) { 
                Controls.Add(control); 
            }
        } 

        private void UpdateNamingContainer(Control namingContainer) {
            // Remove the cached uniqueID if the control already had a namingcontainer
            // and the namingcontainer is changed. 
            if (_namingContainer != null && _namingContainer != namingContainer) {
                ClearCachedUniqueIDRecursive(); 
            } 

            _namingContainer = namingContainer; 
        }

        private void ClearCachedUniqueIDRecursive() {
            _cachedUniqueID = null; 

            if (_occasionalFields != null) { 
                _occasionalFields.UniqueIDPrefix = null; 

                if (_occasionalFields.Controls != null) { 
                    int controlCount = _occasionalFields.Controls.Count;
                    for (int i = 0; i < controlCount; i++) {
                        _occasionalFields.Controls[i].ClearCachedUniqueIDRecursive();
                    } 
                }
            } 
        } 

        protected void EnsureID() { 
            if (_namingContainer != null) {
                if (_id == null) {
                    GenerateAutomaticID();
                } 
                flags.Set(mustRenderID);
            } 
        } 

        private void GenerateAutomaticID() { 
            Debug.Assert(_namingContainer != null);
            Debug.Assert(_id == null);

            // Remember that a generated ID is used for this control. 
            flags.Set(useGeneratedID);
 
            // Calculate the automatic ID. For performance and memory reasons 
            // we look up a static table entry if possible
            _namingContainer.EnsureOccasionalFields(); 
            int idNo = _namingContainer._occasionalFields.NamedControlsID++;
            if (EnableLegacyRendering) {
                // VSWhidbey 517118
                _id = automaticLegacyIDPrefix + idNo.ToString(NumberFormatInfo.InvariantInfo); 
            }
            else { 
                if (idNo < automaticIDCount) { 
                    _id = automaticIDs[idNo];
                } 
                else {
                    _id = automaticIDPrefix + idNo.ToString(NumberFormatInfo.InvariantInfo);
                }
            } 

            _namingContainer.DirtyNameTable(); 
        } 

        internal virtual string GetUniqueIDPrefix() { 
            EnsureOccasionalFields();

            if (_occasionalFields.UniqueIDPrefix == null) {
                string uniqueID = UniqueID; 
                if (!String.IsNullOrEmpty(uniqueID)) {
                    _occasionalFields.UniqueIDPrefix = uniqueID + IdSeparator; 
                } 
                else {
                    _occasionalFields.UniqueIDPrefix = String.Empty; 
                }
            }

            return _occasionalFields.UniqueIDPrefix; 
        }
 
        ///  
        /// Raises the  event. This notifies the control to perform
        ///    any steps necessary for its creation on a page request. 
        /// 
        protected internal virtual void OnInit(EventArgs e) {
            if(HasEvents()) {
                EventHandler handler = _occasionalFields.Events[EventInit] as EventHandler; 
                if(handler != null) {
                    handler(this, e); 
                } 
            }
        } 

        internal virtual void InitRecursive(Control namingContainer) {
            ResolveAdapter();
            if (_occasionalFields != null && _occasionalFields.Controls != null) { 
                if (flags[isNamingContainer]) {
                    namingContainer = this; 
                } 
                string oldmsg = _occasionalFields.Controls.SetCollectionReadOnly(SR.Parent_collections_readonly);
 
                int controlCount = _occasionalFields.Controls.Count;
                for (int i = 0; i < controlCount; i++) {
                    Control control = _occasionalFields.Controls[i];
 
                    // Propagate the page and namingContainer
                    control.UpdateNamingContainer(namingContainer); 
 
                    if ((control._id == null) && (namingContainer != null) && !control.flags[idNotRequired]) {
                        control.GenerateAutomaticID(); 
                    }
                    control._page = Page;

                    control.InitRecursive(namingContainer); 
                }
                _occasionalFields.Controls.SetCollectionReadOnly(oldmsg); 
 
            }
 
            // Only make the actual call if it hasn't already happened (ASURT 111303)
            if (_controlState < ControlState.Initialized) {
                _controlState = ControlState.ChildrenInitialized; // framework also initialized
 
                if ((Page != null) && !DesignMode) {
                    if (Page.ContainsTheme && EnableTheming) { 
                        ApplySkin(Page); 
                    }
                } 

                if (_adapter != null) {
                    _adapter.OnInit(EventArgs.Empty);
                } 
                else {
                    OnInit(EventArgs.Empty); 
                } 

                _controlState = ControlState.Initialized; 
            }

            // track all subsequent state changes
            TrackViewState(); 

#if DEBUG 
            ControlInvariant(); 
#endif
        } 

#if DEBUG

        ///  
        ///    This should be used to assert internal state about the control
        ///  
        internal void ControlInvariant() { 

            // If the control is initialized, the naming container and page should have been pushed in 
            if (_controlState >= ControlState.Initialized) {
                if (DesignMode) {
                    // Top-level UserControls do not have a page or a naming container in the designer
                    // hence the special casing. 

                    Debug.Assert((_namingContainer != null) || (this is Page) || (this is UserControl)); 
 
                    //
 


                }
                else { 
                    if (!(this is Page)) {
                        Debug.Assert(_namingContainer != null); 
                    } 
                    Debug.Assert(Page != null);
                } 
            }
            // If naming container is set and the name table exists, the ID should exist in it.

            if(_namingContainer != null && 
               _namingContainer._occasionalFields != null &&
               _namingContainer._occasionalFields.NamedControls != null && 
               _id != null) { 
                Debug.Assert(_namingContainer._occasionalFields.NamedControls.Contains(_id));
            } 
        }

        // Collect some statistic about the number of controls with occasional and
        // rare fields. 
        internal void GetRareFieldStatistics(ref int totalControls,
            ref int withOccasionalFields, ref int withRareFields) { 
            totalControls++; 
            if (_occasionalFields != null) {
                withOccasionalFields++; 
                if (_occasionalFields.RareFields != null)
                    withRareFields++;

                // No children: we're done 
                if (_occasionalFields.Controls == null)
                    return; 
 
                int controlCount = _occasionalFields.Controls.Count;
                for (int i = 0; i < controlCount; i++) { 
                    Control control = _occasionalFields.Controls[i];

                    control.GetRareFieldStatistics(ref totalControls, ref withOccasionalFields,
                        ref withRareFields); 
                }
            } 
        } 
#endif
 
        protected void ClearChildState() {
            ClearChildControlState();
            ClearChildViewState();
        } 

        protected void ClearChildControlState() { 
            //VSWhidbey 242621 to be consistent with ClearChildViewState, ignore calls before and during Init 
            if (ControlState < ControlState.Initialized) {
                return; 
            }
            flags.Set(disableChildControlState);
            if (Page != null) {
                Page.RegisterRequiresClearChildControlState(this); 
            }
        } 
 

        ///  
        ///    Deletes the view state information for all of the current control's child
        ///       controls.
        /// 
        protected void ClearChildViewState() { 
            if(_occasionalFields != null) {
                _occasionalFields.ControlsViewState = null; 
            } 
        }
 

        /// 
        ///    Indicates whether the current control's children have any saved view state
        ///       information. This property is read-only. 
        /// 
        protected bool HasChildViewState { 
            get { 
                return ((_occasionalFields != null) &&
                        (_occasionalFields.ControlsViewState != null) && 
                        (_occasionalFields.ControlsViewState.Count > 0));
            }
        }
 

        ///  
        /// Sets initial focus on the control 
        /// 
        public virtual void Focus() { 
            Page.SetFocus(this);
        }

        internal void LoadControlStateInternal(object savedStateObj) { 
            // Do not load the control state if it has been applied.
            if (flags[controlStateApplied]) { 
                return; 
            }
 
            flags.Set(controlStateApplied);

            Pair savedState = (Pair)savedStateObj;
            if (savedState == null) { 
                return;
            } 
            Page page = Page; 
            if (page != null && !page.ShouldLoadControlState(this)) {
                return; 
            }
            // VSWhidbey160650: Only call LoadControlState with non null savedState
            if (savedState.First != null) {
                LoadControlState(savedState.First); 
            }
            // VSWhidbey356804: Only call LoadAdapterControlState with non null savedState 
            if (_adapter == null || savedState.Second == null) { 
                return;
            } 
            _adapter.LoadAdapterControlState(savedState.Second);
        }

 
        /// 
        /// Load the control state, which is the essential state information needed even if view state is disabled. 
        ///  
        protected internal virtual void LoadControlState(object savedState) {
        } 


        /// 
        ///    Restores the view state information from a previous page 
        ///       request that was saved by the Control.SavedState method.
        ///  
        protected virtual void LoadViewState(object savedState) { 
            if (savedState != null) {
                ViewState.LoadViewState(savedState); 

                // Load values cached out of view state
                object visible = ViewState["Visible"];
                if (visible != null) { 
                    if(!(bool)visible) {
                        flags.Set(invisible); 
                    } 
                    else {
                        flags.Clear(invisible); 
                    }
                    flags.Set(visibleDirty);
                }
            } 
        }
 
        internal void LoadViewStateRecursive(object savedState) { 
            // nothing to do if we have no state
            if (savedState == null || flags[disableViewState]) 
                return;

            if (Page != null && Page.IsPostBack) {
                object controlState = null; 
                object adapterState = null;
                ArrayList childState = null; 
 
                Pair allSavedState = savedState as Pair;
                if (allSavedState != null) { 
                    controlState = allSavedState.First;
                    childState = (ArrayList)allSavedState.Second;
                }
                else { 
                    Debug.Assert(savedState is Triplet);
                    Triplet t = (Triplet)savedState; 
 
                    controlState = t.First;
                    adapterState = t.Second; 
                    childState = (ArrayList)t.Third;
                }

                try { 
                    if ((adapterState != null) && (_adapter != null)) {
                        _adapter.LoadAdapterViewState(adapterState); 
                    } 

                    if (controlState != null) { 
                        LoadViewState(controlState);
                    }

                    if (childState != null) { 
                        if (LoadViewStateByID) {
                            LoadChildViewStateByID(childState); 
                        } 
                        else {
                            LoadChildViewStateByIndex(childState); 
                        }
                    }
                }
                catch (InvalidCastException) { 
                    // catch all viewstate loading problems with casts.  They are most likely changed control trees.
                    throw new HttpException(SR.GetString(SR.Controls_Cant_Change_Between_Posts)); 
                } 
                catch (IndexOutOfRangeException) {
                    // catch all viewstate loading problems with indeces.  They are most likely changed control trees. 
                    throw new HttpException(SR.GetString(SR.Controls_Cant_Change_Between_Posts));
                }
            }
 
            _controlState = ControlState.ViewStateLoaded;
        } 
 
        internal void LoadChildViewStateByID(ArrayList childState) {
            int childStateCount = childState.Count; 
            for (int i = 0; i < childStateCount; i += 2) {
                // first element is index or ID of control with state and the
                // next element is state of the control
                string controlId = (string)childState[i]; 
                object state = childState[i + 1];
 
                Control childControl = FindControl(controlId); 
                if (childControl != null) {
                    childControl.LoadViewStateRecursive(state); 
                }
                else {
                    // couldn't find a control for this state blob, save it for later
                    EnsureOccasionalFields(); 
                    if (_occasionalFields.ControlsViewState == null) {
                        _occasionalFields.ControlsViewState = new Hashtable(); 
                    } 
                    _occasionalFields.ControlsViewState[controlId] = state;
                } 
            }
        }

        internal void LoadChildViewStateByIndex(ArrayList childState) { 
            ControlCollection ctrlColl = Controls;
            int ctrlCount = ctrlColl.Count; 
 
            int childStateCount = childState.Count;
            for (int i = 0; i < childStateCount; i += 2) { 
                // first element is index of control with state and the
                // next element is state of the control
                int controlIndex = (int)childState[i];
                object state = childState[i + 1]; 

                if (controlIndex < ctrlCount) { 
                    // we have a control for this state blob 
                    ctrlColl[controlIndex].LoadViewStateRecursive(state);
                } 
                else {
                    // couldn't find a control for this state blob, save it for later
                    EnsureOccasionalFields();
                    if (_occasionalFields.ControlsViewState == null) { 
                        _occasionalFields.ControlsViewState = new Hashtable();
                    } 
                    _occasionalFields.ControlsViewState[controlIndex] = state; 
                }
            } 
        }

        ///
        /// Figure out if a path is physical or virtual.  This is useful because a number of our controls 
        /// accept either type of path for the same attribute.
        /// 
        internal void ResolvePhysicalOrVirtualPath(string path, out VirtualPath virtualPath, out string physicalPath) { 
            if (System.Web.Util.UrlPath.IsAbsolutePhysicalPath(path)) {
                physicalPath = path; 
                virtualPath = null;
            }
            else {
                physicalPath = null; 

                // It could be relative, so resolve it 
                virtualPath = TemplateControlVirtualDirectory.Combine(VirtualPath.Create(path)); 
            }
        } 


        /// 
        ///  
        ///   This function takes a virtual path, that is a relative or root relative URL without a protocol.
        ///   It returns the mapped physcial file name relative to the template source. It throws an exception if 
        ///   there is insufficient security access to read or investigate the mapped result. This should be used 
        ///   by controls that can read files and live in fully trusted DLLs such as System.Web.dll to prevent
        ///   security issues. The exception thrown does not give away information about the mapping.  For absolute 
        ///   physical paths, this function checks permission
        /// 
        /// 
        protected internal string MapPathSecure(string virtualPath) { 
            if (String.IsNullOrEmpty(virtualPath)) {
                throw new ArgumentNullException("virtualPath", SR.GetString(SR.VirtualPath_Length_Zero)); 
            } 

            string physicalPath; 
            VirtualPath virtualPathObject;
            ResolvePhysicalOrVirtualPath(virtualPath, out virtualPathObject, out physicalPath);
            if (physicalPath == null) {
                physicalPath = virtualPathObject.MapPathInternal(TemplateControlVirtualDirectory, 
                    true /*allowCrossAppMapping*/);
            } 
 
            // Security check
            HttpRuntime.CheckFilePermission(physicalPath); 

            return physicalPath;
        }
 

        ///  
        ///  
        ///   This function takes a virtual path, that is a relative or root relative URL without a protocol.
        ///   It can also take a physical path, either local (c:\) or UNC. 
        ///   It returns a stream used to read to contents of the file. It throws an exception if
        ///   there is insufficient security access to read or investigate the mapped result. This should be used
        ///   by controls that can read files and live in fully trusted DLLs such as System.Web.dll to prevent
        ///   security issues. The exception thrown does not give away information about the mapping.  For absolute 
        ///   physical paths, this function checks permission
        ///  
        ///  
        protected internal Stream OpenFile(string path) {
 
            string physicalPath = null;
            VirtualFile vfile = null;

            // Need to Trim it since MapPath no longer allows trailing space (VSWhidbey 441210) 
            path = path.Trim();
 
            if (UrlPath.IsAbsolutePhysicalPath(path)) { 
                // Absolute physical path
                physicalPath = path; 
            }
            else {
                vfile = HostingEnvironment.VirtualPathProvider.GetFile(path);
                MapPathBasedVirtualFile mapPathVFile = vfile as MapPathBasedVirtualFile; 
                if (mapPathVFile != null) {
                    physicalPath = mapPathVFile.PhysicalPath; 
                } 
            }
 
            // If we got a physical path, make sure the user has access to it
            if (physicalPath != null) {
                HttpRuntime.CheckFilePermission(physicalPath);
            } 

            if (vfile != null) { 
                return vfile.Open(); 
            }
            else { 
                return new FileStream(physicalPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            }
        }
 
        ///
        /// Open a stream from either a virtual or physical path, and if possible get a CacheDependency 
        /// for the resulting Stream. 
        ///
        internal Stream OpenFileAndGetDependency(VirtualPath virtualPath, string physicalPath, out CacheDependency dependency) { 

            // Only one of the paths should be non-null
            Debug.Assert((virtualPath == null) != (physicalPath == null));
 
            // If we got a virtual path, and we're using the default VPP, call MapPath
            if (physicalPath == null && HostingEnvironment.UsingMapPathBasedVirtualPathProvider) { 
                physicalPath = virtualPath.MapPathInternal(TemplateControlVirtualDirectory, 
                    true /*allowCrossAppMapping*/);
            } 

            Stream stream;
            if (physicalPath != null) {
                // Security check 
                HttpRuntime.CheckFilePermission(physicalPath);
 
                // Work directly with the physical file, bypassing the VPP 
                stream = new FileStream(physicalPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                dependency = new CacheDependency(0, physicalPath); 
            }
            else {
                // It's non file system based, so go though the VirtualPathProvider
                stream = virtualPath.OpenFile(); 
                dependency = VirtualPathProvider.GetCacheDependency(virtualPath);
            } 
 
            return stream;
        } 


        /// 
        /// Raises the  
        /// event. This notifies the control that it should perform any work that needs to
        /// occur for each page request. 
        ///  
        protected internal virtual void OnLoad(EventArgs e) {
            if(HasEvents()) { 
                EventHandler handler = _occasionalFields.Events[EventLoad] as EventHandler;
                if(handler != null) {
                    handler(this, e);
                } 
            }
        } 
 
        internal virtual void LoadRecursive() {
 
            // Only make the actual call if it hasn't already happened (ASURT 111303)
            if (_controlState < ControlState.Loaded) {
                if(_adapter != null) {
                    _adapter.OnLoad(EventArgs.Empty); 
                }
                else { 
                    OnLoad(EventArgs.Empty); 
                }
            } 

            // Call Load on all our children
            if (_occasionalFields != null && _occasionalFields.Controls != null) {
                string oldmsg = _occasionalFields.Controls.SetCollectionReadOnly(SR.Parent_collections_readonly); 

                int controlCount = _occasionalFields.Controls.Count; 
                for (int i = 0; i < controlCount; i++) { 
                    _occasionalFields.Controls[i].LoadRecursive();
                } 

                _occasionalFields.Controls.SetCollectionReadOnly(oldmsg);
            }
 
            if (_controlState < ControlState.Loaded)
                _controlState = ControlState.Loaded; 
        } 

 
        /// 
        /// Raises the  event. This method uses event arguments
        ///    to pass the event data to the control.
        ///  
        protected internal virtual void OnPreRender(EventArgs e) {
            if(HasEvents()) { 
                EventHandler handler = _occasionalFields.Events[EventPreRender] as EventHandler; 
                if (handler != null) {
                    handler(this, e); 
                }
            }
        }
 
        internal virtual void PreRenderRecursiveInternal() {
            // Call Visible property and cache value in !flags[invisible] to allow Visible to be overridden. 
            // This avoids unnecessary virtual property calls in SaveViewState and Render. 
            bool visible = Visible;
            if(!visible) { 
                flags.Set(invisible);
            }
            else {
                flags.Clear(invisible); 
                EnsureChildControls();
 
                if(_adapter != null) { 
                    _adapter.OnPreRender(EventArgs.Empty);
                } 
                else {
                    OnPreRender(EventArgs.Empty);
                }
 
                if (_occasionalFields != null && _occasionalFields.Controls != null) {
                    string oldmsg = _occasionalFields.Controls.SetCollectionReadOnly(SR.Parent_collections_readonly); 
 
                    int controlCount = _occasionalFields.Controls.Count;
                    for (int i=0; i < controlCount; i++) { 
                        _occasionalFields.Controls[i].PreRenderRecursiveInternal();
                    }
                    _occasionalFields.Controls.SetCollectionReadOnly(oldmsg);
                } 
            }
            _controlState = ControlState.PreRendered; 
        } 

        internal int EstimateStateSize(object state) { 
            if(state == null) {
                return 0;
            }
            return Util.SerializeWithAssert(new ObjectStateFormatter(), state).Length; 
        }
 
        /* 
         * Walk the tree and fill in profile information
         */ 

        /// 
        /// 
        /// Gathers information about the control and delivers it to the  
        /// property to be displayed when tracing is enabled for the page.
        ///  
        protected void BuildProfileTree(string parentId, bool calcViewState) { 
            // estimate the viewstate size.
            calcViewState = calcViewState && (!flags[disableViewState]); 
            int viewstatesize;
            if (calcViewState)
                viewstatesize = EstimateStateSize(SaveViewState());
            else 
                viewstatesize = 0;
 
            int controlstatesize = 0; 
            if(Page != null && Page._registeredControlsRequiringControlState != null && Page._registeredControlsRequiringControlState.Contains(this)) {
                controlstatesize = EstimateStateSize(SaveControlStateInternal()); 
            }

            // give it all to the profiler
            Page.Trace.AddNewControl(UniqueID, parentId, this.GetType().FullName, viewstatesize, controlstatesize); 

            if (_occasionalFields != null && _occasionalFields.Controls != null) { 
                int controlCount = _occasionalFields.Controls.Count; 
                for (int i = 0; i < controlCount; i++) {
                    _occasionalFields.Controls[i].BuildProfileTree(UniqueID, calcViewState); 
                }
            }
        }
 

        internal object SaveControlStateInternal() { 
            object controlState = SaveControlState(); 
            object adapterControlState = null;
            if (_adapter != null) { 
                adapterControlState = _adapter.SaveAdapterControlState();
            }
            if (controlState != null || adapterControlState != null) {
                return new Pair(controlState, adapterControlState); 
            }
            return null; 
        } 

 
        /// 
        /// Save the control state, which is the essential state information needed even if view state is disabled.
        /// 
        protected internal virtual object SaveControlState() { 
            return null;
        } 
 
        // Save modified state the control would like restored on the postback.
        // Return null if there is no state to save. 

        /// 
        ///    
        ///       Saves view state for use with a later  
        ///       request.
        ///     
        ///  
        protected virtual object SaveViewState() {
            // Save values cached out of view state 
            if (flags[visibleDirty]) {
                ViewState["Visible"] = !flags[invisible];
            }
            if (_viewState != null) 
                return _viewState.SaveViewState();
 
            return null; 
        }
 
        // Answer any state this control or its descendants want to save on freeze.
        // The format for saving is Triplet(myState, ArrayList childIDs, ArrayList childStates),
        // where myState or childStates and childIDs may be null.
        internal object SaveViewStateRecursive() { 
            if (flags[disableViewState])
                return null; 
 
            object adapterState = null;
            if (_adapter != null) { 
                adapterState = _adapter.SaveAdapterViewState();
            }

            object controlSavedState = SaveViewState(); 

            ArrayList childStates = null; 
            if (HasControls()) { 
                ControlCollection occasionalFieldControls = _occasionalFields.Controls;
                int occasionalFieldControlCount = occasionalFieldControls.Count; 

                bool useId = LoadViewStateByID;
                for (int i = 0; i < occasionalFieldControlCount; i++) {
                    Control child = occasionalFieldControls[i]; 
                    object childState = child.SaveViewStateRecursive();
                    if (childState != null) { 
                        if (childStates == null) { 
                            childStates = new ArrayList(occasionalFieldControlCount);
                        } 

                        if (useId) {
                            child.EnsureID();
                            childStates.Add(child.ID); 
                        }
                        else { 
                            childStates.Add(i); 
                        }
                        childStates.Add(childState); 
                    }
                }
            }
 
            if (_adapter != null) {
                if ((controlSavedState != null) || (adapterState != null) || (childStates != null)) { 
                    return new Triplet(controlSavedState, adapterState, childStates); 
                }
            } 
            else {
                if ((controlSavedState != null) || (childStates != null)) {
                    return new Pair(controlSavedState, childStates);
                } 
            }
 
            return null; 
        }
 

        /// 
        /// Outputs control content to a provided HTMLTextWriter
        /// output stream. 
        /// 
        protected internal virtual void Render(HtmlTextWriter writer) { 
            RenderChildren(writer); 
        }
 
        internal void RenderChildrenInternal(HtmlTextWriter writer, ICollection children) {
            // If we have a delegate, use it for the rendering.
            // This happens when there is some ASP code.  See also Whidbey 33012.
            if(RareFields != null && RareFields.RenderMethod != null ) { 
                writer.BeginRender();
                RareFields.RenderMethod(writer, this); 
                writer.EndRender(); 
                return;
            } 
            if (children != null) {
                foreach (Control child in children) {
                    child.RenderControl(writer);
                } 
            }
        } 
 
        protected internal virtual void RenderChildren(HtmlTextWriter writer) {
            ICollection children = (_occasionalFields == null) ? null : _occasionalFields.Controls; 
            RenderChildrenInternal(writer, children);
        }

        ///  
        ///    [To be supplied.]
        ///  
        public virtual void RenderControl(HtmlTextWriter writer) { 
            //use the Adapter property to ensure it is resolved
            RenderControl(writer, Adapter); 
        }

        /// 
        ///    Used for MobilePage implementation. 
        /// 
        protected void RenderControl(HtmlTextWriter writer, ControlAdapter adapter) { 
            if (!flags[invisible] && !flags[notVisibleOnPage]) { 
                HttpContext context = (Page == null) ? null : Page._context;
                if (context  != null && context.TraceIsEnabled) { 
                    int presize = context.Response.GetBufferedLength();
                    RenderControlInternal(writer, adapter);
                    int postsize = context.Response.GetBufferedLength();
                    context.Trace.AddControlSize(UniqueID, postsize - presize); 
                }
                else { 
                    RenderControlInternal(writer, adapter); 
                }
            } 
        }

        private void RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) {
            if (adapter != null) { 
                //
                adapter.BeginRender(writer); 
                adapter.Render(writer); 
                adapter.EndRender(writer);
            } 
            else {
                Render(writer);
            }
        } 

 
        ///  
        ///    [To be supplied.]
        ///  
        protected internal virtual void OnUnload(EventArgs e) {
            if(HasEvents()) {
                EventHandler handler = _occasionalFields.Events[EventUnload] as EventHandler;
                if (handler != null) { 
                    handler(this, e);
                } 
            } 
        }
 

        /// 
        ///    Enables a control to perform final cleanup.
        ///  
        public virtual void Dispose() {
            IContainer container = null; 
 
            if (Site != null) {
                container = (IContainer)Site.GetService(typeof(IContainer)); 
                if (container != null) {
                    container.Remove(this);
                    EventHandler disp = Events[EventDisposed] as EventHandler;
                    if (disp != null) 
                        disp(this, EventArgs.Empty);
                } 
            } 

            if (_occasionalFields != null) { 
                _occasionalFields.Dispose();
                //do not null out for backwards compat, VSWhidbey 475940
                //_occasionalFields = null;
            } 
        }
 
 
        internal virtual void UnloadRecursive(bool dispose) {
            Page page = Page; 
            if (page != null && page.RequiresControlState(this)) {
                page.UnregisterRequiresControlState(this);
                RareFieldsEnsured.RequiredControlState = true;
            } 

            // Remove the generated ID so it will be assigned a different ID next time. 
            if (flags[useGeneratedID]) { 
                _id = null;
                flags.Clear(useGeneratedID); 
            }

            if (_occasionalFields != null && _occasionalFields.Controls != null) {
                string oldmsg = _occasionalFields.Controls.SetCollectionReadOnly(SR.Parent_collections_readonly); 

                int controlCount = _occasionalFields.Controls.Count; 
                for (int i = 0; i < controlCount; i++) 
                    _occasionalFields.Controls[i].UnloadRecursive(dispose);
 
                _occasionalFields.Controls.SetCollectionReadOnly(oldmsg);
            }

            if(_adapter != null) { 
                _adapter.OnUnload(EventArgs.Empty);
            } 
            else { 
                OnUnload(EventArgs.Empty);
            } 

            //
            if (dispose)
                Dispose(); 

            // VSWhidbey 244999: Everett behavior doesn't reset the control state. 
            // But for control which requires its OnInit method to be called again 
            // to properly initialize when the control is removed and added back
            // to Page's control tree, the control can override IsReloadable 
            // to true so the control state is reset.  e.g. Validator, see bug
            if (IsReloadable) {
                _controlState = ControlState.Constructed;
            } 
        }
 
 
        /// 
        ///    Assigns an sources of the event and its information up the page control 
        ///       hierarchy until they reach the top of the control tree. 
        /// 
        protected void RaiseBubbleEvent(object source, EventArgs args) {
            Control currentTarget = Parent; 
            while (currentTarget != null) {
                if (currentTarget.OnBubbleEvent(source, args)) { 
                    return; 
                }
                currentTarget = currentTarget.Parent; 
            }
        }

 
        /// 
        ///    Determines whether the event for the control should be passed up the page's 
        ///       control hierarchy. 
        /// 
        protected virtual bool OnBubbleEvent(object source, EventArgs args) { 
            return false;
        }

 
        // Members related to being a container
 
 
        /// 
        ///     Gets a ControlCollection object that represents the child controls for a specified control in the 
        ///       UI hierarchy.
        /// 
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        WebSysDescription(SR.Control_Controls) 
        ] 
        public virtual ControlCollection Controls {
            get { 
                if (_occasionalFields == null || _occasionalFields.Controls == null) {
                    EnsureOccasionalFields();
                    _occasionalFields.Controls = CreateControlCollection();
                } 
                return _occasionalFields.Controls;
            } 
        } 

 
        /// 
        ///    Indicates a dictionary of state information that allows you to save and restore
        ///       the state of a control across multiple requests for the same page.
        ///  
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        WebSysDescription(SR.Control_State)
        ] 
        protected virtual StateBag ViewState {
            get {
                if (_viewState != null) {   // create a StateBag on demand; WebControl makes its case sensitive
                    return _viewState; 
                }
 
                _viewState = new StateBag(ViewStateIgnoresCase); 
                if (IsTrackingViewState)
                    _viewState.TrackViewState(); 
                return _viewState;
            }
        }
 
        // fast enough that we cam always use it.
 
        ///  
        /// Indicates whether the  object is case-insensitive.
        ///  
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        ] 
        protected virtual bool ViewStateIgnoresCase {
            get { 
                return false; 
            }
        } 


        /// 
        ///  
        protected internal virtual void AddedControl(Control control, int index) {
            if (control.OwnerControl != null) { 
                throw new InvalidOperationException(SR.GetString(SR.Substitution_NotAllowed)); 
            }
 
            if (control._parent != null) {
                control._parent.Controls.Remove(control);
            }
 
            control._parent = this;
            control._page = Page; 
            control.flags.Clear(designModeChecked); 

            // We only add to naming container if it is available. Otherwise, it will be pushed through 
            // during InitRecursive
            Control namingContainer = flags[isNamingContainer] ? this : _namingContainer;
            if (namingContainer != null) {
                control.UpdateNamingContainer(namingContainer); 
                if (control._id == null && !control.flags[idNotRequired]) {
                    // this will also dirty the name table in the naming container 
                    control.GenerateAutomaticID(); 
                }
                else if (control._id != null || (control._occasionalFields != null && control._occasionalFields.Controls != null)) { 
                    // If the control has and ID, or has children (which *may* themselves
                    // have ID's), we need to dirty the name table (ASURT 100557)
                    namingContainer.DirtyNameTable();
                } 
            }
 
            /* 
             * The following is for times when AddChild is called after CreateChildControls. This
             * allows users to add children at any time in the creation process without having 
             * to understand the underlying machinery.
             * Note that if page is null, it means we haven't been attached to a container ourselves.
             * If this is true, when we are, our children will be recursively set up.
             */ 
            if (_controlState >= ControlState.ChildrenInitialized) {
 
                Debug.Assert(namingContainer != null); 
                control.InitRecursive(namingContainer);
 
                // VSWhidbey 396372: We need to reregister the control state if the control is reparented because the control
                // is unregistered during unload, but its already been inited once, so it will not get its Init called again
                // which is where most controls call RegisterRequiresControlState
                if (control._controlState >= ControlState.Initialized && 
                    control.RareFields != null &&
                    control.RareFields.RequiredControlState) { 
                    Page.RegisterRequiresControlState(control); 
                }
 
                if (_controlState >= ControlState.ViewStateLoaded) {
                    object viewState = null;
                    if(_occasionalFields != null && _occasionalFields.ControlsViewState != null) {
                        viewState = _occasionalFields.ControlsViewState[index]; 
                        // This solution takes the conservative approach that once viewstate has been
                        // applied to a child control, it is thrown away.  This eliminates inadvertently 
                        // setting viewstate on the wrong control, which can occur in scenarios where 
                        // the child control collection is being manipulated via code.  Probably need
                        // to provide a feature where programmer can control whether to reapply viewstate 
                        // or not.
                        if (LoadViewStateByID) {
                            control.EnsureID();
                            viewState = _occasionalFields.ControlsViewState[control.ID]; 
                            _occasionalFields.ControlsViewState.Remove(control.ID);
                        } 
                        else { 
                            viewState = _occasionalFields.ControlsViewState[index];
                            _occasionalFields.ControlsViewState.Remove(index); 
                        }
                    }

                    control.LoadViewStateRecursive(viewState); 

                    if (_controlState >= ControlState.Loaded) { 
                        control.LoadRecursive(); 

                        if (_controlState >= ControlState.PreRendered) 
                            control.PreRenderRecursiveInternal();
                    }
                }
            } 
        }
 
 
        /// 
        ///    [To be supplied.] 
        /// 
        protected virtual ControlCollection CreateControlCollection() {
            return new ControlCollection(this);
        } 

 
        ///  
        ///    
        ///       Notifies any controls that use composition-based implementation to create any 
        ///       child controls they contain in preperation for postback or rendering.
        ///    
        /// 
        protected internal virtual void CreateChildControls() { 
        }
 
 

        ///  
        ///    Indicates whether the control's child controls have been created.
        /// 
        protected bool ChildControlsCreated {
            get { 
                return flags[controlsCreated];
            } 
            set { 
                if (!value && flags[controlsCreated]) {
                    Controls.Clear(); 
                }
                if(value) {
                    flags.Set(controlsCreated);
                } 
                else {
                    flags.Clear(controlsCreated); 
                } 
            }
        } 


        /// 
        ///    Make a URL absolute using the AppRelativeTemplateSourceDirectory.  The returned URL is for 
        ///        client use, and will contain the session cookie if appropriate.
        ///  
        public string ResolveUrl(string relativeUrl) { 
            if (relativeUrl == null) {
                throw new ArgumentNullException("relativeUrl"); 
            }

            // check if its empty or already absolute
            if ((relativeUrl.Length == 0) || (UrlPath.IsRelativeUrl(relativeUrl) == false)) { 
                return relativeUrl;
            } 
 
            string baseUrl = AppRelativeTemplateSourceDirectory;
            if (String.IsNullOrEmpty(baseUrl)) { 
                return relativeUrl;
            }

            // first make it absolute 
            string url = UrlPath.Combine(baseUrl, relativeUrl);
 
            // include the session cookie if available (ASURT 47658) 
            // As a side effect, this will change an app relative path (~/...) to app absolute
            return Context.Response.ApplyAppPathModifier(url); 
        }


        ///  
        ///     Return a URL that is suitable for use on the client.
        ///     If the URL is absolute, return it unchanged.  If it is relative, turn it into a 
        ///     relative URL that is correct from the point of view of the current request path 
        ///     (which is what the browser uses for resolution).
        ///  
        public string ResolveClientUrl(string relativeUrl) {
            if (DesignMode && Page != null && Page.Site != null) {
                IUrlResolutionService resolutionService = (IUrlResolutionService)Page.Site.GetService(typeof(IUrlResolutionService));
                if (resolutionService != null) { 
                    return resolutionService.ResolveClientUrl(relativeUrl);
                } 
            } 

            if (relativeUrl == null) { 
                throw new ArgumentNullException("relativeUrl");
            }

            // Get the app absolute TemplateSourceDirectory (not app relative) 
            string tplSourceDir = VirtualPath.GetVirtualPathString(TemplateControlVirtualDirectory);
            if (String.IsNullOrEmpty(tplSourceDir)) 
                return relativeUrl; 

            string baseRequestDir = Context.Request.ClientBaseDir.VirtualPathString; 

            // If the path is app relative (~/...), we cannot take shortcuts, since
            // the ~ is meaningless on the client, and must be resolved
            if (!UrlPath.IsAppRelativePath(relativeUrl)) { 

                // If the template source directory is the same as the directory of the request, 
                // we don't need to do any adjustments to the input path 
                if (StringUtil.EqualsIgnoreCase(baseRequestDir, tplSourceDir))
                    return relativeUrl; 

                // check if it's empty or absolute
                if ((relativeUrl.Length == 0) || (!UrlPath.IsRelativeUrl(relativeUrl))) {
                    return relativeUrl; 
                }
            } 
 
            // first make it absolute
            string url = UrlPath.Combine(tplSourceDir, relativeUrl); 

            // Make sure the path ends with a slash before calling MakeRelative
            baseRequestDir = UrlPath.AppendSlashToPathIfNeeded(baseRequestDir);
 
            // Now, make it relative to the current request, so that the client will
            // compute the correct path 
            return HttpUtility.UrlPathEncode(UrlPath.MakeRelative(baseRequestDir, url)); 
        }
 
        internal void DirtyNameTable() {
            Debug.Assert(this is INamingContainer);
            if(_occasionalFields != null) {
                _occasionalFields.NamedControls = null; 
            }
        } 
 
        private void EnsureNamedControlsTable() {
            Debug.Assert(this is INamingContainer); 
            Debug.Assert(HasControls());
            Debug.Assert(_occasionalFields != null);
            Debug.Assert(_occasionalFields.NamedControls == null);
 
            _occasionalFields.NamedControls = new HybridDictionary(/*initialSize*/ _occasionalFields.NamedControlsID, /*caseInsensitive*/ true);
            FillNamedControlsTable(this, _occasionalFields.Controls); 
        } 

        private void FillNamedControlsTable(Control namingContainer, ControlCollection controls) { 
            Debug.Assert(namingContainer._occasionalFields != null);
            Debug.Assert(namingContainer._occasionalFields.NamedControls != null);
            Debug.Assert((controls != null) && (controls.Count != 0));
 
            int controlCount = controls.Count;
            for (int i=0; i < controlCount; i++) { 
                Control control = controls[i]; 
                if (control._id != null) {
#if DEBUG 
                    if (control._namingContainer != null) {
                        Debug.Assert(control._namingContainer == namingContainer);
                    }
#endif // DEBUG 
                    try {
                        namingContainer.EnsureOccasionalFields(); 
                        namingContainer._occasionalFields.NamedControls.Add(control._id, control); 
                    }
                    catch { 
                        throw new HttpException(SR.GetString(SR.Duplicate_id_used, control._id, "FindControl"));
                    }
                }
                if (control.HasControls() && (control.flags[isNamingContainer] == false)) { 
                    FillNamedControlsTable(namingContainer, control.Controls);
                } 
            } 
        }
 

        /// 
        ///    Searches the current naming container for a control with
        ///       the specified  . 
        /// 
        public virtual Control FindControl(String id) { 
            return FindControl(id, 0); 
        }
 

        /// 
        /// 
        ///    Searches the current naming container for a control with the specified 
        ///     and an offset to aid in the
        ///       search. 
        ///  
        protected virtual Control FindControl(String id, int pathOffset) {
            string childID; 

            EnsureChildControls();

            // If we're not the naming container, let it do the job 
            if (!(flags[isNamingContainer])) {
                Control namingContainer = NamingContainer; 
                if (namingContainer != null) { 
                    return namingContainer.FindControl(id, pathOffset);
                } 
                return null;
            }

            // No registered control, demand create the named controls table 
            //call HasControls ensuress _occasionalFields != null
            if(HasControls() && _occasionalFields.NamedControls == null) { 
                EnsureNamedControlsTable(); 
            }
            if (_occasionalFields == null || _occasionalFields.NamedControls == null) { 
                return null;
            }

            // Need to support ':' for V1 backward compatibility. 
            char[] findControlSeparators = { ID_SEPARATOR, LEGACY_ID_SEPARATOR };
 
            // Is it a hierarchical name? 
            int newPathOffset = id.IndexOfAny(findControlSeparators, pathOffset);
 
            // If not, handle it here
            if (newPathOffset == -1) {
                childID = id.Substring(pathOffset);
                return _occasionalFields.NamedControls[childID] as Control; 
            }
 
            // Get the name of the child, and try to locate it 
            childID = id.Substring(pathOffset, newPathOffset - pathOffset);
            Control child =  _occasionalFields.NamedControls[childID] as Control; 

            // Child doesn't exist: fail
            if (child == null)
                return null; 

            return child.FindControl(id, newPathOffset + 1); 
        } 

        /* 
         * Called when the controls of a naming container are cleared.
         */
        internal void ClearNamingContainer() {
            Debug.Assert(this is INamingContainer); 

            EnsureOccasionalFields(); 
            _occasionalFields.NamedControlsID = 0; 
            DirtyNameTable();
        } 


        /// 
        ///  
        /// 
        [SecurityPermission(SecurityAction.Demand, Unrestricted = true)] 
        protected virtual IDictionary GetDesignModeState() { 
            ControlRareFields rareFields = RareFieldsEnsured;
            if (rareFields.DesignModeState == null) { 
                rareFields.DesignModeState = new HybridDictionary();
            }
            return rareFields.DesignModeState;
        } 

 
        ///  
        ///    Determines if the current control contains any child
        ///       controls. Since this method simply deteremines if any child controls exist at 
        ///       all, it can enhance performance by avoiding a call to the Count property,
        ///       inherited from the  class, on the 
        ///       property.
        ///  
        public virtual bool HasControls() {
            return _occasionalFields != null && _occasionalFields.Controls != null && _occasionalFields.Controls.Count > 0; 
        } 

        /* 
         * Check if a Control either has children or has a compiled render method.
         * This is to address issues like ASURT 94127
         */
        internal bool HasRenderingData() { 
            return HasControls() || HasRenderDelegate();
        } 
 
        /*
         * Check if a Control either has children or has a compiled render method. 
         * This is to address issues like ASURT 94127
         */
        internal bool HasRenderDelegate() {
            if(RareFields != null) { 
                return (RareFields.RenderMethod != null );
            } 
            return false; 
        }
 
        /*
         * Returns true if the container contains just a static string, i.e.,
         * when the Controls collection has a single LiteralControl.
         */ 

        ///  
        ///    Determines if the container holds literal content only. 
        ///       When this method returns 
        ///       , the container collection only holds a single literal control. The 
        ///       content is then passed to the requesting browser as HTML.
        /// 
        protected bool IsLiteralContent() {
            return (_occasionalFields != null && _occasionalFields.Controls != null) && (_occasionalFields.Controls.Count == 1) && 
            ((_occasionalFields.Controls[0] is LiteralControl));
        } 
 

        ///  
        ///    Determines if view state changes to the
        ///    
        ///    are being saved. 
        ///  
        protected bool IsTrackingViewState {
            get { 
                return flags[marked]; 
            }
        } 


        /// 
        ///    Turns on tracking of view state changes to the control 
        ///       so that they can be stored in the 
        ///       object. 
        ///  
        protected virtual void TrackViewState() {
            if (_viewState != null) 
                _viewState.TrackViewState();

            flags.Set(marked);
        } 

 
        ///  
        ///    Checks that the control contains child controls; if it does not, it creates
        ///       them. This includes any literal content being parsed as a  
        ///       object. 
        /// 
        protected virtual void EnsureChildControls() {
            if (!ChildControlsCreated && !flags[creatingControls]) { 
                flags.Set(creatingControls);
                try { 
                    ResolveAdapter(); 
                    if(_adapter != null) {
                        _adapter.CreateChildControls(); 
                    }
                    else {
                        CreateChildControls();
                    } 

                    // Only set ChildControlsCreated = true if CreateChildControls() did not throw 
                    // an exception (VSWhidbey 465798). 
                    ChildControlsCreated = true;
                } 
                finally {
                    flags.Clear(creatingControls);
                }
            } 
        }
 
        ///  
        /// Used internally to store a ControlBuilder reference for the control.
        /// The builder will be used at design-time to help persist all the filtered properties 
        /// of the control.
        /// 
        internal void SetControlBuilder(ControlBuilder controlBuilder) {
            RareFieldsEnsured.ControlBuilder = controlBuilder; 
        }
 
 
        /// 
        ///  
        protected internal virtual void RemovedControl(Control control) {
            if (control.OwnerControl != null) {
                throw new InvalidOperationException(SR.GetString(SR.Substitution_NotAllowed));
            } 

            if ((_namingContainer != null) && (control._id != null)) { 
                _namingContainer.DirtyNameTable(); 
            }
 
            // Controls may need to do their own cleanup.
            control.UnloadRecursive(false);

            control._parent = null; 
            control._page = null;
            control._namingContainer = null; 
 
            // Don't reset _templateSourceVirtualDirectory on TemplateControl's, because
            // the path is their own, not their parent. i.e. it doesn't change no matter 
            // where in the tree they end up.
            if (!(control is TemplateControl))
                control._templateSourceVirtualDirectory = null;
 
            control._templateControl = null;
 
            control.flags.Clear(mustRenderID); 
            control.ClearCachedUniqueIDRecursive();
        } 

        internal void SetDesignMode() {
            flags.Set(designMode);
            flags.Set(designModeChecked); 
        }
 
 
        /// 
        ///  
        /// 
        protected virtual void SetDesignModeState(IDictionary data) {
        }
 
        // Set the delegate to the render method
 
        ///  
        /// 
        ///    Assigns any event handler delegates for the control to match the parameters 
        ///       defined in the . 
        /// 
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        public void SetRenderMethodDelegate(RenderMethod renderMethod) { 
            RareFieldsEnsured.RenderMethod = renderMethod;
 
            // Make the collection readonly if there are code blocks (ASURT 78810) 
            Controls.SetCollectionReadOnly(SR.Collection_readonly_Codeblocks);
        } 


        /// 
        ///  
        ///    Returns whether the control contains any data binding logic. This method is
        ///       only accessed by RAD designers. 
        ///  
        bool IDataBindingsAccessor.HasDataBindings {
            get { 
                return ((RareFields != null) && (RareFields.DataBindings != null) && (RareFields.DataBindings.Count != 0));
            }
        }
 

        ///  
        ///  
        /// Indicates a collection of all data bindings on the control. This property is
        /// read-only. 
        /// 
        DataBindingCollection IDataBindingsAccessor.DataBindings {
            get {
                ControlRareFields rareFields = RareFieldsEnsured; 
                if (rareFields.DataBindings == null) {
                    rareFields.DataBindings = new DataBindingCollection(); 
                } 
                return rareFields.DataBindings;
            } 
        }


        // IParserAccessor interface 
        // A sub-object tag was parsed by the parser; add it to this control.
 
        ///  
        /// 
        /// Notifies the control that an element, XML or HTML, was parsed, and adds it to 
        /// the control.
        /// 
        void IParserAccessor.AddParsedSubObject(object obj) {
            AddParsedSubObject(obj); 
        }
 
        internal string SpacerImageUrl { 
            get {
                EnsureOccasionalFields(); 
                if (_occasionalFields.SpacerImageUrl == null) {
                    _occasionalFields.SpacerImageUrl = Page.ClientScript.GetWebResourceUrl(typeof(WebControl), "Spacer.gif");
                }
                return _occasionalFields.SpacerImageUrl; 
            }
        } 
 
        private Control OwnerControl {
            get { 
                if (RareFields == null) {
                    return null;
                }
 
                return RareFields.OwnerControl;
            } 
            set { 
                RareFieldsEnsured.OwnerControl = value;
            } 
        }

        internal IPostBackDataHandler PostBackDataHandler {
            get { 
                IPostBackDataHandler pbdh = _adapter as IPostBackDataHandler;
                if(pbdh != null) 
                    return pbdh; 
                pbdh = this as IPostBackDataHandler;
                return pbdh; 
            }
        }

        internal IPostBackEventHandler PostBackEventHandler { 
            get {
                IPostBackEventHandler pbeh = _adapter as IPostBackEventHandler; 
                if(pbeh != null) 
                    return pbeh;
                pbeh = this as IPostBackEventHandler; 
                return pbeh;
            }
        }
 
#if ORCAS
        internal bool NotVisibleOnPage { 
            get { 
                return flags[notVisibleOnPage];
            } 

            set {
                if(value) {
                    flags.Set(notVisibleOnPage); 
                }
                else { 
                    flags.Clear(notVisibleOnPage); 
                }
            } 
        }

        internal int VirtualStartPage {
            get { 
                return RareFields != null ? RareFields.VirtualStartPage : -1;
            } 
            set { 
                RareFieldsEnsured.VirtualStartPage = value;
            } 
        }

        internal int VirtualEndPage {
            get { 
                return RareFields != null ? RareFields.VirtualEndPage : -1;
            } 
 
            set {
                RareFieldsEnsured.VirtualEndPage = value; 
            }
        }
#endif
 
        #region IControlDesignerAccessor implementation
 
        ///  
        IDictionary IControlDesignerAccessor.UserData {
            get { 
                ControlRareFields rareFields = RareFieldsEnsured;
                if (rareFields.ControlDesignerAccessorUserData == null) {
                    rareFields.ControlDesignerAccessorUserData = new HybridDictionary();
                } 
                return rareFields.ControlDesignerAccessorUserData;
            } 
        } 

        ///  
        /// 
        /// 
        IDictionary IControlDesignerAccessor.GetDesignModeState() {
            return GetDesignModeState(); 
        }
 
 
        /// 
        ///  
        /// 
        void IControlDesignerAccessor.SetDesignModeState(IDictionary data) {
            SetDesignModeState(data);
        } 

        void IControlDesignerAccessor.SetOwnerControl(Control owner) { 
            if (owner == this) { 
                throw new ArgumentException(SR.GetString(SR.Control_CannotOwnSelf), "owner");
            } 
            OwnerControl = owner;
            _parent = owner.Parent;
            _page = owner.Page;
        } 
        #endregion
 
        #region IControlBuilderAccessor implementation 

        ///  
        /// 
        /// A reference to the ControlBuilder that was used to construct this control (if there was one)
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        ControlBuilder IControlBuilderAccessor.ControlBuilder {
            get { 
                return RareFields != null ? RareFields.ControlBuilder : null;
            }
        }
        #endregion IControlBuilderAccessor implementation 

        #region IExpressionsAccessor 
 

        ///  
        bool IExpressionsAccessor.HasExpressions {
            get {
                if (RareFields == null) {
                    return false; 
                }
                ExpressionBindingCollection expressions = RareFields.ExpressionBindings; 
                return ((expressions != null) && (expressions.Count > 0)); 
            }
        } 


        /// 
        ExpressionBindingCollection IExpressionsAccessor.Expressions { 
            get {
                ExpressionBindingCollection expressions = RareFieldsEnsured.ExpressionBindings; 
                if (expressions == null) { 
                    expressions = new ExpressionBindingCollection();
                    RareFields.ExpressionBindings = expressions; 
                }
                return expressions;
            }
        } 
        #endregion
 
        private sealed class ControlRareFields : IDisposable { 

            internal ControlRareFields() { 
            }
            public ISite Site;
            public RenderMethod RenderMethod;
            // Reference to the templateControl that hosts this control. 
#if ORCAS
            public int VirtualStartPage = -1; 
            public int VirtualEndPage = -1; 
            public ContentPager ContentPager;
#endif 
            // Reference to the ControlBuilder used to build this control
            public ControlBuilder ControlBuilder;
            public DataBindingCollection DataBindings;
            public Control OwnerControl; 
            public ExpressionBindingCollection ExpressionBindings;
            public bool RequiredControlState = false; 
 
            // These fields are only used in the designer so we
            // keep them here to prevent memory bloat at runtime 
            public IDictionary ControlDesignerAccessorUserData;
            public IDictionary DesignModeState;

            public void Dispose() { 
                //do not null out for backwards compat, VSWhidbey 475940
                //Site = null; 
                //RenderMethod = null; 
                //DataBindings = null;
                //OwnerControl = null; 
                //ExpressionBindings = null;
                ControlBuilder = null;
                if (OwnerControl != null)
                { 
                    OwnerControl.Dispose();
                } 
                ControlDesignerAccessorUserData = null; 
                DesignModeState = null;
 
#if ORCAS
                ContentPager = null;
#endif
            } 
        }
 
        private sealed class OccasionalFields : IDisposable { 
            internal OccasionalFields() {
            } 

            public string SkinId;
            // Events
            public EventHandlerList Events; 
            public IDictionary ControlsViewState;
            public ControlCollection Controls; 
            public int NamedControlsID; 
            // Only used if we are a naming container.  It contains all the controls
            // in the namespace. 
            public IDictionary NamedControls;
            public ControlRareFields RareFields;
            public String UniqueIDPrefix;
 
            public string SpacerImageUrl;
 
            public void Dispose() { 
                if (Events != null) {
                    Events.Dispose(); 
                    Events = null;
                }
                if (RareFields != null) {
                    RareFields.Dispose(); 
                }
 
                ControlsViewState = null; 
                //do not null out for backwards compat, VSWhidbey 475940
                //Controls = null; 
                //NamedControls = null;
                //UniqueIDPrefix = null;
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK