System.Drawing: added email to icon and test file headers
[mono.git] / mcs / class / System.Web / System.Web.UI / Control.cs
1 //
2 // System.Web.UI.Control.cs
3 //
4 // Authors:
5 //   Bob Smith <bob@thestuff.net>
6 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 //   Sanjay Gupta (gsanjay@novell.com)
9 //   Marek Habersack <mhabersack@novell.com>
10 //
11 // (C) Bob Smith
12 // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com)
13 // (C) 2004-2010 Novell, Inc. (http://www.novell.com)
14 //
15
16 //
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
24 // 
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
27 // 
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 //
36
37 using System.Collections;
38 using System.Collections.Generic;
39 using System.ComponentModel;
40 using System.ComponentModel.Design;
41 using System.ComponentModel.Design.Serialization;
42 using System.Globalization;
43 using System.IO;
44 using System.Security.Permissions;
45 using System.Text;
46 using System.Web;
47 using System.Web.Configuration;
48 using System.Web.UI.Adapters;
49 using System.Web.UI.WebControls;
50 using System.Web.Util;
51
52 #if NET_4_0
53 using System.Web.Routing;
54 #endif
55
56 namespace System.Web.UI
57 {
58         // CAS
59         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
60         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
61         // attributes
62         [DefaultProperty ("ID"), DesignerCategory ("Code"), ToolboxItemFilter ("System.Web.UI", ToolboxItemFilterType.Require)]
63         [ToolboxItem ("System.Web.UI.Design.WebControlToolboxItem, " + Consts.AssemblySystem_Design)]
64         [Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
65         [DesignerSerializer ("Microsoft.VisualStudio.Web.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VisualStudio_Web,
66                                 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
67         [Bindable (true)]
68         [Themeable (false)]
69         public partial class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor, IUrlResolutionService, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
70         {
71                 internal static readonly object DataBindingEvent = new object ();
72                 internal static readonly object DisposedEvent = new object ();
73                 internal static readonly object InitEvent = new object ();
74                 internal static readonly object LoadEvent = new object ();
75                 internal static readonly object PreRenderEvent = new object ();
76                 internal static readonly object UnloadEvent = new object ();
77                 internal static string [] defaultNameArray;
78                 /* */
79                 int event_mask;
80                 const int databinding_mask = 1;
81                 const int disposed_mask = 1 << 1;
82                 const int init_mask = 1 << 2;
83                 const int load_mask = 1 << 3;
84                 const int prerender_mask = 1 << 4;
85                 const int unload_mask = 1 << 5;
86                 /* */
87
88                 [ThreadStatic]
89                 static Dictionary <Type, bool> loadViewStateByIDCache;
90                 bool? loadViewStateByID;
91                 string uniqueID;
92                 string clientID;
93                 string _userId;
94                 ControlCollection _controls;
95                 Control _namingContainer;
96                 Page _page;
97                 Control _parent;
98                 ISite _site;
99                 StateBag _viewState;
100                 EventHandlerList _events;
101                 RenderMethod _renderMethodDelegate;
102                 Hashtable _controlsCache;
103                 int defaultNumberID;
104
105                 DataBindingCollection dataBindings;
106                 Hashtable pendingVS; // may hold unused viewstate data from child controls
107                 TemplateControl _templateControl;
108                 bool _isChildControlStateCleared;
109                 string _templateSourceDirectory;
110 #if NET_4_0
111                 ViewStateMode viewStateMode;
112                 ClientIDMode? clientIDMode;
113                 ClientIDMode? effectiveClientIDMode;
114                 Version renderingCompatibility;
115                 bool? renderingCompatibilityOld;
116 #endif
117                 /*************/
118                 int stateMask;
119                 const int ENABLE_VIEWSTATE = 1;
120                 const int VISIBLE = 1 << 1;
121                 const int AUTOID = 1 << 2;
122                 const int CREATING_CONTROLS = 1 << 3;
123                 const int BINDING_CONTAINER = 1 << 4;
124                 const int AUTO_EVENT_WIREUP = 1 << 5;
125                 const int IS_NAMING_CONTAINER = 1 << 6;
126                 const int VISIBLE_CHANGED = 1 << 7;
127                 const int TRACK_VIEWSTATE = 1 << 8;
128                 const int CHILD_CONTROLS_CREATED = 1 << 9;
129                 const int ID_SET = 1 << 10;
130                 const int INITED = 1 << 11;
131                 const int INITING = 1 << 12;
132                 const int VIEWSTATE_LOADED = 1 << 13;
133                 const int LOADED = 1 << 14;
134                 const int PRERENDERED = 1 << 15;
135                 const int ENABLE_THEMING = 1 << 16;
136                 const int AUTOID_SET = 1 << 17;
137                 const int REMOVED = 1 << 18;
138                 /*************/
139
140                 static Control ()
141                 {
142                         defaultNameArray = new string [100];
143                         for (int i = 0; i < 100; i++)
144                                 defaultNameArray [i] = String.Concat ("ctl", i.ToString ("D2"));
145                 }
146
147                 public Control ()
148                 {
149                         stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
150                         if (this is INamingContainer)
151                                 stateMask |= IS_NAMING_CONTAINER;
152 #if NET_4_0
153                         viewStateMode = ViewStateMode.Inherit;
154 #endif
155                 }
156                 
157                 ControlAdapter adapter;
158                 bool did_adapter_lookup;
159                 protected internal ControlAdapter Adapter {
160                         get {
161                                 if (!did_adapter_lookup) {
162                                         adapter = ResolveAdapter ();
163                                         if (adapter != null)
164                                                 adapter.control = this;
165                                         did_adapter_lookup = true;
166                                 }
167                                 return adapter;
168                         }
169                 }
170
171                 string _appRelativeTemplateSourceDirectory = null;
172
173                 [EditorBrowsable (EditorBrowsableState.Advanced)]
174                 [Browsable (false)]
175                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
176                 public string AppRelativeTemplateSourceDirectory {
177                         get {
178                                 if (_appRelativeTemplateSourceDirectory != null)
179                                         return _appRelativeTemplateSourceDirectory;
180
181                                 string tempSrcDir = null;
182                                 TemplateControl templateControl = TemplateControl;
183                                 if (templateControl != null) {
184                                         string templateVirtualPath = templateControl.AppRelativeVirtualPath;
185                                         if (!String.IsNullOrEmpty (templateVirtualPath))
186                                                 tempSrcDir = VirtualPathUtility.GetDirectory (templateVirtualPath, false);
187                                 }
188                                 
189                                 _appRelativeTemplateSourceDirectory = (tempSrcDir != null) ? tempSrcDir : VirtualPathUtility.ToAppRelative (TemplateSourceDirectory);
190                                 return _appRelativeTemplateSourceDirectory;
191                         }
192                         [EditorBrowsable (EditorBrowsableState.Never)]
193                         set {
194                                 _appRelativeTemplateSourceDirectory = value;
195                                 _templateSourceDirectory = null;
196                         }
197                 }
198
199                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
200                 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
201 #if NET_4_0
202                 [Bindable (true)]
203 #endif
204                 public Control BindingContainer {
205                         get {
206                                 Control container = NamingContainer;
207                                 if (container != null && container is INonBindingContainer || (stateMask & BINDING_CONTAINER) == 0)
208                                         container = container.BindingContainer;
209
210                                 return container;
211                         }
212                 }
213
214                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
215                 [Browsable (false)]
216                 [WebSysDescription ("An Identification of the control that is rendered.")]
217                 public virtual string ClientID {
218                         get {
219                                 if (clientID != null)
220                                         return clientID;
221 #if NET_4_0
222                                 clientID = GetClientID ();
223 #else
224                                 clientID = UniqueID2ClientID (UniqueID);
225 #endif                          
226                                 stateMask |= ID_SET;
227                                 return clientID;
228                         }
229                 }
230 #if NET_4_0
231                 [Bindable (false)]
232                 [Browsable (false)]
233                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
234                 public virtual Version RenderingCompatibility {
235                         get {
236                                 if (renderingCompatibility == null) {
237                                         var ps = WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
238                                         renderingCompatibility = ps != null ? ps.ControlRenderingCompatibilityVersion : new Version (4, 0);
239                                 }
240
241                                 return renderingCompatibility;
242                         }
243                         
244                         set {
245                                 renderingCompatibility = value;
246                                 renderingCompatibilityOld = null;
247                         }
248                 }
249
250                 internal bool RenderingCompatibilityLessThan40 {
251                         get {
252                                 if (!renderingCompatibilityOld.HasValue)
253                                         renderingCompatibilityOld = RenderingCompatibility < new Version (4, 0);
254
255                                 return renderingCompatibilityOld.Value;
256                         }
257                 }
258                 
259                 [Bindable (false)]
260                 [Browsable (false)]
261                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
262                 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
263                 public Control DataItemContainer {
264                         get {
265                                 Control container = NamingContainer;
266                                 if (container == null)
267                                         return null;
268
269                                 if (container is IDataItemContainer)
270                                         return container;
271
272                                 return container.DataItemContainer;
273                         }
274                 }
275
276                 [Bindable (false)]
277                 [Browsable (false)]
278                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
279                 [EditorBrowsableAttribute (EditorBrowsableState.Never)]
280                 public Control DataKeysContainer {
281                         get {
282                                 Control container = NamingContainer;
283                                 if (container == null)
284                                         return null;
285
286                                 if (container is IDataKeysControl)
287                                         return container;
288
289                                 return container.DataKeysContainer;
290                         }
291                 }
292
293                 [Themeable (false)]
294                 [DefaultValue (ClientIDMode.Inherit)]
295                 public virtual ClientIDMode ClientIDMode {
296                         get {
297                                 if (!clientIDMode.HasValue)
298                                         return ClientIDMode.Inherit;
299
300                                 return clientIDMode.Value;
301                         }
302                         
303                         set {
304                                 if (!clientIDMode.HasValue || clientIDMode.Value != value) {
305                                         ClearCachedClientID ();
306                                         ClearEffectiveClientIDMode ();
307                                         clientIDMode = value;
308                                 }
309                         }
310                 }
311
312                 internal ClientIDMode EffectiveClientIDMode {
313                         get {
314                                 if (effectiveClientIDMode.HasValue)
315                                         return effectiveClientIDMode.Value;
316                                 
317                                 ClientIDMode ret = ClientIDMode;
318                                 if (ret != ClientIDMode.Inherit) {
319                                         effectiveClientIDMode = ret;
320                                         return ret;
321                                 }
322                                 
323                                 // not sure about this, but it seems logical as INamingContainer is
324                                 // the top of the hierarchy and it should "reset" the mode.
325                                 Control container = NamingContainer;
326                                 if (container != null) {
327                                         effectiveClientIDMode = container.EffectiveClientIDMode;
328                                         return effectiveClientIDMode.Value;
329                                 }
330
331                                 var ps = WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
332                                 effectiveClientIDMode = ps.ClientIDMode;
333
334                                 return effectiveClientIDMode.Value;
335                         }       
336                 }
337
338                 protected void ClearCachedClientID ()
339                 {
340                         clientID = null;
341                         if (!HasControls ())
342                                 return;
343
344                         for (int i = 0; i < _controls.Count; i++)
345                                 _controls [i].ClearCachedClientID ();
346                 }
347
348                 protected void ClearEffectiveClientIDMode ()
349                 {
350                         effectiveClientIDMode = null;
351                         if (!HasControls ())
352                                 return;
353
354                         for (int i = 0; i < _controls.Count; i++)
355                                 _controls [i].ClearEffectiveClientIDMode ();
356                 }
357
358                 string GetClientID ()
359                 {
360                         switch (EffectiveClientIDMode) {
361                                 case ClientIDMode.AutoID:
362                                         return UniqueID2ClientID (UniqueID);
363
364                                 case ClientIDMode.Predictable:
365                                         EnsureID ();
366                                         return GeneratePredictableClientID ();
367
368                                 case ClientIDMode.Static:
369                                         EnsureID ();
370                                         return ID;
371
372                                 default:
373                                         throw new InvalidOperationException ("Unsupported ClientIDMode value.");
374                         }
375                 }
376                 
377                 string GeneratePredictableClientID ()
378                 {
379                         string myID = ID;
380                         bool haveMyID = !String.IsNullOrEmpty (myID);
381                         char separator = ClientIDSeparator;
382
383                         var sb = new StringBuilder ();
384                         Control container = NamingContainer;
385                         if (this is INamingContainer && !haveMyID) {
386                                 if (container != null)
387                                         EnsureIDInternal ();
388                                 myID = _userId;
389                         }
390                         
391                         if (container != null && container != Page) {
392                                 string containerID = container.ID;
393                                 if (!String.IsNullOrEmpty (containerID)) {
394                                         sb.Append (container.GetClientID ());
395                                         sb.Append (separator);
396                                 } else {
397                                         sb.Append (container.GeneratePredictableClientID ());
398                                         if (sb.Length > 0)
399                                                 sb.Append (separator);
400                                 }
401                         }
402
403                         if (!haveMyID) {
404                                 if (this is INamingContainer || !AutoID)
405                                         sb.Append (myID);
406                                 else {
407                                         int length = sb.Length;
408                                         if (length > 0 && sb [length - 1] == separator)
409                                                 sb.Length = length - 1;
410                                 }
411                                 
412                                 return sb.ToString ();
413                         }
414                         
415                         sb.Append (myID);
416                         IDataItemContainer dataItemContainer = DataItemContainer as IDataItemContainer;
417                         if (dataItemContainer == null)
418                                 return sb.ToString ();
419                         
420                         IDataKeysControl dataKeysContainer = DataKeysContainer as IDataKeysControl;
421                         GetDataBoundControlFieldValue (sb, separator, dataItemContainer, dataKeysContainer);
422                         
423                         return sb.ToString ();
424                 }
425
426                 void GetDataBoundControlFieldValue (StringBuilder sb, char separator, IDataItemContainer dataItemContainer, IDataKeysControl dataKeysContainer)
427                 {
428                         if (dataItemContainer is IDataBoundItemControl)
429                                 return;
430                         
431                         int index = dataItemContainer.DisplayIndex;
432                         if (dataKeysContainer == null) {
433                                 if (index >= 0) {
434                                         sb.Append (separator);
435                                         sb.Append (index);
436                                 }
437                                 return;
438                         }
439                         
440                         string[] suffixes = dataKeysContainer.ClientIDRowSuffix;
441                         DataKeyArray keys = dataKeysContainer.ClientIDRowSuffixDataKeys;
442                         if (keys == null || suffixes == null || suffixes.Length == 0) {
443                                 sb.Append (separator);
444                                 sb.Append (index);
445                                 return;
446                         }
447
448                         object value;
449                         DataKey key = keys [index];
450                         foreach (string suffix in suffixes) {
451                                 sb.Append (separator);
452                                 value = key != null ? key [suffix] : null;
453                                 if (value == null)
454                                         continue;
455                                 sb.Append (value.ToString ());
456                         }
457                 }
458 #endif
459                 internal string UniqueID2ClientID (string uniqueId)
460                 {
461                         if (String.IsNullOrEmpty (uniqueId))
462                                 return null;
463                         
464                         return uniqueId.Replace (IdSeparator, ClientIDSeparator);
465                 }
466
467                 protected char ClientIDSeparator {
468                         get { return '_'; }
469                 }
470
471
472                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
473                 [Browsable (false)]
474                 [WebSysDescription ("The child controls of this control.")]
475                 public virtual ControlCollection Controls { //DIT
476                         get {
477                                 if (_controls == null)
478                                         _controls = CreateControlCollection ();
479                                 return _controls;
480                         }
481                 }
482
483                 [MonoTODO ("revisit once we have a real design strategy")]
484                 protected internal bool DesignMode {
485                         get { return false; }
486                 }
487
488                 [DefaultValue (true), WebCategory ("Behavior")]
489                 [WebSysDescription ("An Identification of the control that is rendered.")]
490                 [Themeable (false)]
491                 public virtual bool EnableViewState {
492                         get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
493                         set { SetMask (ENABLE_VIEWSTATE, value); }
494                 }
495
496                 [MergableProperty (false), ParenthesizePropertyName (true)]
497                 [WebSysDescription ("The name of the control that is rendered.")]
498                 [Filterable (false), Themeable (false)]
499                 public virtual string ID {
500                         get { return (((stateMask & ID_SET) != 0) ? _userId : null); }
501
502                         set {
503                                 if (value != null && value.Length == 0)
504                                         value = null;
505
506                                 stateMask |= ID_SET;
507                                 _userId = value;
508                                 NullifyUniqueID ();
509                         }
510                 }
511
512                 protected internal bool IsChildControlStateCleared {
513                         get { return _isChildControlStateCleared; }
514                 }
515
516                 protected bool LoadViewStateByID {
517                         get {
518                                 if (loadViewStateByID == null)
519                                         loadViewStateByID = IsLoadViewStateByID ();
520
521                                 return (bool)loadViewStateByID;
522                         }
523                 }
524
525                 protected internal bool IsViewStateEnabled {
526                         get {
527                                 for (Control control = this; control != null; control = control.Parent) {
528                                         if (!control.EnableViewState)
529                                                 return false;
530 #if NET_4_0
531                                         ViewStateMode vsm = control.ViewStateMode;
532                                         if (vsm != ViewStateMode.Inherit)
533                                                 return vsm == ViewStateMode.Enabled;
534 #endif
535                                 }
536                                 
537                                 return true;
538                         }
539                 }
540
541                 protected char IdSeparator {
542                         get { return '$'; }
543                 }
544
545                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
546                 [Browsable (false)]
547                 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
548 #if NET_4_0
549                 [Bindable (true)]
550 #endif
551                 public virtual Control NamingContainer {
552                         get {
553                                 if (_namingContainer == null && _parent != null) {
554                                         if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
555                                                 _namingContainer = _parent.NamingContainer;
556                                         else
557                                                 _namingContainer = _parent;
558                                 }
559
560                                 return _namingContainer;
561                         }
562                 }
563
564                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
565                 [Browsable (false)]
566                 [WebSysDescription ("The webpage that this control resides on.")]
567                 [Bindable (false)]
568                 public virtual Page Page { //DIT
569                         get {
570                                 if (_page == null){
571                                         if (NamingContainer != null)
572                                                 _page = NamingContainer.Page;
573                                         else if (Parent != null)
574                                                 _page = Parent.Page;
575                                 }
576                                 return _page;
577                         }
578                         
579                         set { _page = value; }
580                 }
581
582                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
583                 [Browsable (false)]
584                 [WebSysDescription ("The parent control of this control.")]
585 #if NET_4_0
586                 [Bindable (true)]
587 #endif
588                 public virtual Control Parent { //DIT
589                         get { return _parent; }
590                 }
591
592                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
593                 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
594                 [WebSysDescription ("The site this control is part of.")]
595                 public ISite Site { //DIT
596                         get { return _site; }
597                         set { _site = value; }
598                 }
599
600                 [Browsable (false)]
601                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
602 #if NET_4_0
603                 [Bindable (true)]
604 #endif
605                 public TemplateControl TemplateControl {
606                         get { return TemplateControlInternal; }
607
608                         [EditorBrowsable (EditorBrowsableState.Never)]
609                         set { _templateControl = value; }
610                 }
611
612                 internal virtual TemplateControl TemplateControlInternal {
613                         get {
614                                 if (_templateControl != null)
615                                         return _templateControl;
616                                 if (_parent != null)
617                                         return _parent.TemplateControl;
618                                 return null;
619                         }
620                 }
621
622 #if !TARGET_J2EE
623                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
624                 [Browsable (false)]
625                 [WebSysDescription ("A virtual directory containing the parent of the control.")]
626                 public virtual string TemplateSourceDirectory {
627                         get {
628                                 if (_templateSourceDirectory == null) {
629                                         TemplateControl tc = TemplateControl;
630
631                                         if (tc == null) {
632                                                 HttpContext ctx = Context;
633                                                 if (ctx != null)
634                                                         _templateSourceDirectory = VirtualPathUtility.GetDirectory (ctx.Request.CurrentExecutionFilePath);
635                                         } else if (tc != this)
636                                                 _templateSourceDirectory = tc.TemplateSourceDirectory;
637
638                                         if (_templateSourceDirectory == null && this is TemplateControl) {
639                                                 string path = ((TemplateControl) this).AppRelativeVirtualPath;
640
641                                                 if (path != null) {
642                                                         string ret = VirtualPathUtility.GetDirectory (VirtualPathUtility.ToAbsolute (path));
643                                                         int len = ret.Length;
644                                                         if (len <= 1)
645                                                                 return ret;
646                                                         if (ret [--len] == '/')
647                                                                 _templateSourceDirectory = ret.Substring (0, len);
648                                                 } else
649                                                         _templateSourceDirectory = String.Empty;
650                                         }
651                                         if (_templateSourceDirectory == null)
652                                                 _templateSourceDirectory = String.Empty;
653                                 }
654
655                                 return _templateSourceDirectory;
656                         }
657                 }
658 #endif
659
660                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
661                 [Browsable (false)]
662                 [WebSysDescription ("The unique ID of the control.")]
663                 public virtual string UniqueID {
664                         get {
665                                 if (uniqueID != null)
666                                         return uniqueID;
667
668                                 Control container = NamingContainer;
669                                 if (container == null)
670                                         return _userId;
671
672                                 EnsureIDInternal ();
673                                 string prefix = container.UniqueID;
674                                 if (container == Page || prefix == null) {
675                                         uniqueID = _userId;
676 #if TARGET_J2EE
677                                         if (getFacesContext () != null)
678                                                 uniqueID = getFacesContext ().getExternalContext ().encodeNamespace (uniqueID);
679 #endif
680                                         return uniqueID;
681                                 }
682
683                                 uniqueID = prefix + IdSeparator + _userId;
684                                 return uniqueID;
685                         }
686                 }
687
688                 void SetMask (int m, bool val) {
689                         if (val)
690                                 stateMask |= m;
691                         else
692                                 stateMask &= ~m;
693                 }
694
695                 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
696                 [WebSysDescription ("Visiblity state of the control.")]
697                 public virtual bool Visible {
698                         get {
699                                 if ((stateMask & VISIBLE) == 0)
700                                         return false;
701
702                                 if (_parent != null)
703                                         return _parent.Visible;
704
705                                 return true;
706                         }
707
708                         set {
709                                 if ((value && (stateMask & VISIBLE) == 0) ||
710                                         (!value && (stateMask & VISIBLE) != 0)) {
711                                         if (IsTrackingViewState)
712                                                 stateMask |= VISIBLE_CHANGED;
713                                 }
714
715                                 SetMask (VISIBLE, value);
716                         }
717                 }
718
719                 protected bool ChildControlsCreated {
720                         get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
721                         set {
722                                 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
723                                         ControlCollection cc = Controls;
724                                         if (cc != null)
725                                                 cc.Clear ();
726                                 }
727
728                                 SetMask (CHILD_CONTROLS_CREATED, value);
729                         }
730                 }
731
732                 [Browsable (false)]
733                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
734                 protected internal virtual HttpContext Context { //DIT
735                         get {
736                                 Page page = Page;
737                                 if (page != null)
738                                         return page.Context;
739                                 
740                                 return HttpContext.Current;
741                         }
742                 }
743
744                 protected EventHandlerList Events {
745                         get {
746                                 if (_events == null)
747                                         _events = new EventHandlerList ();
748                                 return _events;
749                         }
750                 }
751
752                 protected bool HasChildViewState {
753                         get { return (pendingVS != null && pendingVS.Count > 0); }
754                 }
755
756                 protected bool IsTrackingViewState {
757                         get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
758                 }
759
760                 [Browsable (false)]
761                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
762                 [WebSysDescription ("ViewState")]
763                 protected virtual StateBag ViewState {
764                         get {
765                                 if (_viewState == null)
766                                         _viewState = new StateBag (ViewStateIgnoresCase);
767
768                                 if (IsTrackingViewState)
769                                         _viewState.TrackViewState ();
770
771                                 return _viewState;
772                         }
773                 }
774
775                 [Browsable (false)]
776                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
777                 protected virtual bool ViewStateIgnoresCase {
778                         get { return false; }
779                 }
780
781                 internal bool AutoEventWireup {
782                         get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
783                         set { SetMask (AUTO_EVENT_WIREUP, value); }
784                 }
785                 
786                 internal void SetBindingContainer (bool isBC)
787                 {
788                         SetMask (BINDING_CONTAINER, isBC);
789                 }
790
791                 internal void ResetChildNames ()
792                 {
793                         ResetChildNames (-1);
794                 }
795
796                 internal void ResetChildNames (int value)
797                 {
798                         if (value < 0)
799                                 defaultNumberID = 0;
800                         else
801                                 defaultNumberID = value;
802                 }
803
804                 internal int GetDefaultNumberID ()
805                 {
806                         return defaultNumberID;
807                 }
808
809                 string GetDefaultName ()
810                 {
811                         string defaultName;
812                         if (defaultNumberID > 99)
813                                 defaultName = "ctl" + defaultNumberID++;
814                         else
815                                 defaultName = defaultNameArray [defaultNumberID++];
816                         return defaultName;
817                 }
818
819                 void NullifyUniqueID ()
820                 {
821                         uniqueID = null;
822 #if NET_4_0
823                         ClearCachedClientID ();
824 #else
825                         clientID = null;
826 #endif
827                         if (!HasControls ())
828                                 return;
829
830                         for (int i = 0; i < _controls.Count; i++)
831                                 _controls [i].NullifyUniqueID ();
832                 }
833
834                 bool IsLoadViewStateByID ()
835                 {
836                         if (loadViewStateByIDCache == null)
837                                 loadViewStateByIDCache = new Dictionary <Type, bool> ();
838
839                         bool ret;
840                         Type myType = GetType ();
841                         if (loadViewStateByIDCache.TryGetValue (myType, out ret))
842                                 return ret;
843
844                         System.ComponentModel.AttributeCollection attrs = TypeDescriptor.GetAttributes (myType);
845                         ret = false;
846                         
847                         if (attrs != null) {
848                                 foreach (Attribute attr in attrs) {
849                                         if (attr is ViewStateModeByIdAttribute) {
850                                                 ret = true;
851                                                 break;
852                                         }
853                                 }
854                         }
855                         
856                         loadViewStateByIDCache.Add (myType, ret);
857                         return ret;
858                 }
859                 
860                 protected internal virtual void AddedControl (Control control, int index)
861                 {
862                         ResetControlsCache ();
863
864                         /* Ensure the control don't have more than 1 parent */
865                         if (control._parent != null)
866                                 control._parent.Controls.Remove (control);
867
868                         control._parent = this;
869                         Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
870
871                         if ((stateMask & (INITING | INITED)) != 0) {
872                                 control.InitRecursive (nc);
873                                 control.SetMask (REMOVED, false);
874                         } else {
875                                 control.SetNamingContainer (nc);
876                                 control.SetMask (REMOVED, false);
877                                 return;
878                         }
879
880                         if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
881                                 if (pendingVS != null) {
882                                         object vs;
883                                         bool byId = LoadViewStateByID;
884                                         string id;
885                                         
886                                         if (byId) {
887                                                 control.EnsureID ();
888                                                 id = control.ID;
889                                                 vs = pendingVS [id];
890                                         } else {
891                                                 id = null;
892                                                 vs = pendingVS [index];
893                                         }
894                                         
895                                         if (vs != null) {
896                                                 if (byId)
897                                                         pendingVS.Remove (id);
898                                                 else
899                                                         pendingVS.Remove (index);
900                                                 
901                                                 if (pendingVS.Count == 0)
902                                                         pendingVS = null;
903
904                                                 control.LoadViewStateRecursive (vs);
905                                         }
906                                 }
907                         }
908
909                         if ((stateMask & LOADED) != 0)
910                                 control.LoadRecursive ();
911
912                         if ((stateMask & PRERENDERED) != 0)
913                                 control.PreRenderRecursiveInternal ();
914                 }
915                 
916                 void SetNamingContainer (Control nc)
917                 {
918                         if (nc != null) {
919                                 _namingContainer = nc;
920                                 if (AutoID)
921                                         EnsureIDInternal ();
922                         }
923                 }
924
925                 protected virtual void AddParsedSubObject (object obj) //DIT
926                 {
927                         Control c = obj as Control;
928                         if (c != null)
929                                 Controls.Add (c);
930                 }
931
932                 [EditorBrowsable (EditorBrowsableState.Advanced)]
933                 public virtual void ApplyStyleSheetSkin (Page page)
934                 {
935                         if (page == null)
936                                 return;
937
938                         if (!EnableTheming) /* this enough? */
939                                 return;
940
941                         /* apply the style sheet skin here */
942                         if (page.StyleSheetPageTheme != null) {
943                                 ControlSkin cs = page.StyleSheetPageTheme.GetControlSkin (GetType (), SkinID);
944                                 if (cs != null)
945                                         cs.ApplySkin (this);
946                         }
947                 }
948
949                 [MonoTODO]
950                 protected void BuildProfileTree (string parentId, bool calcViewState)
951                 {
952                 }
953
954                 protected void ClearChildControlState ()
955                 {
956                         _isChildControlStateCleared = true;
957                 }
958
959                 protected void ClearChildState ()
960                 {
961                         ClearChildViewState ();
962                         ClearChildControlState ();
963                 }
964
965                 protected void ClearChildViewState ()
966                 {
967                         pendingVS = null;
968                 }
969
970                 protected internal virtual void CreateChildControls () //DIT
971                 {
972                 }
973
974                 protected virtual ControlCollection CreateControlCollection () //DIT
975                 {
976                         return new ControlCollection (this);
977                 }
978
979                 protected virtual void EnsureChildControls ()
980                 {
981                         if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
982                                 stateMask |= CREATING_CONTROLS;
983                                 if (Adapter != null)
984                                         Adapter.CreateChildControls ();
985                                 else
986                                         CreateChildControls ();
987                                 ChildControlsCreated = true;
988                                 stateMask &= ~CREATING_CONTROLS;
989                         }
990                 }
991
992                 void EnsureIDInternal ()
993                 {
994                         if (_userId != null)
995                                 return;
996
997                         _userId = NamingContainer.GetDefaultName ();
998                         SetMask (AUTOID_SET, true);
999                 }
1000
1001                 protected void EnsureID ()
1002                 {
1003                         if (NamingContainer == null)
1004                                 return;
1005                         EnsureIDInternal ();
1006                         SetMask (ID_SET, true);
1007                 }
1008
1009                 protected bool HasEvents ()
1010                 {
1011                         return _events != null;
1012                 }
1013
1014                 void ResetControlsCache ()
1015                 {
1016                         _controlsCache = null;
1017
1018                         if ((this.stateMask & IS_NAMING_CONTAINER) == 0 && Parent != null)
1019                                 Parent.ResetControlsCache ();
1020                 }
1021
1022                 Hashtable InitControlsCache ()
1023                 {
1024                         if (_controlsCache != null)
1025                                 return _controlsCache;
1026
1027                         if ((this.stateMask & IS_NAMING_CONTAINER) != 0 || Parent == null)
1028                                 //LAMESPEC: MS' docs don't mention it, but FindControl is case insensitive.
1029                                 _controlsCache = new Hashtable (StringComparer.OrdinalIgnoreCase);
1030                         else
1031                                 _controlsCache = Parent.InitControlsCache ();
1032
1033                         return _controlsCache;
1034                 }
1035
1036                 void EnsureControlsCache ()
1037                 {
1038                         if (_controlsCache != null)
1039                                 return;
1040
1041                         InitControlsCache ();
1042
1043                         FillControlCache (_controls);
1044                 }
1045
1046                 void FillControlCache (ControlCollection controls)
1047                 {
1048                         if (controls == null || controls.Count == 0)
1049                                 return;
1050                         
1051                         foreach (Control c in controls) {
1052                                 try {
1053                                         if (c._userId != null)
1054                                                 _controlsCache.Add (c._userId, c);
1055                                 } catch (ArgumentException) {
1056                                         throw new HttpException (
1057                                                 "Multiple controls with the same ID '" + 
1058                                                 c._userId + 
1059                                                 "' were found. FindControl requires that controls have unique IDs. ");
1060                                 }
1061
1062                                 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ())
1063                                         FillControlCache (c.Controls);
1064                         }
1065                 }
1066
1067                 protected bool IsLiteralContent ()
1068                 {
1069                         if (_controls != null && _controls.Count == 1 && _controls [0] is LiteralControl)
1070                                 return true;
1071
1072                         return false;
1073                 }
1074
1075                 [WebSysDescription ("")]
1076                 public virtual Control FindControl (string id)
1077                 {
1078                         return FindControl (id, 0);
1079                 }
1080
1081                 Control LookForControlByName (string id)
1082                 {
1083                         EnsureControlsCache ();
1084                         return (Control) _controlsCache [id];
1085                 }
1086
1087                 protected virtual Control FindControl (string id, int pathOffset)
1088                 {
1089                         EnsureChildControls ();
1090                         Control namingContainer = null;
1091                         if ((stateMask & IS_NAMING_CONTAINER) == 0) {
1092                                 namingContainer = NamingContainer;
1093                                 if (namingContainer == null)
1094                                         return null;
1095
1096                                 return namingContainer.FindControl (id, pathOffset);
1097                         }
1098
1099                         if (!HasControls ())
1100                                 return null;
1101                         
1102                         int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
1103                         if (separatorIdx == -1) {
1104                                 // If there are no separators in the id, we must first check whether
1105                                 // any direct descendant control with that id exists before
1106                                 // attempting to look in our naming container
1107                                 Control ctl = LookForControlByName (pathOffset > 0 ? id.Substring (pathOffset) : id);
1108                                 if (ctl != null)
1109                                         return ctl;
1110                                 
1111                                 if (pathOffset == 0) {
1112                                         namingContainer = NamingContainer;
1113                                         if (namingContainer != null) {
1114                                                 ctl = namingContainer.FindControl (id);
1115                                                 if (ctl != null)
1116                                                         return ctl;
1117                                         }
1118                                 }
1119                                 return null;
1120                         }
1121
1122                         string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
1123                         namingContainer = LookForControlByName (idfound);
1124                         if (namingContainer == null)
1125                                 return null;
1126
1127                         return namingContainer.FindControl (id, separatorIdx + 1);
1128                 }
1129
1130                 protected virtual void LoadViewState (object savedState)
1131                 {
1132                         if (savedState != null) {
1133                                 ViewState.LoadViewState (savedState);
1134                                 object o = ViewState ["Visible"];
1135                                 if (o != null) {
1136                                         SetMask (VISIBLE, (bool) o);
1137                                         stateMask |= VISIBLE_CHANGED;
1138                                 }
1139                         }
1140                 }
1141
1142                 // [MonoTODO("Secure?")]
1143                 protected string MapPathSecure (string virtualPath)
1144                 {
1145                         string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
1146                         return Context.Request.MapPath (combined);
1147                 }
1148
1149                 protected virtual bool OnBubbleEvent (object source, EventArgs args) //DIT
1150                 {
1151 #if MONO_TRACE
1152                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1153                         string type_name = null;
1154                         if (trace != null) {
1155                                 type_name = GetType ().Name;
1156                                 trace.Write ("control", String.Concat ("OnBubbleEvent ", _userId, " ", type_name));
1157                         }
1158 #endif
1159                         return false;
1160                 }
1161
1162                 protected virtual void OnDataBinding (EventArgs e)
1163                 {
1164                         if ((event_mask & databinding_mask) != 0) {
1165                                 EventHandler eh = (EventHandler) (_events [DataBindingEvent]);
1166                                 if (eh != null) {
1167 #if MONO_TRACE
1168                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1169                                         string type_name = null;
1170                                         if (trace != null) {
1171                                                 type_name = GetType ().Name;
1172                                                 trace.Write ("control", String.Concat ("OnDataBinding ", _userId, " ", type_name));
1173                                         }
1174 #endif
1175                                         eh (this, e);
1176                                 }
1177                         }
1178                 }
1179
1180                 protected internal virtual void OnInit (EventArgs e)
1181                 {
1182                         if ((event_mask & init_mask) != 0) {
1183                                 EventHandler eh = (EventHandler) (_events [InitEvent]);
1184                                 if (eh != null) {
1185 #if MONO_TRACE
1186                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1187                                         string type_name = null;
1188                                         if (trace != null) {
1189                                                 type_name = GetType ().Name;
1190                                                 trace.Write ("control", String.Concat ("OnInit ", _userId, " ", type_name));
1191                                         }
1192 #endif
1193                                         eh (this, e);
1194                                 }
1195                         }
1196                 }
1197
1198                 protected internal virtual void OnLoad (EventArgs e)
1199                 {
1200                         if ((event_mask & load_mask) != 0) {
1201                                 EventHandler eh = (EventHandler) (_events [LoadEvent]);
1202                                 if (eh != null) {
1203 #if MONO_TRACE
1204                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1205                                         string type_name = null;
1206                                         if (trace != null) {
1207                                                 type_name = GetType ().Name;
1208                                                 trace.Write ("control", String.Concat ("OnLoad ", _userId, " ", type_name));
1209                                         }
1210 #endif
1211                                         eh (this, e);
1212                                 }
1213                         }
1214                 }
1215
1216                 protected internal virtual void OnPreRender (EventArgs e)
1217                 {
1218                         if ((event_mask & prerender_mask) != 0) {
1219                                 EventHandler eh = (EventHandler) (_events [PreRenderEvent]);
1220                                 if (eh != null) {
1221 #if MONO_TRACE
1222                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1223                                         string type_name = null;
1224                                         if (trace != null) {
1225                                                 type_name = GetType ().Name;
1226                                                 trace.Write ("control", String.Concat ("OnPreRender ", _userId, " ", type_name));
1227                                         }
1228 #endif
1229                                         eh (this, e);
1230                                 }
1231                         }
1232                 }
1233
1234                 protected internal virtual void OnUnload (EventArgs e)
1235                 {
1236                         if ((event_mask & unload_mask) != 0) {
1237                                 EventHandler eh = (EventHandler) (_events [UnloadEvent]);
1238                                 if (eh != null) {
1239 #if MONO_TRACE
1240                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1241                                         string type_name = null;
1242                                         if (trace != null) {
1243                                                 type_name = GetType ().Name;
1244                                                 trace.Write ("control", String.Concat ("OnUnload ", _userId, " ", type_name));
1245                                         }
1246 #endif
1247                                         eh (this, e);
1248                                 }
1249                         }
1250                 }
1251
1252                 protected internal Stream OpenFile (string path)
1253                 {
1254                         try {
1255                                 string filePath = Context.Server.MapPath (path);
1256                                 return File.OpenRead (filePath);
1257                         }
1258                         catch (UnauthorizedAccessException) {
1259                                 throw new HttpException ("Access to the specified file was denied.");
1260                         }
1261                 }
1262
1263                 internal string GetPhysicalFilePath (string virtualPath)
1264                 {
1265                         Page page = Page;
1266
1267                         if (VirtualPathUtility.IsAbsolute (virtualPath))
1268                                 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
1269
1270                         // We need to determine whether one of our parents is a
1271                         // master page. If so, we need to map the path
1272                         // relatively to the master page and not our containing
1273                         // page/control. This is necessary for cases when a
1274                         // relative path is used in a control placed in a master
1275                         // page and the master page is referenced from a
1276                         // location other than its own. In such cases MS.NET looks
1277                         // for the file in the directory where the master page
1278                         // is.
1279                         //
1280                         // An example of where it is needed is at
1281                         //
1282                         // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
1283                         //
1284                         MasterPage master = null;
1285                         Control ctrl = Parent;
1286
1287                         while (ctrl != null) {
1288                                 if (ctrl is MasterPage) {
1289                                         master = ctrl as MasterPage;
1290                                         break;
1291                                 }
1292                                 ctrl = ctrl.Parent;
1293                         }
1294
1295                         string path;
1296                         if (master != null)
1297                                 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory + "/", virtualPath);
1298                         else
1299                                 path = VirtualPathUtility.Combine (TemplateSourceDirectory + "/", virtualPath);
1300                         
1301                         return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1302                 }
1303
1304                 protected void RaiseBubbleEvent (object source, EventArgs args)
1305                 {
1306                         Control c = Parent;
1307                         while (c != null) {
1308 #if MONO_TRACE
1309                                 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1310                                 string type_name = null;
1311                                 if (trace != null) {
1312                                         type_name = GetType ().Name;
1313                                         trace.Write ("control", String.Concat ("RaiseBubbleEvent ", _userId, " ", type_name));
1314                                 }
1315 #endif
1316                                 if (c.OnBubbleEvent (source, args)) {
1317 #if MONO_TRACE
1318                                         if (trace != null)
1319                                                 trace.Write ("control", String.Concat ("End RaiseBubbleEvent (false) ", _userId, " ", type_name));
1320 #endif
1321                                         break;
1322                                 }
1323 #if MONO_TRACE
1324                                 if (trace != null)
1325                                         trace.Write ("control", String.Concat ("End RaiseBubbleEvent (true) ", _userId, " ", type_name));
1326 #endif
1327                                 c = c.Parent;
1328                         }
1329                 }
1330
1331                 protected internal virtual void Render (HtmlTextWriter writer) //DIT
1332                 {
1333                         RenderChildren (writer);
1334                 }
1335
1336                 protected internal virtual void RenderChildren (HtmlTextWriter writer) //DIT
1337                 {
1338                         if (_renderMethodDelegate != null) {
1339                                 _renderMethodDelegate (writer, this);
1340                                 return;
1341                         }
1342
1343                         if (_controls == null)
1344                                 return;
1345
1346                         int len = _controls.Count;
1347                         Control c;
1348                         for (int i = 0; i < len; i++) {
1349                                 c = _controls [i];
1350                                 if (c == null)
1351                                         continue;
1352                                 ControlAdapter tmp = c.Adapter;
1353                                 if (tmp != null)
1354                                         c.RenderControl (writer, tmp);
1355                                 else
1356                                         c.RenderControl (writer);
1357                         }
1358                 }
1359
1360                 protected virtual ControlAdapter ResolveAdapter ()
1361                 {
1362                         HttpContext context = Context;
1363
1364                         if (context == null)
1365                                 return null;
1366
1367                         if (!context.Request.BrowserMightHaveAdapters)
1368                                 return null;
1369                                 
1370                         // Search up the type hierarchy until we find a control with an adapter.
1371                         IDictionary typeMap = context.Request.Browser.Adapters;
1372                         Type controlType = GetType ();
1373                         Type adapterType = (Type)typeMap [controlType];
1374                         while (adapterType == null && controlType != typeof (Control)) {
1375                                 controlType = controlType.BaseType;
1376                                 adapterType = (Type)typeMap [controlType];
1377                         }
1378
1379                         ControlAdapter a = null;
1380                         if (adapterType != null)
1381                                 a = (ControlAdapter)Activator.CreateInstance (adapterType);
1382                         return a;
1383                 }
1384
1385                 protected virtual object SaveViewState ()
1386                 {
1387                         if ((stateMask & VISIBLE_CHANGED) != 0) {
1388                                 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1389                         } else if (_viewState == null) {
1390                                 return null;
1391                         }
1392
1393                         return _viewState.SaveViewState ();
1394                 }
1395
1396                 protected virtual void TrackViewState ()
1397                 {
1398                         if (_viewState != null)
1399                                 _viewState.TrackViewState ();
1400
1401                         stateMask |= TRACK_VIEWSTATE;
1402                 }
1403
1404                 public virtual void Dispose ()
1405                 {
1406                         if ((event_mask & disposed_mask) != 0) {
1407                                 EventHandler eh = (EventHandler) (_events [DisposedEvent]);
1408                                 if (eh != null)
1409                                         eh (this, EventArgs.Empty);
1410                         }
1411                 }
1412
1413                 [WebCategory ("FIXME")]
1414                 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1415                 public event EventHandler DataBinding {
1416                         add {
1417                                 event_mask |= databinding_mask;
1418                                 Events.AddHandler (DataBindingEvent, value);
1419                         }
1420                         remove { Events.RemoveHandler (DataBindingEvent, value); }
1421                 }
1422
1423                 [WebSysDescription ("Raised when the contol is disposed.")]
1424                 public event EventHandler Disposed {
1425                         add {
1426                                 event_mask |= disposed_mask;
1427                                 Events.AddHandler (DisposedEvent, value);
1428                         }
1429                         remove { Events.RemoveHandler (DisposedEvent, value); }
1430                 }
1431
1432                 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1433                 public event EventHandler Init {
1434                         add {
1435                                 event_mask |= init_mask;
1436                                 Events.AddHandler (InitEvent, value);
1437                         }
1438                         remove { Events.RemoveHandler (InitEvent, value); }
1439                 }
1440
1441                 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1442                 public event EventHandler Load {
1443                         add {
1444                                 event_mask |= load_mask;
1445                                 Events.AddHandler (LoadEvent, value);
1446                         }
1447                         remove { Events.RemoveHandler (LoadEvent, value); }
1448                 }
1449
1450                 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1451                 public event EventHandler PreRender {
1452                         add {
1453                                 event_mask |= prerender_mask;
1454                                 Events.AddHandler (PreRenderEvent, value);
1455                         }
1456                         remove { Events.RemoveHandler (PreRenderEvent, value); }
1457                 }
1458
1459                 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1460                 public event EventHandler Unload {
1461                         add {
1462                                 event_mask |= unload_mask;
1463                                 Events.AddHandler (UnloadEvent, value);
1464                         }
1465                         remove { Events.RemoveHandler (UnloadEvent, value); }
1466                 }
1467
1468                 public virtual void DataBind () //DIT
1469                 {
1470                         DataBind (true);
1471                 }
1472
1473                 protected virtual void DataBindChildren ()
1474                 {
1475                         if (!HasControls ())
1476                                 return;
1477
1478                         int len = _controls != null ? _controls.Count : 0;
1479                         for (int i = 0; i < len; i++) {
1480                                 Control c = _controls [i];
1481                                 c.DataBind ();
1482                         }
1483                 }
1484
1485                 public virtual bool HasControls ()
1486                 {
1487                         return (_controls != null && _controls.Count > 0);
1488                 }
1489                 
1490                 public virtual void RenderControl (HtmlTextWriter writer)
1491                 {
1492                         if (this.adapter != null) {
1493                                 RenderControl (writer, this.adapter);
1494                                 return;
1495                         }
1496
1497                         if ((stateMask & VISIBLE) != 0) {
1498                                 HttpContext ctx = Context;
1499                                 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1500                                 int pos = 0;
1501                                 if ((trace != null) && trace.IsEnabled)
1502                                         pos = ctx.Response.GetOutputByteCount ();
1503
1504                                 Render (writer);
1505                                 if ((trace != null) && trace.IsEnabled) {
1506                                         int size = ctx.Response.GetOutputByteCount () - pos;
1507                                         trace.SaveSize (this, size >= 0 ? size : 0);
1508                                 }
1509                         }
1510                 }
1511
1512                 protected void RenderControl (HtmlTextWriter writer, ControlAdapter adapter)
1513                 {
1514                         if ((stateMask & VISIBLE) != 0) {
1515                                 adapter.BeginRender (writer);
1516                                 adapter.Render (writer);
1517                                 adapter.EndRender (writer);
1518                         }
1519                 }
1520
1521                 public string ResolveUrl (string relativeUrl)
1522                 {
1523                         if (relativeUrl == null)
1524                                 throw new ArgumentNullException ("relativeUrl");
1525
1526                         if (relativeUrl == String.Empty)
1527                                 return relativeUrl;
1528
1529                         if (VirtualPathUtility.IsAbsolute (relativeUrl))
1530                                 return relativeUrl;
1531
1532                         if (relativeUrl [0] == '#')
1533                                 return relativeUrl;
1534
1535                         string ts = AppRelativeTemplateSourceDirectory;
1536                         HttpContext ctx = Context;
1537                         HttpResponse resp = ctx != null ? ctx.Response : null;
1538                         if (ts == null || ts.Length == 0 || resp == null || relativeUrl.IndexOf (':') >= 0)
1539                                 return relativeUrl;
1540                         
1541                         if (!VirtualPathUtility.IsAppRelative (relativeUrl))
1542                                 relativeUrl = VirtualPathUtility.Combine (VirtualPathUtility.AppendTrailingSlash (ts), relativeUrl);
1543                         
1544                         return resp.ApplyAppPathModifier (relativeUrl);
1545                 }
1546
1547
1548                 public string ResolveClientUrl (string relativeUrl)
1549                 {
1550                         if (relativeUrl == null)
1551                                 throw new ArgumentNullException ("relativeUrl");
1552
1553                         if (relativeUrl.Length == 0)
1554                                 return String.Empty;
1555
1556 #if TARGET_J2EE
1557                         relativeUrl = ResolveClientUrlInternal (relativeUrl);
1558
1559                         javax.faces.context.FacesContext faces = getFacesContext ();
1560                         if (faces == null)
1561                                 return relativeUrl;
1562
1563                         string url;
1564                         if (relativeUrl.IndexOf (':') >= 0)
1565                                 url = ResolveAppRelativeFromFullPath (relativeUrl);
1566                         else if (VirtualPathUtility.IsAbsolute (relativeUrl))
1567                                 url = VirtualPathUtility.ToAppRelative (relativeUrl);
1568                         else
1569                                 return faces.getApplication ().getViewHandler ().getResourceURL (faces, relativeUrl);
1570
1571                         if (VirtualPathUtility.IsAppRelative (url)) {
1572                                 url = url.Substring (1);
1573                                 url = url.Length == 0 ? "/" : url;
1574                                 return faces.getApplication ().getViewHandler ().getResourceURL (faces, url);
1575                         }
1576                         return relativeUrl;
1577                 }
1578                 
1579                 string ResolveClientUrlInternal (string relativeUrl) {
1580                         if (relativeUrl.StartsWith (J2EE.J2EEConsts.ACTION_URL_PREFIX, StringComparison.Ordinal))
1581                                 return CreateActionUrl (relativeUrl.Substring (J2EE.J2EEConsts.ACTION_URL_PREFIX.Length));
1582
1583                         if (relativeUrl.StartsWith (J2EE.J2EEConsts.RENDER_URL_PREFIX, StringComparison.Ordinal))
1584                                 return ResolveClientUrl (relativeUrl.Substring (J2EE.J2EEConsts.RENDER_URL_PREFIX.Length));
1585
1586 #endif
1587                         if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1588                                 return relativeUrl;
1589
1590                         HttpContext context = Context;
1591                         HttpRequest req = context != null ? context.Request : null;
1592                         if (req != null) {
1593                                 string templateSourceDirectory = TemplateSourceDirectory;
1594                                 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1595                                         return relativeUrl;
1596
1597                                 string basePath = req.ClientFilePath;
1598
1599                                 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1600                                         basePath = VirtualPathUtility.GetDirectory (basePath, false);
1601
1602                                 if (VirtualPathUtility.IsAppRelative (relativeUrl))
1603                                         return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1604
1605                                 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1606
1607                                 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1608                                         return relativeUrl;
1609
1610                                 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1611                                 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1612                         }
1613                         return relativeUrl;
1614                 }
1615
1616                 internal bool HasRenderMethodDelegate ()
1617                 {
1618                         return _renderMethodDelegate != null;
1619                 }
1620
1621                 [EditorBrowsable (EditorBrowsableState.Advanced)]
1622                 public void SetRenderMethodDelegate (RenderMethod renderMethod) //DIT
1623                 {
1624                         _renderMethodDelegate = renderMethod;
1625                 }
1626
1627                 internal void LoadRecursive ()
1628                 {
1629 #if MONO_TRACE
1630                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1631                         string type_name = null;
1632                         if (trace != null) {
1633                                 type_name = GetType ().Name;
1634                                 trace.Write ("control", String.Concat ("LoadRecursive ", _userId, " ", type_name));
1635                         }
1636 #endif
1637                         if ((stateMask & LOADED) == 0) {
1638                                 if (Adapter != null)
1639                                         Adapter.OnLoad (EventArgs.Empty);
1640                                 else
1641                                         OnLoad (EventArgs.Empty);
1642                         }
1643                         int ccount = _controls != null ? _controls.Count : 0;
1644                         for (int i = 0; i < ccount; i++) {
1645                                 Control c = _controls [i];
1646                                 c.LoadRecursive ();
1647                         }
1648
1649 #if MONO_TRACE
1650                         if (trace != null)
1651                                 trace.Write ("control", String.Concat ("End LoadRecursive ", _userId, " ", type_name));
1652 #endif
1653                         stateMask |= LOADED;
1654                 }
1655
1656                 internal void UnloadRecursive (Boolean dispose)
1657                 {
1658 #if MONO_TRACE
1659                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1660                         string type_name = null;
1661                         if (trace != null) {
1662                                 type_name = GetType ().Name;
1663                                 trace.Write ("control", String.Concat ("UnloadRecursive ", _userId, " ", type_name));
1664                         }
1665 #endif
1666                         int ccount = _controls != null ? _controls.Count : 0;
1667                         for (int i = 0; i < ccount; i++) {
1668                                 Control c = _controls [i];
1669                                 c.UnloadRecursive (dispose);
1670                         }
1671
1672 #if MONO_TRACE
1673                         if (trace != null)
1674                                 trace.Write ("control", String.Concat ("End UnloadRecursive ", _userId, " ", type_name));
1675 #endif
1676                         ControlAdapter tmp = Adapter;
1677                         if (tmp != null)
1678                                 tmp.OnUnload (EventArgs.Empty);
1679                         else
1680                                 OnUnload (EventArgs.Empty);
1681                         if (dispose)
1682                                 Dispose ();
1683                 }
1684
1685                 internal void PreRenderRecursiveInternal ()
1686                 {
1687                         bool visible;
1688
1689                         visible = Visible;                      
1690                         if (visible) {
1691                                 SetMask (VISIBLE, true);
1692                                 EnsureChildControls ();
1693 #if MONO_TRACE
1694                                 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1695                                 string type_name = null;
1696                                 if (trace != null) {
1697                                         type_name = GetType ().Name;
1698                                         trace.Write ("control", String.Concat ("PreRenderRecursive ", _userId, " ", type_name));
1699                                 }
1700 #endif
1701                                 if (Adapter != null)
1702                                         Adapter.OnPreRender (EventArgs.Empty);
1703                                 else
1704                                         OnPreRender (EventArgs.Empty);
1705                                 if (!HasControls ())
1706                                         return;
1707
1708                                 int len = _controls != null ? _controls.Count : 0;
1709                                 for (int i = 0; i < len; i++) {
1710                                         Control c = _controls [i];
1711                                         c.PreRenderRecursiveInternal ();
1712                                 }
1713 #if MONO_TRACE
1714                                 if (trace != null)
1715                                         trace.Write ("control", String.Concat ("End PreRenderRecursive ", _userId, " ", type_name));
1716 #endif
1717                         } else
1718                                 SetMask (VISIBLE, false);
1719                         
1720                         stateMask |= PRERENDERED;
1721                 }
1722 #if NET_4_0
1723                 internal virtual
1724 #else
1725                 internal
1726 #endif
1727                 void InitRecursive (Control namingContainer)
1728                 {
1729 #if MONO_TRACE
1730                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1731                         string type_name = null;
1732                         if (trace != null) {
1733                                 type_name = GetType ().Name;
1734                                 trace.Write ("control", String.Concat ("InitRecursive ", _userId, " ", type_name));
1735                         }
1736 #endif
1737                         SetNamingContainer (namingContainer);
1738
1739                         if (HasControls ()) {
1740                                 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1741                                         namingContainer = this;
1742
1743                                 int len = _controls != null ? _controls.Count : 0;
1744                                 for (int i = 0; i < len; i++) {
1745                                         Control c = _controls [i];
1746                                         c.InitRecursive (namingContainer);
1747                                 }
1748                         }
1749
1750                         if ((stateMask & REMOVED) == 0 && (stateMask & INITED) != INITED) {
1751                                 stateMask |= INITING;
1752                                 ApplyTheme ();
1753                                 ControlAdapter tmp = Adapter;
1754                                 if (tmp != null)
1755                                         tmp.OnInit (EventArgs.Empty);
1756                                 else
1757                                         OnInit (EventArgs.Empty);
1758                                 TrackViewState ();
1759                                 stateMask |= INITED;
1760                                 stateMask &= ~INITING;
1761                         }
1762                         
1763 #if MONO_TRACE
1764                         if (trace != null)
1765                                 trace.Write ("control", String.Concat ("End InitRecursive ", _userId, " ", type_name));
1766 #endif
1767                 }
1768
1769                 internal object SaveViewStateRecursive ()
1770                 {
1771                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1772 #if MONO_TRACE
1773                         string type_name = null;
1774                         if (trace != null) {
1775                                 type_name = GetType ().Name;
1776                                 trace.Write ("control", String.Concat ("SaveViewStateRecursive ", _userId, " ", type_name));
1777                         }
1778 #endif
1779
1780                         ArrayList controlStates = null;
1781                         bool byId = LoadViewStateByID;
1782                         if (HasControls ()) {
1783                                 int len = _controls != null ? _controls.Count : 0;
1784                                 for (int i = 0; i < len; i++) {
1785                                         Control ctrl = _controls [i];
1786                                         object ctrlState = ctrl.SaveViewStateRecursive ();
1787                                         if (ctrlState == null)
1788                                                 continue;
1789
1790                                         if (controlStates == null)
1791                                                 controlStates = new ArrayList ();
1792                                         if (byId) {
1793                                                 ctrl.EnsureID ();
1794                                                 controlStates.Add (new Pair (ctrl.ID, ctrlState));
1795                                         } else
1796                                                 controlStates.Add (new Pair (i, ctrlState));
1797                                 }
1798                         }
1799
1800                         object thisAdapterViewState = null;
1801                         if (Adapter != null)
1802                                 thisAdapterViewState = Adapter.SaveAdapterViewState ();
1803
1804                         object thisState = null;
1805
1806                         if (IsViewStateEnabled)
1807                                 thisState = SaveViewState ();
1808
1809                         if (thisState == null && controlStates == null) {
1810                                 if (trace != null) {
1811 #if MONO_TRACE
1812                                         trace.Write ("control", "End SaveViewStateRecursive " + _userId + " " + type_name + " saved nothing");
1813 #endif
1814                                         trace.SaveViewState (this, null);
1815                                 }
1816                                 return null;
1817                         }
1818
1819                         if (trace != null) {
1820 #if MONO_TRACE
1821                                 trace.Write ("control", "End SaveViewStateRecursive " + _userId + " " + type_name + " saved a Triplet");
1822 #endif
1823                                 trace.SaveViewState (this, thisState);
1824                         }
1825                         thisState = new object[] { thisState, thisAdapterViewState };
1826                         return new Pair (thisState, controlStates);
1827                 }
1828
1829                 internal void LoadViewStateRecursive (object savedState)
1830                 {
1831                         if (savedState == null)
1832                                 return;
1833
1834 #if MONO_TRACE
1835                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1836                         string type_name = null;
1837                         if (trace != null) {
1838                                 type_name = GetType ().Name;
1839                                 trace.Write ("control", String.Concat ("LoadViewStateRecursive ", _userId, " ", type_name));
1840                         }
1841 #endif
1842                         Pair savedInfo = (Pair) savedState;
1843                         object[] controlAndAdapterViewStates = (object [])savedInfo.First;
1844                         if (Adapter != null)
1845                                 Adapter.LoadAdapterViewState (controlAndAdapterViewStates [1]);
1846                         LoadViewState (controlAndAdapterViewStates [0]);
1847
1848                         ArrayList controlStates = savedInfo.Second as ArrayList;
1849                         if (controlStates == null)
1850                                 return;
1851
1852                         int nControls = controlStates.Count;
1853                         bool byId = LoadViewStateByID;
1854                         for (int i = 0; i < nControls; i++) {
1855                                 Pair p = controlStates [i] as Pair;
1856                                 if (p == null)
1857                                         continue;
1858
1859                                 if (byId) {
1860                                         string id = (string)p.First;
1861                                         bool found = false;
1862                                         
1863                                         foreach (Control c in Controls) {
1864                                                 c.EnsureID ();
1865                                                 if (c.ID == id) {
1866                                                         found = true;
1867                                                         c.LoadViewStateRecursive (p.Second);
1868                                                         break;
1869                                                 }
1870                                         }
1871
1872                                         if (!found) {
1873                                                 if (pendingVS == null)
1874                                                         pendingVS = new Hashtable ();
1875                                                 pendingVS [id] = p.Second;
1876                                         }
1877                                 } else {
1878                                         int k = (int) p.First;
1879                                         if (k < Controls.Count) {
1880                                                 Control c = Controls [k];
1881                                                 c.LoadViewStateRecursive (p.Second);
1882                                         } else {
1883                                                 if (pendingVS == null)
1884                                                         pendingVS = new Hashtable ();
1885
1886                                                 pendingVS [k] = p.Second;
1887                                         }
1888                                 }
1889                         }
1890
1891 #if MONO_TRACE
1892                         if (trace != null)
1893                                 trace.Write ("control", String.Concat ("End LoadViewStateRecursive ", _userId, " ", type_name));
1894 #endif
1895                         stateMask |= VIEWSTATE_LOADED;
1896                 }
1897
1898                 internal ControlSkin controlSkin;
1899
1900                 internal void ApplyTheme ()
1901                 {
1902 #if MONO_TRACE
1903                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1904                         string type_name = null;
1905                         if (trace != null) {
1906                                 type_name = GetType ().Name;
1907                                 trace.Write ("control", String.Concat ("ApplyThemeRecursive ", _userId, " ", type_name));
1908                         }
1909 #endif
1910                         Page page = Page;
1911                         if (page != null && page.PageTheme != null && EnableTheming) {
1912                                 ControlSkin controlSkin = page.PageTheme.GetControlSkin (GetType (), SkinID);
1913                                 if (controlSkin != null)
1914                                         controlSkin.ApplySkin (this);
1915                         }
1916
1917 #if MONO_TRACE
1918                         if (trace != null)
1919                                 trace.Write ("control", String.Concat ("End ApplyThemeRecursive ", _userId, " ", type_name));
1920 #endif
1921                 }
1922
1923                 internal bool AutoID {
1924                         get { return (stateMask & AUTOID) != 0; }
1925                         set {
1926                                 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1927                                         return;
1928
1929                                 SetMask (AUTOID, value);
1930                         }
1931                 }
1932
1933                 protected internal virtual void RemovedControl (Control control)
1934                 {
1935                         control.UnloadRecursive (false);
1936                         control._parent = null;
1937                         control._page = null;
1938                         control._namingContainer = null;
1939                         if ((control.stateMask & AUTOID_SET) != 0) {
1940                                 control._userId = null;
1941                                 control.SetMask (ID_SET, false);
1942                         }
1943                         control.NullifyUniqueID ();
1944                         control.SetMask (REMOVED, true);
1945                         ResetControlsCache ();
1946                 }
1947                 
1948                 string skinId = string.Empty;
1949                 bool _enableTheming = true;
1950
1951                 [Browsable (false)]
1952                 [Themeable (false)]
1953                 [DefaultValue (true)]
1954                 public virtual bool EnableTheming {
1955                         get {
1956                                 if ((stateMask & ENABLE_THEMING) != 0)
1957                                         return _enableTheming;
1958
1959                                 if (_parent != null)
1960                                         return _parent.EnableTheming;
1961
1962                                 return true;
1963                         }
1964                         set {
1965                                 SetMask (ENABLE_THEMING, true);
1966                                 _enableTheming = value;
1967                         }
1968                 }
1969
1970                 [Browsable (false)]
1971                 [DefaultValue ("")]
1972                 [Filterable (false)]
1973                 public virtual string SkinID {
1974                         get { return skinId; }
1975                         set { skinId = value; }
1976                 }
1977
1978                 ControlBuilder IControlBuilderAccessor.ControlBuilder {
1979                         get { throw new NotImplementedException (); }
1980                 }
1981
1982                 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1983                 {
1984                         throw new NotImplementedException ();
1985                 }
1986
1987                 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1988                 {
1989                         SetDesignModeState (designData);
1990                 }
1991
1992                 void IControlDesignerAccessor.SetOwnerControl (Control control)
1993                 {
1994                         throw new NotImplementedException ();
1995                 }
1996
1997                 IDictionary IControlDesignerAccessor.UserData {
1998                         get { throw new NotImplementedException (); }
1999                 }
2000
2001                 ExpressionBindingCollection expressionBindings;
2002
2003                 ExpressionBindingCollection IExpressionsAccessor.Expressions {
2004                         get {
2005                                 if (expressionBindings == null)
2006                                         expressionBindings = new ExpressionBindingCollection ();
2007                                 return expressionBindings;
2008                         }
2009                 }
2010
2011                 bool IExpressionsAccessor.HasExpressions {
2012                         get { return (expressionBindings != null && expressionBindings.Count > 0); }
2013                 }
2014
2015                 public virtual void Focus ()
2016                 {
2017                         Page.SetFocus (this);
2018                 }
2019
2020                 protected internal virtual void LoadControlState (object state)
2021                 {
2022                 }
2023
2024                 protected internal virtual object SaveControlState ()
2025                 {
2026                         return null;
2027                 }
2028
2029                 protected virtual void DataBind (bool raiseOnDataBinding)
2030                 {
2031                         bool foundDataItem = false;
2032
2033                         if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
2034                                 object o = DataBinder.GetDataItem (this, out foundDataItem);
2035                                 if (foundDataItem)
2036                                         Page.PushDataItemContext (o);
2037                         }
2038
2039                         try {
2040                                 if (raiseOnDataBinding)
2041                                         OnDataBinding (EventArgs.Empty);
2042                                 DataBindChildren ();
2043                         } finally {
2044                                 if (foundDataItem)
2045                                         Page.PopDataItemContext ();
2046                         }
2047                 }
2048
2049                 protected virtual IDictionary GetDesignModeState ()
2050                 {
2051                         throw new NotImplementedException ();
2052                 }
2053
2054                 protected virtual void SetDesignModeState (IDictionary data)
2055                 {
2056                         throw new NotImplementedException ();
2057                 }
2058
2059                 internal bool IsInited {
2060                         get { return (stateMask & INITED) != 0; }
2061                 }
2062
2063                 internal bool IsLoaded {
2064                         get { return (stateMask & LOADED) != 0; }
2065                 }
2066
2067                 internal bool IsPrerendered {
2068                         get { return (stateMask & PRERENDERED) != 0; }
2069                 }
2070
2071                 bool CheckForValidationSupport ()
2072                 {
2073                         return GetType ().GetCustomAttributes (typeof (SupportsEventValidationAttribute), false).Length > 0;
2074                 }
2075
2076                 //
2077                 // Apparently this is where .NET routes validation from all the controls which
2078                 // support it. See:
2079                 //
2080                 //  http://odetocode.com/Blogs/scott/archive/2006/03/20/3145.aspx
2081                 //    Sample in here contains ValidateEvent in the stack trace
2082                 //
2083                 //  http://odetocode.com/blogs/scott/archive/2006/03/21/3153.aspx
2084                 //
2085                 //  http://www.alexthissen.nl/blogs/main/archive/2005/12/13/event-validation-of-controls-in-asp-net-2-0.aspx
2086                 //
2087                 // It also seems that it's the control's responsibility to call this method or
2088                 // validation won't take place. Also, the SupportsEventValidation attribute must be
2089                 // present on the control for validation to take place.
2090                 //
2091                 internal void ValidateEvent (String uniqueId, String argument)
2092                 {
2093                         Page page = Page;
2094                         
2095                         if (page != null && CheckForValidationSupport ())
2096                                 page.ClientScript.ValidateEvent (uniqueId, argument);
2097                 }
2098
2099                 void IParserAccessor.AddParsedSubObject (object obj)
2100                 {
2101                         this.AddParsedSubObject (obj);
2102                 }
2103
2104                 DataBindingCollection IDataBindingsAccessor.DataBindings {
2105                         get {
2106                                 if (dataBindings == null) {
2107                                         dataBindings = new DataBindingCollection ();
2108                                 }
2109                                 return dataBindings;
2110                         }
2111                 }
2112
2113                 bool IDataBindingsAccessor.HasDataBindings {
2114                         get {
2115                                 if (dataBindings != null && dataBindings.Count > 0) {
2116                                         return true;
2117                                 }
2118                                 return false;
2119                         }
2120                 }
2121 #if NET_4_0
2122                 [ThemeableAttribute(false)]
2123                 [DefaultValue ("0")]
2124                 public virtual ViewStateMode ViewStateMode {
2125                         get { return viewStateMode;  }
2126                         set {
2127                                 if (value < ViewStateMode.Inherit || value > ViewStateMode.Disabled)
2128                                         throw new ArgumentOutOfRangeException ("An attempt was made to set this property to a value that is not in the ViewStateMode enumeration.");
2129
2130                                 viewStateMode = value;
2131                         }
2132                 }
2133
2134                 public string GetRouteUrl (object routeParameters)
2135                 {
2136                         return GetRouteUrl (null, new RouteValueDictionary (routeParameters));
2137                 }
2138
2139                 public string GetRouteUrl (RouteValueDictionary routeParameters)
2140                 {
2141                         return GetRouteUrl (null, routeParameters);
2142                 }
2143
2144                 public string GetRouteUrl (string routeName, object routeParameters)
2145                 {
2146                         return GetRouteUrl (routeName, new RouteValueDictionary (routeParameters));
2147                 }
2148
2149                 public string GetRouteUrl (string routeName, RouteValueDictionary routeParameters)
2150                 {
2151                         HttpContext ctx = Context ?? HttpContext.Current;
2152                         HttpRequest req = ctx != null ? ctx.Request : null;
2153
2154                         if (req == null)
2155                                 return null;
2156
2157                         VirtualPathData vpd = RouteTable.Routes.GetVirtualPath (req.RequestContext, routeName, routeParameters);
2158                         if (vpd == null)
2159                                 return null;
2160
2161                         return vpd.VirtualPath;
2162                 }
2163
2164                 public string GetUniqueIDRelativeTo (Control control)
2165                 {
2166                         if (control == null)
2167                                 throw new ArgumentNullException ("control");
2168
2169                         Control parent = this;
2170                         Control namingContainer = control.NamingContainer;
2171                         
2172                         if (namingContainer != null)
2173                                 while (parent != null && parent != namingContainer)
2174                                         parent = parent.Parent;
2175
2176                         if (parent != namingContainer)
2177                                 throw new InvalidOperationException (
2178                                         String.Format ("This control is not a descendant of the NamingContainer of '{0}'", control.UniqueID)
2179                                 );
2180
2181                         int idx = control.UniqueID.LastIndexOf (IdSeparator);
2182                         if (idx < 0)
2183                                 return UniqueID;
2184
2185                         return UniqueID.Substring (idx + 1);
2186                 }
2187 #endif
2188         }
2189 }