* ObjectStateFormatter.cs: Avoid NRE in Serialize. Fixes bug #81851.
[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 //
10 // (C) Bob Smith
11 // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com)
12 // (C) 2004 Novell, Inc. (http://www.novell.com)
13 //
14
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 // This will provide extra information when trace is enabled. Might be too verbose.
37 #define MONO_TRACE
38
39 using System.Collections;
40 using System.ComponentModel;
41 using System.ComponentModel.Design;
42 using System.ComponentModel.Design.Serialization;
43 using System.Security.Permissions;
44 using System.Web;
45 using System.Web.Util;
46 using System.Globalization;
47 #if NET_2_0
48 using System.Web.UI.Adapters;
49 using System.IO;
50 #endif
51
52 namespace System.Web.UI
53 {
54         // CAS
55         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
56         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
57         // attributes
58         [DefaultProperty ("ID"), DesignerCategory ("Code"), ToolboxItemFilter ("System.Web.UI", ToolboxItemFilterType.Require)]
59         [ToolboxItem ("System.Web.UI.Design.WebControlToolboxItem, " + Consts.AssemblySystem_Design)]
60         [Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
61 #if NET_2_0
62         [DesignerSerializer ("Microsoft.VisualStudio.Web.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VisualStudio_Web,
63                                 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
64         [Bindable (true)]
65         [Themeable (false)]
66 #else
67         [DesignerSerializer ("Microsoft.VSDesigner.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner,
68                                 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
69 #endif          
70         public partial class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor
71 #if NET_2_0
72         , IUrlResolutionService, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
73 #endif
74         {
75                 static readonly object DataBindingEvent = new object();
76                 static readonly object DisposedEvent = new object();
77                 static readonly object InitEvent = new object();
78                 static readonly object LoadEvent = new object();
79                 static readonly object PreRenderEvent = new object();
80                 static readonly object UnloadEvent = new object();
81                 static string[] defaultNameArray;
82                 /* */
83                 int event_mask;
84                 const int databinding_mask = 1;
85                 const int disposed_mask = 1 << 1;
86                 const int init_mask = 1 << 2;
87                 const int load_mask = 1 << 3;
88                 const int prerender_mask = 1 << 4;
89                 const int unload_mask = 1 << 5;
90                 /* */
91
92                 string uniqueID;
93                 string _userId;
94                 ControlCollection _controls;
95                 Control _namingContainer;
96                 Page _page;
97                 Control _parent;
98                 ISite _site;
99                 HttpContext _context;
100                 StateBag _viewState;
101                 EventHandlerList _events;
102                 RenderMethod _renderMethodDelegate;
103                 int defaultNumberID;
104  
105                 DataBindingCollection dataBindings;
106                 Hashtable pendingVS; // may hold unused viewstate data from child controls
107                 
108
109 #if NET_2_0
110                 TemplateControl _templateControl;
111                 bool _isChildControlStateCleared;
112                 string _templateSourceDirectory;
113 #endif
114                 /*************/
115                 int stateMask;
116                 const int ENABLE_VIEWSTATE      = 1;
117                 const int VISIBLE               = 1 << 1;
118                 const int AUTOID                = 1 << 2;
119                 const int CREATING_CONTROLS     = 1 << 3;
120                 const int BINDING_CONTAINER     = 1 << 4;
121                 const int AUTO_EVENT_WIREUP     = 1 << 5;
122                 const int IS_NAMING_CONTAINER   = 1 << 6;
123                 const int VISIBLE_CHANGED       = 1 << 7;
124                 const int TRACK_VIEWSTATE       = 1 << 8;
125                 const int CHILD_CONTROLS_CREATED = 1 << 9;
126                 const int ID_SET                = 1 << 10;
127                 const int INITED                = 1 << 11;
128                 const int INITING               = 1 << 12;
129                 const int VIEWSTATE_LOADED      = 1 << 13;
130                 const int LOADED                = 1 << 14;
131                 const int PRERENDERED           = 1 << 15;
132 #if NET_2_0
133                 const int ENABLE_THEMING        = 1 << 16;
134 #endif
135                 /*************/
136                 
137                 static Control ()
138                 {
139                         defaultNameArray = new string [100];
140                         for (int i = 0 ; i < 100 ; i++)
141 #if NET_2_0
142                                 defaultNameArray [i] = String.Format("ctl{0:D2}", i);
143 #else
144                                 defaultNameArray [i] = "_ctl" + i;
145 #endif
146                 }
147
148                 public Control()
149                 {
150                         stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
151                         if (this is INamingContainer)
152                                 stateMask |= IS_NAMING_CONTAINER;
153                 }
154
155 #if NET_2_0
156                 [MonoTODO("Not implemented, always returns null")]
157                 protected ControlAdapter Adapter 
158                 {
159                         get {
160                                 // for the time being, fool the
161                                 // Control machinery into thinking we
162                                 // don't have an Adapter.  This will
163                                 // allow us to write all the rest of
164                                 // the Adapter handling code without
165                                 // having to worry about *having*
166                                 // adapters.
167                                 return null;
168                         }
169                 }
170
171                 string _appRelativeTemplateSourceDirectory = null;
172
173                 [EditorBrowsable (EditorBrowsableState.Advanced)]
174                 [Browsable (false)]
175                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
176                 public string AppRelativeTemplateSourceDirectory 
177                 {
178                         get {
179                                 if (_appRelativeTemplateSourceDirectory != null && !(this is MasterPage))
180                                         return _appRelativeTemplateSourceDirectory;
181
182                                 if (Parent != null)
183                                         return Parent.AppRelativeTemplateSourceDirectory;
184
185                                 return "~/";
186                         }
187                         [EditorBrowsable (EditorBrowsableState.Never)]
188                         set     { _appRelativeTemplateSourceDirectory = value; }
189                 }
190                 
191 #endif          
192
193                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
194                 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
195                 public Control BindingContainer {
196                         get {
197                                 Control container = NamingContainer;
198                                 if (container != null && (container.stateMask & BINDING_CONTAINER) == 0)
199                                         container = container.BindingContainer;
200                                 return container;
201                         }
202                 }
203
204                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
205                 [Browsable (false)]
206                 [WebSysDescription ("An Identification of the control that is rendered.")]
207                 public virtual string ClientID {
208                         get {
209                                 string client = UniqueID;
210
211                                 if (client != null)
212 #if NET_2_0
213                                         client = UniqueID2ClientID (client);
214 #else
215                                         client = client.Replace (':', ClientIDSeparator);
216 #endif
217                                 
218                                 stateMask |= ID_SET;
219                                 return client;
220                         }
221                 }
222
223 #if NET_2_0
224                 internal string UniqueID2ClientID (string uniqueId)
225                 {
226                         return uniqueId.Replace (IdSeparator, ClientIDSeparator);
227                 }
228
229                 protected char ClientIDSeparator
230 #else
231                 char ClientIDSeparator
232 #endif          
233                 {
234                         get {
235                                 return '_';
236                         }
237                 }
238
239
240                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
241                 [Browsable (false)]
242                 [WebSysDescription ("The child controls of this control.")]
243                 public virtual ControlCollection Controls //DIT
244                 {
245                         get
246                         {
247                                 if (_controls == null) _controls = CreateControlCollection();
248                                 return _controls;
249                         }
250                 }
251
252 #if NET_2_0
253                 [MonoTODO ("revisit once we have a real design strategy")]
254                 protected internal bool DesignMode 
255                 {
256                         get { return false; }
257                 }
258 #endif          
259
260                 [DefaultValue (true), WebCategory ("Behavior")]
261                 [WebSysDescription ("An Identification of the control that is rendered.")]
262 #if NET_2_0
263                 [Themeable (false)]
264 #endif                
265                 public virtual bool EnableViewState {
266                         get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
267                         set { SetMask (ENABLE_VIEWSTATE, value); }
268                 }
269                 
270                 [MergableProperty (false), ParenthesizePropertyName (true)]
271                 [WebSysDescription ("The name of the control that is rendered.")]
272 #if NET_2_0
273                 [Filterable (false), Themeable (false)]
274 #endif                
275
276                 public virtual string ID {
277                         get {
278                                 return (((stateMask & ID_SET) != 0) ? _userId : null);
279                         }
280                         
281                         set {
282                                 if (value == "")
283                                         value = null;
284
285                                 stateMask |= ID_SET;
286                                 _userId = value;
287                                 NullifyUniqueID ();
288                         }
289                 }
290
291 #if NET_2_0
292                 protected char IdSeparator 
293                 {
294                         get {
295                                 return '$';
296                         }
297                 }
298
299                 protected internal bool IsChildControlStateCleared {
300                         get { return _isChildControlStateCleared; }
301                 }
302
303                 protected internal bool IsViewStateEnabled 
304                 {
305                         get {
306
307                                 for (Control control = this; control != null; control = control.Parent)
308                                         if (!control.EnableViewState)
309                                                 return false;
310
311                                 return true;
312                         }
313                 }
314
315                 protected bool LoadViewStateByID 
316                 {
317                         get {
318                                 return false;
319                         }
320                 }
321 #endif          
322                 
323                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
324                 [Browsable (false)]
325                 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
326                 public virtual Control NamingContainer {
327                         get {
328                                 if (_namingContainer == null && _parent != null) {
329                                         if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
330                                                 _namingContainer = _parent.NamingContainer;
331                                         else
332                                                 _namingContainer = _parent;
333                                 }
334
335                                 return _namingContainer;
336                         }
337                 }
338
339                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
340                 [Browsable (false)]
341                 [WebSysDescription ("The webpage that this control resides on.")]
342 #if NET_2_0
343                 [Bindable (false)]
344 #endif                
345                 public virtual Page Page //DIT
346                 {
347                         get
348                         {
349                                 if (_page == null && _parent != null) _page = _parent.Page;
350                                 return _page;
351                         }
352                         set
353                         {
354                                 _page = value;
355                         }
356                 }
357
358                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
359                 [Browsable (false)]
360                 [WebSysDescription ("The parent control of this control.")]
361                 public virtual Control Parent //DIT
362                 {
363                         get
364                         {
365                                 return _parent;
366                         }
367                 }
368
369                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
370                 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
371                 [WebSysDescription ("The site this control is part of.")]
372                 public ISite Site //DIT
373                 {
374                         get
375                         {
376                                 return _site;
377                         }
378                         set
379                         {
380                                 _site = value;
381                         }
382                 }
383
384 #if NET_2_0
385                 [Browsable (false)]
386                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
387                 public TemplateControl TemplateControl {
388                         get {
389                                 if (_templateControl != null)
390                                         return _templateControl;
391                                 if (_parent != null)
392                                         return _parent.TemplateControl;
393                                 return null;
394                         }
395                         
396                         [EditorBrowsable (EditorBrowsableState.Never)]
397                         set { _templateControl = value; }
398                 }
399 #endif          
400
401 #if !TARGET_J2EE
402                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
403                 [Browsable (false)]
404                 [WebSysDescription ("A virtual directory containing the parent of the control.")]
405                 public virtual string TemplateSourceDirectory {
406                         get {
407 #if NET_2_0
408                                 if (_templateSourceDirectory == null) {
409                                         TemplateControl tc = TemplateControl;
410
411                                         if (tc == null) {
412                                                 HttpContext ctx = Context;
413                                                 if (ctx != null)
414                                                         _templateSourceDirectory = VirtualPathUtility.GetDirectory (ctx.Request.CurrentExecutionFilePath);
415                                         } else if (tc != this)
416                                                 _templateSourceDirectory = tc.TemplateSourceDirectory;
417                                         
418                                         if (_templateSourceDirectory == null && this is TemplateControl) {
419                                                 string path = ((TemplateControl)this).AppRelativeVirtualPath;
420                                                 
421                                                 if (path != null) {
422                                                         // Pretend our application virtual root is "/" even if it isn't - we just
423                                                         // want to get an absolute url out of relative one, without the real
424                                                         // application root prepended to it.
425                                                         string ret = VirtualPathUtility.GetDirectory (VirtualPathUtility.ToAbsolute (path, "/"));
426                                                         int len = ret.Length;
427                                                         if (len <= 1)
428                                                                 return ret;
429                                                         if (ret [--len] == '/')
430                                                                 _templateSourceDirectory = ret.Substring (0, len);
431                                                 } else
432                                                         _templateSourceDirectory = String.Empty;
433                                         }
434                                         if (_templateSourceDirectory == null)
435                                                 _templateSourceDirectory = String.Empty;
436                                 }
437                                 
438                                 return _templateSourceDirectory;
439 #else
440                                 return (_parent == null) ? String.Empty : _parent.TemplateSourceDirectory;
441 #endif
442                         }
443                 }
444 #endif
445
446                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
447                 [Browsable (false)]
448                 [WebSysDescription ("The unique ID of the control.")]
449                 public virtual string UniqueID {
450                         get {
451                                 if (uniqueID != null)
452                                         return uniqueID;
453
454                                 if (_namingContainer == null) {
455                                         if ((stateMask & IS_NAMING_CONTAINER) == 0)
456                                                 _namingContainer = NamingContainer;
457                                         if (_namingContainer == null)
458                                                 return _userId;
459                                 }
460
461                                 if (_userId == null)
462                                         _userId = _namingContainer.GetDefaultName ();
463
464                                 string prefix = _namingContainer.UniqueID;
465 #if TARGET_J2EE
466                                 // For J2EE portlets we need to add the namespace to the ID.
467                                 if (_namingContainer == _page && _page.PortletNamespace != null)
468                                         prefix = _page.PortletNamespace;
469                                 else
470 #endif
471                                 if (_namingContainer == _page || prefix == null) {
472                                         uniqueID = _userId;
473                                         return uniqueID;
474                                 }
475
476 #if NET_2_0
477                                 uniqueID = prefix + IdSeparator + _userId;
478 #else
479                                 uniqueID = prefix + ":" + _userId;
480 #endif
481                                 return uniqueID;
482                         }
483                 }
484
485                 void SetMask (int m, bool val)
486                 {
487                         if (val)
488                                 stateMask |= m;
489                         else
490                                 stateMask &= ~m;
491                 }
492                 
493                 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
494                 [WebSysDescription ("Visiblity state of the control.")]
495                 public virtual bool Visible {
496                         get {
497                                 if ((stateMask & VISIBLE) == 0)
498                                         return false;
499
500                                 if (_parent != null)
501                                         return _parent.Visible;
502
503                                 return true;
504                         }
505
506                         set {
507                                 if ((value && (stateMask & VISIBLE) == 0) ||
508                                     (!value && (stateMask & VISIBLE) != 0)) {
509                                         if (IsTrackingViewState)
510                                                 stateMask |= VISIBLE_CHANGED;
511                                 }
512
513                                 SetMask (VISIBLE, value);
514                         }
515                 }
516
517                 protected bool ChildControlsCreated {
518                         get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
519                         set {
520                                 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
521                                         if (_controls != null)
522                                                 _controls.Clear();
523                                 }
524
525                                 SetMask (CHILD_CONTROLS_CREATED, value);
526                         }
527                 }
528
529                 [Browsable (false)]
530                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
531                 protected virtual HttpContext Context //DIT
532                 {
533                         get
534                         {
535                                 HttpContext context;
536                                 if (_context != null)
537                                         return _context;
538                                 if (_parent == null)
539                                         return HttpContext.Current;
540                                 context = _parent.Context;
541                                 if (context != null)
542                                         return context;
543                                 return HttpContext.Current;
544                         }
545                 }
546
547                 protected EventHandlerList Events {
548                         get {
549                                 if (_events == null)
550                                         _events = new EventHandlerList ();
551                                 return _events;
552                         }
553                 }
554
555                 protected bool HasChildViewState {
556                         get {
557                                 return (pendingVS != null && pendingVS.Count > 0);
558                         }
559                 }
560
561                 protected bool IsTrackingViewState {
562                         get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
563                 }
564
565                 [Browsable (false)]
566                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
567                 [WebSysDescription ("ViewState")]
568                 protected virtual StateBag ViewState
569                 {
570                         get
571                         {
572                                 if(_viewState == null)
573                                         _viewState = new StateBag (ViewStateIgnoresCase);
574
575                                 if (IsTrackingViewState)
576                                         _viewState.TrackViewState ();
577
578                                 return _viewState;
579                         }
580                 }
581
582                 [Browsable (false)]
583                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
584                 protected virtual bool ViewStateIgnoresCase
585                 {
586                         get {
587                                 return false;
588                         }
589                 }
590
591                 internal bool AutoEventWireup {
592                         get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
593                         set { SetMask (AUTO_EVENT_WIREUP, value); }
594                 }
595
596                 internal void SetBindingContainer (bool isBC)
597                 {
598                         SetMask (BINDING_CONTAINER, isBC);
599                 }
600
601                 internal void ResetChildNames ()
602                 {
603                         defaultNumberID = 0;
604                 }
605
606                 string GetDefaultName ()
607                 {
608                         string defaultName;
609                         if (defaultNumberID > 99) {
610 #if NET_2_0
611                                 defaultName = "ctl" + defaultNumberID++;
612 #else
613                                 defaultName = "_ctl" + defaultNumberID++;
614 #endif
615                         } else {
616                                 defaultName = defaultNameArray [defaultNumberID++];
617                         }
618                         return defaultName;
619                 }
620
621                 void NullifyUniqueID ()
622                 {
623                         uniqueID = null;
624                         if (!HasControls ())
625                                 return;
626
627                         foreach (Control c in _controls)
628                                 c.NullifyUniqueID ();
629                 }
630
631                 protected internal virtual void AddedControl (Control control, int index)
632                 {
633                         /* Ensure the control don't have more than 1 parent */
634                         if (control._parent != null)
635                                 control._parent.Controls.Remove (control);
636
637                         control._parent = this;
638                         control._page = _page;
639                         Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
640
641                         if (nc != null) {
642                                 control._namingContainer = nc;
643                                 if (control.AutoID == true && control._userId == null)
644                                         control._userId =  nc.GetDefaultName ();
645                         }
646
647                         if ((stateMask & (INITING | INITED)) != 0)
648                                 control.InitRecursive (nc);
649
650                         if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
651                                 if (pendingVS != null) {
652                                         object vs = pendingVS [index];
653                                         if (vs != null) {
654                                                 pendingVS.Remove (index);
655                                                 if (pendingVS.Count == 0)
656                                                         pendingVS = null;
657                                         
658                                                 control.LoadViewStateRecursive (vs);
659                                         }
660                                 }
661                         }
662
663                         if ((stateMask & LOADED) != 0)
664                                 control.LoadRecursive ();
665                         
666                         if ((stateMask & PRERENDERED) != 0)
667                                 control.PreRenderRecursiveInternal ();
668                 }
669
670                 protected virtual void AddParsedSubObject(object obj) //DIT
671                 {
672                         Control c = obj as Control;
673                         if (c != null) Controls.Add(c);
674                 }
675
676 #if NET_2_0
677                 [EditorBrowsable (EditorBrowsableState.Advanced)]
678                 public virtual void ApplyStyleSheetSkin (Page page)
679                 {
680                         if (!EnableTheming) /* this enough? */
681                                 return;
682
683                         /* apply the style sheet skin here */
684                         if (page.StyleSheetPageTheme != null) {
685                                 ControlSkin cs = page.StyleSheetPageTheme.GetControlSkin (GetType(), SkinID);
686                                 if (cs != null)
687                                         cs.ApplySkin (this);
688                         }
689                 }
690 #endif          
691
692                 protected void BuildProfileTree(string parentId, bool calcViewState)
693                 {
694                         //TODO
695                 }
696
697 #if NET_2_0
698                 protected void ClearChildControlState ()
699                 {
700                         _isChildControlStateCleared = true;
701                 }
702
703                 protected void ClearChildState ()
704                 {
705                         ClearChildViewState ();
706                         ClearChildControlState ();
707                 }
708 #endif          
709
710                 protected void ClearChildViewState ()
711                 {
712                         pendingVS = null;
713                 }
714
715 #if NET_2_0
716                 protected internal
717 #else
718                 protected
719 #endif          
720                 virtual void CreateChildControls() {} //DIT
721                 
722                 protected virtual ControlCollection CreateControlCollection() //DIT
723                 {
724                         return new ControlCollection(this);
725                 }
726
727                 protected virtual void EnsureChildControls ()
728                 {
729                         if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
730                                 stateMask |= CREATING_CONTROLS;
731 #if NET_2_0
732                                 if (Adapter != null)
733                                         Adapter.CreateChildControls ();
734                                 else
735 #endif
736                                         CreateChildControls();
737                                 ChildControlsCreated = true;
738                                 stateMask &= ~CREATING_CONTROLS;
739                         }
740                 }
741
742 #if NET_2_0
743                 protected void EnsureID ()
744                 {
745                         if (Page == null)
746                                 return;
747                         ID = NamingContainer.GetDefaultName ();
748                 }
749
750                 protected bool HasEvents ()
751                 {
752                         return _events != null;
753                 }
754                 
755 #endif
756                 
757
758                 protected bool IsLiteralContent()
759                 {
760                         if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
761                                 return true;
762
763                         return false;
764                 }
765
766                 [WebSysDescription ("")]
767                 public virtual Control FindControl (string id)
768                 {
769                         return FindControl (id, 0);
770                 }
771
772                 Control LookForControlByName (string id)
773                 {
774 #if TARGET_J2EE
775                         if (this == Page && id != null && id == Page.PortletNamespace)
776                                 return this;
777 #endif
778                         if (!HasControls ())
779                                 return null;
780
781                         Control result = null;
782                         foreach (Control c in _controls) {
783                                 if (String.Compare (id, c._userId, true, CultureInfo.InvariantCulture) == 0) {
784                                         if (result != null && result != c) {
785                                                 throw new HttpException ("1 Found more than one control with ID '" + id + "'");
786                                         }
787
788                                         result = c;
789                                         continue;
790                                 }
791
792                                 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ()) {
793                                         Control child = c.LookForControlByName (id);
794                                         if (child != null) {
795                                                 if (result != null && result != child)
796                                                         throw new HttpException ("2 Found more than one control with ID '" + id + "'");
797
798                                                 result = child;
799                                         }
800                                 }
801                         }
802
803                         return result;
804                 }
805
806                 protected virtual Control FindControl (string id, int pathOffset)
807                 {
808                         EnsureChildControls ();
809                         Control namingContainer = null;
810                         if ((stateMask & IS_NAMING_CONTAINER) == 0) {
811                                 namingContainer = NamingContainer;
812                                 if (namingContainer == null)
813                                         return null;
814
815                                 return namingContainer.FindControl (id, pathOffset);
816                         }
817
818                         if (!HasControls ())
819                                 return null;
820 #if NET_2_0
821                         int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
822 #else
823                         int separatorIdx = id.IndexOf (':', pathOffset);
824 #endif
825                         if (separatorIdx == -1)
826                                 return LookForControlByName (id.Substring (pathOffset));
827                         
828                         string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
829                         namingContainer = LookForControlByName (idfound);
830                         if (namingContainer == null)
831                                 return null;
832
833                         return namingContainer.FindControl (id, separatorIdx + 1);
834                 }
835
836                 protected virtual void LoadViewState(object savedState)
837                 {
838                         if (savedState != null) {
839                                 ViewState.LoadViewState (savedState);
840                                 object o = ViewState ["Visible"];
841                                 if (o != null) {
842                                         SetMask (VISIBLE, (bool) o);
843                                         stateMask |= VISIBLE_CHANGED;
844                                 }
845                         }
846                 }
847
848                 // [MonoTODO("Secure?")]
849                 protected string MapPathSecure(string virtualPath)
850                 {
851                         string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
852                         return Context.Request.MapPath (combined);
853                 }
854
855                 protected virtual bool OnBubbleEvent(object source, EventArgs args) //DIT
856                 {
857 #if MONO_TRACE
858                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
859                         string type_name = null;
860                         if (trace != null) {
861                                 type_name = GetType ().Name;
862                                 trace.Write ("control", String.Format ("OnBubbleEvent {0} {1}", _userId, type_name));
863                         }
864 #endif
865                         return false;
866                 }
867
868                 protected virtual void OnDataBinding (EventArgs e)
869                 {
870                         if ((event_mask & databinding_mask) != 0) {
871                                 EventHandler eh = (EventHandler)(_events [DataBindingEvent]);
872                                 if (eh != null) {
873 #if MONO_TRACE
874                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
875                                         string type_name = null;
876                                         if (trace != null) {
877                                                 type_name = GetType ().Name;
878                                                 trace.Write ("control", String.Format ("OnDataBinding {0} {1}", _userId, type_name));
879                                         }
880 #endif
881                                         eh (this, e);
882                                 }
883                         }
884                 }
885
886 #if NET_2_0
887                 protected internal
888 #else           
889                 protected
890 #endif          
891                 virtual void OnInit (EventArgs e)
892                 {
893                         if ((event_mask & init_mask) != 0) {
894                                 EventHandler eh = (EventHandler)(_events [InitEvent]);
895                                 if (eh != null) {
896 #if MONO_TRACE
897                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
898                                         string type_name = null;
899                                         if (trace != null) {
900                                                 type_name = GetType ().Name;
901                                                 trace.Write ("control", String.Format ("OnInit {0} {1}", _userId, type_name));
902                                         }
903 #endif
904                                         eh (this, e);
905                                 }
906                         }
907                 }
908
909 #if NET_2_0
910                 protected internal
911 #else
912                 protected
913 #endif          
914                 virtual void OnLoad (EventArgs e)
915                 {
916                         if ((event_mask & load_mask) != 0) {
917                                 EventHandler eh = (EventHandler)(_events [LoadEvent]);
918                                 if (eh != null) {
919 #if MONO_TRACE
920                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
921                                         string type_name = null;
922                                         if (trace != null) {
923                                                 type_name = GetType ().Name;
924                                                 trace.Write ("control", String.Format ("OnLoad {0} {1}", _userId, type_name));
925                                         }
926 #endif
927                                         eh (this, e);
928                                 }
929                         }
930                 }
931
932 #if NET_2_0
933                 protected internal
934 #else
935                 protected
936 #endif
937                 virtual void OnPreRender (EventArgs e)
938                 {
939                         if ((event_mask & prerender_mask) != 0) {
940                                 EventHandler eh = (EventHandler)(_events [PreRenderEvent]);
941                                 if (eh != null) {
942 #if MONO_TRACE
943                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
944                                         string type_name = null;
945                                         if (trace != null) {
946                                                 type_name = GetType ().Name;
947                                                 trace.Write ("control", String.Format ("OnPreRender {0} {1}", _userId, type_name));
948                                         }
949 #endif
950                                         eh (this, e);
951                                 }
952                         }
953                 }
954
955 #if NET_2_0
956                 protected internal
957 #else
958                 protected
959 #endif
960                 virtual void OnUnload(EventArgs e)
961                 {
962                         if ((event_mask & unload_mask) != 0) {
963                                 EventHandler eh = (EventHandler)(_events [UnloadEvent]);
964                                 if (eh != null) {
965 #if MONO_TRACE
966                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
967                                         string type_name = null;
968                                         if (trace != null) {
969                                                 type_name = GetType ().Name;
970                                                 trace.Write ("control", String.Format ("OnUnload {0} {1}", _userId, type_name));
971                                         }
972 #endif
973                                         eh (this, e);
974                                 }
975                         }
976                 }
977
978 #if NET_2_0
979                 protected internal Stream OpenFile (string path)
980                 {
981                         try {
982                                 string filePath = Context.Server.MapPath (path);
983                                 return File.OpenRead (filePath);
984                         }
985                         catch (UnauthorizedAccessException) {
986                                 throw new HttpException ("Access to the specified file was denied.");
987                         }
988                 }
989
990                 internal string GetPhysicalFilePath (string virtualPath)
991                 {
992                         Page page = Page;
993                         
994                         if (VirtualPathUtility.IsAbsolute (virtualPath))
995                                 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
996
997                         // We need to determine whether one of our parents is a
998                         // master page. If so, we need to map the path
999                         // relatively to the master page and not our containing
1000                         // page/control. This is necessary for cases when a
1001                         // relative path is used in a control placed in a master
1002                         // page and the master page is referenced from a
1003                         // location other than its own. In such cases MS.NET looks
1004                         // for the file in the directory where the master page
1005                         // is.
1006                         //
1007                         // An example of where it is needed is at
1008                         //
1009                         // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
1010                         //
1011                         MasterPage master = null;
1012                         Control ctrl = Parent;
1013
1014                         while (ctrl != null) {
1015                                 if (ctrl is MasterPage) {
1016                                         master = ctrl as MasterPage;
1017                                         break;
1018                                 }
1019                                 ctrl = ctrl.Parent;
1020                         }
1021                         
1022                         string path;
1023                         if (master != null)
1024                                 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory, virtualPath);
1025                         else
1026                                 path = VirtualPathUtility.Combine (TemplateSourceDirectory, virtualPath);
1027                         return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1028                 }
1029 #endif          
1030
1031                 protected void RaiseBubbleEvent(object source, EventArgs args)
1032                 {
1033                         Control c = Parent;
1034                         while (c != null) {
1035 #if MONO_TRACE
1036                                 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1037                                 string type_name = null;
1038                                 if (trace != null) {
1039                                         type_name = GetType ().Name;
1040                                         trace.Write ("control", String.Format ("RaiseBubbleEvent {0} {1}", _userId, type_name));
1041                                 }
1042 #endif
1043                                 if (c.OnBubbleEvent (source, args)) {
1044 #if MONO_TRACE
1045                                         if (trace != null)
1046                                                 trace.Write ("control", String.Format ("End RaiseBubbleEvent (false) {0} {1}", _userId, type_name));
1047 #endif
1048                                         break;
1049                                 }
1050 #if MONO_TRACE
1051                                 if (trace != null)
1052                                         trace.Write ("control", String.Format ("End RaiseBubbleEvent (true) {0} {1}", _userId, type_name));
1053 #endif
1054                                 c = c.Parent;
1055                         }
1056                 }
1057
1058 #if NET_2_0
1059                 protected internal
1060 #else
1061                 protected
1062 #endif
1063                 virtual void Render(HtmlTextWriter writer) //DIT
1064                 {
1065                         RenderChildren(writer);
1066                 }
1067
1068 #if NET_2_0
1069                 protected internal
1070 #else
1071                 protected
1072 #endif
1073                 virtual void RenderChildren (HtmlTextWriter writer) //DIT
1074                 {
1075                         if (_renderMethodDelegate != null) {
1076                                 _renderMethodDelegate (writer, this);
1077                         } else if (_controls != null) {
1078                                 int len = _controls.Count;
1079                                 for (int i = 0; i < len; i++) {
1080                                         Control c = _controls [i];
1081 #if NET_2_0
1082                                         if (c.Adapter != null)
1083                                                 c.RenderControl (writer, c.Adapter);
1084                                         else
1085 #endif
1086                                                 c.RenderControl (writer);
1087                                 }
1088                         }
1089                 }
1090
1091 #if NET_2_0
1092                 protected virtual ControlAdapter ResolveAdapter ()
1093                 {
1094                         throw new NotImplementedException ();
1095                 }
1096 #endif          
1097
1098                 protected virtual object SaveViewState ()
1099                 {
1100                         if ((stateMask & VISIBLE_CHANGED) != 0) {
1101                                 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1102                         } else if (_viewState == null) {
1103                                 return null;
1104                         }
1105
1106                         return _viewState.SaveViewState ();
1107                 }
1108
1109                 protected virtual void TrackViewState()
1110                 {
1111                         if (_viewState != null)
1112                                 _viewState.TrackViewState ();
1113
1114                         stateMask |= TRACK_VIEWSTATE;
1115                 }
1116
1117                 public virtual void Dispose ()
1118                 {
1119                         if ((event_mask & disposed_mask) != 0) {
1120                                 EventHandler eh = (EventHandler)(_events [DisposedEvent]);
1121                                 if (eh != null) eh (this, EventArgs.Empty);
1122                         }
1123                 }
1124
1125                 [WebCategory ("FIXME")]
1126                 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1127                 public event EventHandler DataBinding {
1128                         add {
1129                                 event_mask |= databinding_mask;
1130                                 Events.AddHandler (DataBindingEvent, value);
1131                         }
1132                         remove { Events.RemoveHandler (DataBindingEvent, value); }
1133                 }
1134
1135                 [WebSysDescription ("Raised when the contol is disposed.")]
1136                 public event EventHandler Disposed {
1137                         add {
1138                                 event_mask |= disposed_mask;
1139                                 Events.AddHandler (DisposedEvent, value);
1140                         }
1141                         remove { Events.RemoveHandler (DisposedEvent, value); }
1142                 }
1143
1144                 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1145                 public event EventHandler Init {
1146                         add {
1147                                 event_mask |= init_mask;
1148                                 Events.AddHandler (InitEvent, value);
1149                         }
1150                         remove { Events.RemoveHandler (InitEvent, value); }
1151                 }
1152
1153                 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1154                 public event EventHandler Load {
1155                         add {
1156                                 event_mask |= load_mask;
1157                                 Events.AddHandler (LoadEvent, value);
1158                         }
1159                         remove { Events.RemoveHandler (LoadEvent, value); }
1160                 }
1161
1162                 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1163                 public event EventHandler PreRender {
1164                         add {
1165                                 event_mask |= prerender_mask;
1166                                 Events.AddHandler (PreRenderEvent, value);
1167                         }
1168                         remove { Events.RemoveHandler (PreRenderEvent, value); }
1169                 }
1170
1171                 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1172                 public event EventHandler Unload {
1173                         add {
1174                                 event_mask |= unload_mask;
1175                                 Events.AddHandler (UnloadEvent, value);
1176                         }
1177                         remove { Events.RemoveHandler (UnloadEvent, value); }
1178                 }
1179
1180                 public virtual void DataBind() //DIT
1181                 {
1182                         #if NET_2_0
1183                         DataBind (true);
1184                         #else
1185                         OnDataBinding (EventArgs.Empty);
1186                         DataBindChildren();
1187                         #endif
1188                 }
1189
1190                 #if NET_2_0
1191                 protected virtual
1192                 #endif
1193                 
1194                 void DataBindChildren ()
1195                 {
1196                         if (!HasControls ())
1197                                 return;
1198                         
1199                         int len = _controls.Count;
1200                         for (int i = 0; i < len; i++) {
1201                                 Control c = _controls [i];
1202                                 c.DataBind ();
1203                         }
1204                 }
1205
1206
1207                 public virtual bool HasControls ()
1208                 {
1209                         return (_controls != null && _controls.Count > 0);
1210                 }
1211
1212 #if NET_2_0
1213                 public virtual
1214 #else
1215                 public
1216 #endif
1217                 void RenderControl (HtmlTextWriter writer)
1218                 {
1219                         if ((stateMask & VISIBLE) != 0) {
1220                                 HttpContext ctx = Context;
1221                                 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1222                                 int pos = 0;
1223                                 if ((trace != null) && trace.IsEnabled)
1224                                         pos = ctx.Response.GetOutputByteCount ();
1225
1226                                 Render(writer);
1227                                 if ((trace != null) && trace.IsEnabled) {
1228                                         int size = ctx.Response.GetOutputByteCount () - pos;
1229                                         trace.SaveSize (this, size >= 0 ? size : 0);
1230                                 }
1231                         }
1232                 }
1233
1234 #if NET_2_0
1235                 protected void RenderControl (HtmlTextWriter writer,
1236                                               ControlAdapter adapter)
1237                 {
1238                         if ((stateMask & VISIBLE) != 0) {
1239                                 adapter.BeginRender (writer);
1240                                 adapter.Render (writer);
1241                                 adapter.EndRender (writer);
1242                         }
1243                 }
1244 #endif          
1245
1246                 public string ResolveUrl (string relativeUrl)
1247                 {
1248                         if (relativeUrl == null)
1249                                 throw new ArgumentNullException ("relativeUrl");
1250
1251                         if (relativeUrl == "")
1252                                 return "";
1253
1254                         if (relativeUrl [0] == '#')
1255                                 return relativeUrl;
1256                         
1257                         string ts = TemplateSourceDirectory;
1258                         if (ts == null || ts.Length == 0 ||
1259                                 Context == null || Context.Response == null ||
1260                                 !UrlUtils.IsRelativeUrl (relativeUrl))
1261                                 return relativeUrl;
1262
1263                         HttpResponse resp = Context.Response;
1264                         return resp.ApplyAppPathModifier (UrlUtils.Combine (ts, relativeUrl));
1265                 }
1266
1267
1268 #if NET_2_0             
1269                 public
1270 #else
1271                 internal
1272 #endif
1273                 string ResolveClientUrl (string relativeUrl)
1274                 {
1275 #if TARGET_J2EE
1276                         // There are no relative paths when rendering a J2EE portlet
1277                         if (Page != null && Page.PortletNamespace != null)
1278                                 return ResolveUrl (relativeUrl);
1279 #endif
1280                         if (relativeUrl == null)
1281                                 throw new ArgumentNullException ("relativeUrl");
1282
1283                         if (relativeUrl.Length == 0)
1284                                 return String.Empty;
1285
1286                         if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1287                                 return relativeUrl;
1288
1289                         HttpContext context = Context;
1290                         if (context != null && context.Request != null) {
1291                                 string basePath = context.Request.CurrentExecutionFilePath;
1292
1293                                 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1294                                         basePath = VirtualPathUtility.GetDirectory (basePath);
1295                                 
1296                                 if(VirtualPathUtility.IsAppRelative(relativeUrl))
1297                                         return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1298                                 
1299                                 string templateSourceDirectory = TemplateSourceDirectory;
1300                                 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1301                                         return relativeUrl;
1302                                 
1303                                 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1304                                 
1305                                 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1306                                         return relativeUrl;
1307                                 
1308                                 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1309                                 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1310                         }
1311                         return relativeUrl;
1312                 }
1313                 
1314                 internal bool HasRenderMethodDelegate () {
1315                         return _renderMethodDelegate != null;
1316                 }
1317
1318                 [EditorBrowsable (EditorBrowsableState.Advanced)]
1319                 public void SetRenderMethodDelegate(RenderMethod renderMethod) //DIT
1320                 {
1321                         _renderMethodDelegate = renderMethod;
1322                 }
1323
1324                 internal void LoadRecursive()
1325                 {
1326 #if MONO_TRACE
1327                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1328                         string type_name = null;
1329                         if (trace != null) {
1330                                 type_name = GetType ().Name;
1331                                 trace.Write ("control", String.Format ("LoadRecursive {0} {1}", _userId, type_name));
1332                         }
1333 #endif
1334 #if NET_2_0
1335                         if (Adapter != null)
1336                                 Adapter.OnLoad (EventArgs.Empty);
1337                         else
1338 #endif
1339                                 OnLoad (EventArgs.Empty);
1340                         if (HasControls ()) {
1341                                 int len = _controls.Count;
1342                                 for (int i=0;i<len;i++)
1343                                 {
1344                                         Control c = _controls[i];
1345                                         c.LoadRecursive ();
1346                                 }
1347                         }
1348
1349 #if MONO_TRACE
1350                         if (trace != null)
1351                                 trace.Write ("control", String.Format ("End LoadRecursive {0} {1}", _userId, type_name));
1352 #endif
1353                         stateMask |= LOADED;
1354                 }
1355
1356                 internal void UnloadRecursive(Boolean dispose)
1357                 {
1358 #if MONO_TRACE
1359                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1360                         string type_name = null;
1361                         if (trace != null) {
1362                                 type_name = GetType ().Name;
1363                                 trace.Write ("control", String.Format ("UnloadRecursive {0} {1}", _userId, type_name));
1364                         }
1365 #endif
1366                         if (HasControls ()) {
1367                                 int len = _controls.Count;
1368                                 for (int i=0;i<len;i++)
1369                                 {
1370                                         Control c = _controls[i];                                       
1371                                         c.UnloadRecursive (dispose);
1372                                 }
1373                         }
1374
1375 #if MONO_TRACE
1376                         if (trace != null)
1377                                 trace.Write ("control", String.Format ("End UnloadRecursive {0} {1}", _userId, type_name));
1378 #endif
1379 #if NET_2_0
1380                         if (Adapter != null)
1381                                 Adapter.OnUnload (EventArgs.Empty);
1382                         else
1383 #endif
1384                                 OnUnload (EventArgs.Empty);
1385                         if (dispose)
1386                                 Dispose();
1387                 }
1388
1389                 internal void PreRenderRecursiveInternal()
1390                 {
1391                         if ((stateMask & VISIBLE) != 0) {
1392                                 EnsureChildControls ();
1393 #if MONO_TRACE
1394                                 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1395                                 string type_name = null;
1396                                 if (trace != null) {
1397                                         type_name = GetType ().Name;
1398                                         trace.Write ("control", String.Format ("PreRenderRecursive {0} {1}", _userId, type_name));
1399                                 }
1400 #endif
1401 #if NET_2_0
1402                                 if (Adapter != null)
1403                                         Adapter.OnPreRender (EventArgs.Empty);
1404                                 else
1405 #endif
1406                                         OnPreRender (EventArgs.Empty);
1407                                 if (!HasControls ())
1408                                         return;
1409                                 
1410                                 int len = _controls.Count;
1411                                 for (int i=0;i<len;i++)
1412                                 {
1413                                         Control c = _controls[i];
1414                                         c.PreRenderRecursiveInternal ();
1415                                 }
1416 #if MONO_TRACE
1417                                 if (trace != null)
1418                                         trace.Write ("control", String.Format ("End PreRenderRecursive {0} {1}", _userId, type_name));
1419 #endif
1420                         }
1421                         stateMask |= PRERENDERED;
1422                 }
1423
1424                 internal void InitRecursive(Control namingContainer)
1425                 {
1426 #if MONO_TRACE
1427                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1428                         string type_name = null;
1429                         if (trace != null) {
1430                                 type_name = GetType ().Name;
1431                                 trace.Write ("control", String.Format ("InitRecursive {0} {1}", _userId, type_name));
1432                         }
1433 #endif
1434                         if (HasControls ()) {
1435                                 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1436                                         namingContainer = this;
1437
1438                                 if (namingContainer != null && 
1439                                     namingContainer._userId == null &&
1440                                     namingContainer.AutoID)
1441                                         namingContainer._userId = namingContainer.GetDefaultName () + "b";
1442
1443                                 int len = _controls.Count;
1444                                 for (int i=0;i<len;i++)
1445                                 {
1446                                         Control c = _controls[i];
1447                                         c._page = Page;
1448                                         c._namingContainer = namingContainer;
1449                                         if (namingContainer != null && c._userId == null && c.AutoID)
1450                                                 c._userId = namingContainer.GetDefaultName () + "c";
1451                                         c.InitRecursive (namingContainer);      
1452                                 }
1453                         }
1454
1455                         stateMask |= INITING;
1456 #if NET_2_0
1457                         ApplyTheme ();
1458                         
1459                         if (Adapter != null)
1460                                 Adapter.OnInit (EventArgs.Empty);
1461                         else
1462 #endif
1463                                 OnInit (EventArgs.Empty);
1464 #if MONO_TRACE
1465                         if (trace != null)
1466                                 trace.Write ("control", String.Format ("End InitRecursive {0} {1}", _userId, type_name));
1467 #endif
1468                         TrackViewState ();
1469                         stateMask |= INITED;
1470                         stateMask &= ~INITING;
1471                 }
1472
1473                 internal object SaveViewStateRecursive ()
1474                 {
1475                         if (!EnableViewState)
1476                                 return null;
1477
1478 #if MONO_TRACE
1479                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1480                         string type_name = null;
1481                         if (trace != null) {
1482                                 type_name = GetType ().Name;
1483                                 trace.Write ("control", String.Format ("SaveViewStateRecursive {0} {1}", _userId, type_name));
1484                         }
1485 #endif
1486
1487                         ArrayList controlList = null;
1488                         ArrayList controlStates = null;
1489
1490                         int idx = -1;
1491                         if (HasControls ())
1492                         {
1493                                 int len = _controls.Count;
1494                                 for (int i=0;i<len;i++)
1495                                 {
1496                                         Control ctrl = _controls[i];
1497                                         object ctrlState = ctrl.SaveViewStateRecursive ();
1498                                         idx++;
1499                                         if (ctrlState == null)
1500                                                 continue;
1501
1502                                         if (controlList == null) 
1503                                         {
1504                                                 controlList = new ArrayList ();
1505                                                 controlStates = new ArrayList ();
1506                                         }
1507
1508                                         controlList.Add (idx);
1509                                         controlStates.Add (ctrlState);
1510                                 }
1511                         }
1512
1513                         object thisState = SaveViewState ();
1514                         if (thisState == null && controlList == null && controlStates == null) {
1515 #if MONO_TRACE
1516                                 if (trace != null) {
1517                                         trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved nothing", _userId, type_name));
1518                                         trace.SaveViewState (this, null);
1519                                 }
1520 #endif
1521                                 return null;
1522                         }
1523
1524 #if MONO_TRACE
1525                         if (trace != null) {
1526                                 trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved a Triplet", _userId, type_name));
1527                                 trace.SaveViewState (this, thisState);
1528                         }
1529 #endif
1530                         return new Triplet (thisState, controlList, controlStates);
1531                 }
1532                 
1533                 internal void LoadViewStateRecursive (object savedState)
1534                 {
1535                         if (!EnableViewState || savedState == null)
1536                                 return;
1537
1538 #if MONO_TRACE
1539                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1540                         string type_name = null;
1541                         if (trace != null) {
1542                                 type_name = GetType ().Name;
1543                                 trace.Write ("control", String.Format ("LoadViewStateRecursive {0} {1}", _userId, type_name));
1544                         }
1545 #endif
1546                         Triplet savedInfo = (Triplet) savedState;
1547                         LoadViewState (savedInfo.First);
1548
1549                         ArrayList controlList = savedInfo.Second as ArrayList;
1550                         if (controlList == null)
1551                                 return;
1552                         ArrayList controlStates = savedInfo.Third as ArrayList;
1553                         int nControls = controlList.Count;
1554                         for (int i = 0; i < nControls; i++) {
1555                                 int k = (int) controlList [i];
1556                                 if (k < Controls.Count && controlStates != null) {
1557                                         Control c = Controls [k];
1558                                         c.LoadViewStateRecursive (controlStates [i]);
1559                                 } else {
1560                                         if (pendingVS == null)
1561                                                 pendingVS = new Hashtable ();
1562
1563                                         pendingVS [k] = controlStates [i];
1564                                 }
1565                         }
1566
1567 #if MONO_TRACE
1568                         if (trace != null)
1569                                 trace.Write ("control", String.Format ("End LoadViewStateRecursive {0} {1}", _userId, type_name));
1570 #endif
1571                         stateMask |= VIEWSTATE_LOADED;
1572                 }
1573
1574 #if NET_2_0
1575                 internal ControlSkin controlSkin;
1576
1577                 internal void ApplyTheme ()
1578                 {
1579 #if MONO_TRACE
1580                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1581                         string type_name = null;
1582                         if (trace != null) {
1583                                 type_name = GetType ().Name;
1584                                 trace.Write ("control", String.Format ("ApplyThemeRecursive {0} {1}", _userId, type_name));
1585                         }
1586 #endif
1587                         if (Page.PageTheme != null && EnableTheming) {
1588                                 ControlSkin controlSkin = Page.PageTheme.GetControlSkin (GetType (), SkinID);
1589                                 if (controlSkin != null)
1590                                         controlSkin.ApplySkin (this);
1591                         }
1592
1593 #if MONO_TRACE
1594                         if (trace != null)
1595                                 trace.Write ("control", String.Format ("End ApplyThemeRecursive {0} {1}", _userId, type_name));
1596 #endif
1597                 }
1598 #endif
1599                 
1600                 internal bool AutoID
1601                 {
1602                         get { return (stateMask & AUTOID) != 0; }
1603                         set {
1604                                 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1605                                         return;
1606
1607                                 SetMask (AUTOID, value);
1608                         }
1609                 }
1610
1611                 protected internal virtual void RemovedControl (Control control)
1612                 {
1613                         control.UnloadRecursive (false);
1614                         control._parent = null;
1615                         control._page = null;
1616                         control._namingContainer = null;
1617                 }
1618
1619
1620 #if NET_2_0
1621
1622                 string skinId = string.Empty;
1623                 bool _enableTheming = true;
1624                 
1625                 [Browsable (false)]
1626                 [Themeable (false)]
1627                 [DefaultValue (true)]
1628                 public virtual bool EnableTheming
1629                 {
1630                         get
1631                         {
1632                                 if ((stateMask & ENABLE_THEMING) != 0)
1633                                         return _enableTheming;
1634
1635                                 if (_parent != null)
1636                                         return _parent.EnableTheming;
1637
1638                                 return true;
1639                         }
1640                         set 
1641                         { 
1642                                 SetMask (ENABLE_THEMING, true);
1643                                 _enableTheming = value;
1644                         }
1645                 }
1646                 
1647                 [Browsable (false)]
1648                 [DefaultValue ("")]
1649                 [Filterable (false)]
1650                 public virtual string SkinID
1651                 {
1652                         get { return skinId; }
1653                         set { skinId = value; }
1654                 }
1655
1656                 ControlBuilder IControlBuilderAccessor.ControlBuilder { 
1657                         get {throw new NotImplementedException (); }
1658                 }
1659
1660                 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1661                 {
1662                         throw new NotImplementedException ();               
1663                 }
1664
1665                 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1666                 {
1667                         SetDesignModeState (designData);
1668                 }
1669         
1670                 void IControlDesignerAccessor.SetOwnerControl (Control control)
1671                 {
1672                         throw new NotImplementedException ();               
1673                 }
1674                 
1675                 IDictionary IControlDesignerAccessor.UserData { 
1676                         get { throw new NotImplementedException (); }
1677                 }
1678        
1679                 ExpressionBindingCollection expressionBindings;
1680
1681                 ExpressionBindingCollection IExpressionsAccessor.Expressions { 
1682                         get { 
1683                                 if (expressionBindings == null)
1684                                         expressionBindings = new ExpressionBindingCollection ();
1685                                 return expressionBindings;
1686                         } 
1687                 }
1688                 
1689                 bool IExpressionsAccessor.HasExpressions { 
1690                         get {
1691                                 return (expressionBindings != null && expressionBindings.Count > 0);
1692                         }
1693                 }
1694
1695                 public virtual void Focus()
1696                 {
1697                         Page.SetFocus (this);
1698                 }
1699                 
1700                 protected internal virtual void LoadControlState (object state)
1701                 {
1702                 }
1703                 
1704                 protected internal virtual object SaveControlState ()
1705                 {
1706                         return null;
1707                 }
1708                 
1709                 protected virtual void DataBind (bool raiseOnDataBinding)
1710                 {
1711                         bool foundDataItem = false;
1712                         
1713                         if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1714                                 object o = DataBinder.GetDataItem (this, out foundDataItem);
1715                                 if (foundDataItem)
1716                                         Page.PushDataItemContext (o);
1717                         }
1718                         
1719                         try {
1720                                 
1721                                 if (raiseOnDataBinding)
1722                                         OnDataBinding (EventArgs.Empty);
1723                                 DataBindChildren();
1724                         
1725                         } finally {
1726                                 if (foundDataItem)
1727                                         Page.PopDataItemContext ();
1728                         }
1729                 }
1730                 
1731                 protected virtual IDictionary GetDesignModeState ()
1732                 {
1733                         throw new NotImplementedException ();               
1734                 }
1735                 
1736                 protected virtual void SetDesignModeState (IDictionary data)
1737                 {
1738                         throw new NotImplementedException ();               
1739                 }
1740 #endif
1741                 void IParserAccessor.AddParsedSubObject (object obj) {
1742                         this.AddParsedSubObject (obj);
1743                 }
1744
1745                 DataBindingCollection IDataBindingsAccessor.DataBindings {
1746                         get {
1747                                 if (dataBindings == null) {
1748                                         dataBindings = new DataBindingCollection ();
1749                                 }
1750                                 return dataBindings;
1751                         }
1752                 }
1753
1754                 bool IDataBindingsAccessor.HasDataBindings {
1755                         get {
1756                                 if (dataBindings != null && dataBindings.Count > 0) {
1757                                         return true;
1758                                 }
1759                                 return false;
1760                         }
1761                 }
1762         }
1763 }