Switch to compiler-tester
[mono.git] / mcs / class / System.Web / System.Web.UI / Page.cs
index 469a5bf85927a0e29d8552d0135972d12a7cb1fe..8f5efede3efd0d31f0884692e7568d8eb98d9042 100755 (executable)
 // (c) 2003 Novell, Inc. (http://www.novell.com)
 //
 
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System;
 using System.Collections;
 using System.Collections.Specialized;
@@ -25,15 +46,19 @@ using System.Web;
 using System.Web.Caching;
 using System.Web.SessionState;
 using System.Web.Util;
+#if NET_2_0
+using System.Web.UI.HtmlControls;
+#endif
 
 namespace System.Web.UI
 {
 
-[MonoTODO ("FIXME missing the IRootDesigner Attribute")]
+#if !NET_2_0
+[RootDesignerSerializer ("Microsoft.VSDesigner.WebForms.RootCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design, true)]
+#endif
 [DefaultEvent ("Load"), DesignerCategory ("ASPXCodeBehind")]
 [ToolboxItem (false)]
-[Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
-[RootDesignerSerializer ("Microsoft.VSDesigner.WebForms.RootCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design, true)]
+[Designer ("Microsoft.VSDesigner.WebForms.WebFormDesigner, " + Consts.AssemblyMicrosoft_VSDesigner, typeof (IRootDesigner))]
 public class Page : TemplateControl, IHttpHandler
 {
        private bool _viewState = true;
@@ -53,24 +78,38 @@ public class Page : TemplateControl, IHttpHandler
        private NameValueCollection secondPostData;
        private bool requiresPostBackScript;
        private bool postBackScriptRendered;
-       private Hashtable registeredArrayDeclares;
-       Hashtable clientScriptBlocks;
-       Hashtable startupScriptBlocks;
-       Hashtable hiddenFields;
-       internal Hashtable submitStatements;
        bool handleViewState;
        string viewStateUserKey;
        NameValueCollection _requestValueCollection;
        string clientTarget;
+       ClientScriptManager scriptManager;
 
        [EditorBrowsable (EditorBrowsableState.Never)]
        protected const string postEventArgumentID = "__EVENTARGUMENT";
        [EditorBrowsable (EditorBrowsableState.Never)]
        protected const string postEventSourceID = "__EVENTTARGET";
 
+#if NET_2_0
+       internal const string CallbackArgumentID = "__CALLBACKARGUMENT";
+       internal const string CallbackSourceID = "__CALLBACKTARGET";
+       internal const string PreviousPageID = "__PREVIOUSPAGE";
+       
+       IPageHeader htmlHeader;
+       
+       MasterPage masterPage;
+       string masterPageFile;
+       
+       Page previousPage;
+       bool isCrossPagePostBack;
+       ArrayList requireStateControls;
+       Hashtable _validatorsByGroup;
+       HtmlForm _form;
+#endif
+
        #region Constructor
        public Page ()
        {
+               scriptManager = new ClientScriptManager (this);
                Page = this;
        }
 
@@ -86,16 +125,34 @@ public class Page : TemplateControl, IHttpHandler
        }
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+       public bool AspCompatMode
+       {
+               get { return false; }
+               set { throw new NotImplementedException (); }
+       }
+#else
        protected bool AspCompatMode
        {
                set { throw new NotImplementedException (); }
        }
+#endif
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public bool Buffer
+       {
+               get { return Response.BufferOutput; }
+               set { Response.BufferOutput = value; }
+       }
+#else
        protected bool Buffer
        {
                set { Response.BufferOutput = value; }
        }
+#endif
 
        [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
        [Browsable (false)]
@@ -104,6 +161,9 @@ public class Page : TemplateControl, IHttpHandler
                get { return _context.Cache; }
        }
 
+#if NET_2_0
+    [EditorBrowsableAttribute (EditorBrowsableState.Advanced)]
+#endif
        [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
        [Browsable (false), DefaultValue ("")]
        [WebSysDescription ("Value do override the automatic browser detection and force the page to use the specified browser.")]
@@ -118,16 +178,36 @@ public class Page : TemplateControl, IHttpHandler
        }
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public int CodePage
+       {
+               get { return Response.ContentEncoding.CodePage; }
+               set { Response.ContentEncoding = Encoding.GetEncoding (value); }
+       }
+#else
        protected int CodePage
        {
                set { Response.ContentEncoding = Encoding.GetEncoding (value); }
        }
+#endif
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public string ContentType
+       {
+               get { return Response.ContentType; }
+               set { Response.ContentType = value; }
+       }
+#else
        protected string ContentType
        {
                set { Response.ContentType = value; }
        }
+#endif
 
        protected override HttpContext Context
        {
@@ -140,10 +220,20 @@ public class Page : TemplateControl, IHttpHandler
        }
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public string Culture
+       {
+               get { return Thread.CurrentThread.CurrentCulture.Name; }
+               set { Thread.CurrentThread.CurrentCulture = new CultureInfo (value); }
+       }
+#else
        protected string Culture
        {
                set { Thread.CurrentThread.CurrentCulture = new CultureInfo (value); }
        }
+#endif
 
        [Browsable (false)]
        public override bool EnableViewState
@@ -152,6 +242,10 @@ public class Page : TemplateControl, IHttpHandler
                set { _viewState = value; }
        }
 
+#if NET_2_0
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+#endif
        [EditorBrowsable (EditorBrowsableState.Never)]
        protected bool EnableViewStateMac
        {
@@ -172,6 +266,9 @@ public class Page : TemplateControl, IHttpHandler
                }
        }
 
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Never)]
        protected ArrayList FileDependencies
        {
@@ -193,7 +290,7 @@ public class Page : TemplateControl, IHttpHandler
        public bool IsPostBack
        {
                get {
-                       return (0 == String.Compare (Request.HttpMethod, "POST", true));
+                       return _requestValueCollection != null;
                }
        }
 
@@ -210,9 +307,18 @@ public class Page : TemplateControl, IHttpHandler
        }
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public int LCID {
+               get { return Thread.CurrentThread.CurrentCulture.LCID; }
+               set { Thread.CurrentThread.CurrentCulture = new CultureInfo (value); }
+       }
+#else
        protected int LCID {
                set { Thread.CurrentThread.CurrentCulture = new CultureInfo (value); }
        }
+#endif
 
        [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
        [Browsable (false)]
@@ -229,10 +335,20 @@ public class Page : TemplateControl, IHttpHandler
        }
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public string ResponseEncoding
+       {
+               get { return Response.ContentEncoding.WebName; }
+               set { Response.ContentEncoding = Encoding.GetEncoding (value); }
+       }
+#else
        protected string ResponseEncoding
        {
                set { Response.ContentEncoding = Encoding.GetEncoding (value); }
        }
+#endif
 
        [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
        [Browsable (false)]
@@ -257,6 +373,9 @@ public class Page : TemplateControl, IHttpHandler
                }
        }
 
+#if NET_2_0
+    [FilterableAttribute (false)]
+#endif
        [Browsable (false)]
        public bool SmartNavigation
        {
@@ -272,28 +391,66 @@ public class Page : TemplateControl, IHttpHandler
        }
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public bool TraceEnabled
+       {
+               get { return Trace.IsEnabled; }
+               set { Trace.IsEnabled = value; }
+       }
+#else
        protected bool TraceEnabled
        {
                set { Trace.IsEnabled = value; }
        }
+#endif
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public TraceMode TraceModeValue
+       {
+               get { return Trace.TraceMode; }
+               set { Trace.TraceMode = value; }
+       }
+#else
        protected TraceMode TraceModeValue
        {
                set { Trace.TraceMode = value; }
        }
+#endif
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+       public int TransactionMode
+       {
+               get { return _transactionMode; }
+               set { _transactionMode = value; }
+       }
+#else
        protected int TransactionMode
        {
                set { _transactionMode = value; }
        }
+#endif
 
        [EditorBrowsable (EditorBrowsableState.Never)]
+#if NET_2_0
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public string UICulture
+       {
+               get { return Thread.CurrentThread.CurrentUICulture.Name; }
+               set { Thread.CurrentThread.CurrentUICulture = new CultureInfo (value); }
+       }
+#else
        protected string UICulture
        {
                set { Thread.CurrentThread.CurrentUICulture = new CultureInfo (value); }
        }
+#endif
 
        [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
        [Browsable (false)]
@@ -368,7 +525,7 @@ public class Page : TemplateControl, IHttpHandler
                        return null;
 
                NameValueCollection coll = null;
-               if (IsPostBack)
+               if (0 == String.Compare (Request.HttpMethod, "POST", true))
                        coll =  req.Form;
                else 
                        coll = req.QueryString;
@@ -379,30 +536,41 @@ public class Page : TemplateControl, IHttpHandler
 
                return coll;
        }
-       
+
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public string GetPostBackClientEvent (Control control, string argument)
        {
-               return GetPostBackEventReference (control, argument);
+               return scriptManager.GetPostBackClientEvent (control, argument);
        }
 
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public string GetPostBackClientHyperlink (Control control, string argument)
        {
-               return "javascript:" + GetPostBackEventReference (control, argument);
+               return scriptManager.GetPostBackClientHyperlink (control, argument);
        }
 
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public string GetPostBackEventReference (Control control)
        {
-               return GetPostBackEventReference (control, "");
+               return scriptManager.GetPostBackEventReference (control);
        }
 
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public string GetPostBackEventReference (Control control, string argument)
        {
-               RequiresPostBackScript ();
-               return String.Format ("__doPostBack('{0}','{1}')", control.UniqueID, argument);
+               return scriptManager.GetPostBackEventReference (control, argument);
        }
 
        internal void RequiresPostBackScript ()
@@ -475,22 +643,24 @@ public class Page : TemplateControl, IHttpHandler
                cache.SetExpires (_context.Timestamp.AddSeconds (duration));
        }
 
+#if NET_2_0
+       [Obsolete]
+#else
        [EditorBrowsable (EditorBrowsableState.Advanced)]
+#endif
        public bool IsClientScriptBlockRegistered (string key)
        {
-               if (clientScriptBlocks == null)
-                       return false;
-
-               return clientScriptBlocks.ContainsKey (key);
+               return scriptManager.IsClientScriptBlockRegistered (key);
        }
 
+#if NET_2_0
+       [Obsolete]
+#else
        [EditorBrowsable (EditorBrowsableState.Advanced)]
+#endif
        public bool IsStartupScriptRegistered (string key)
        {
-               if (startupScriptBlocks == null)
-                       return false;
-
-               return startupScriptBlocks.ContainsKey (key);
+               return scriptManager.IsStartupScriptRegistered (key);
        }
 
        public string MapPath (string virtualPath)
@@ -505,38 +675,21 @@ public class Page : TemplateControl, IHttpHandler
                writer.WriteLine ();
                writer.WriteLine ("<script language=\"javascript\">");
                writer.WriteLine ("<!--");
+
+               if (Request.Browser.Browser == ("Netscape") && Request.Browser.MajorVersion == 4)
+                       writer.WriteLine ("\tvar theForm = document.{0};", formUniqueID);
+               else
+                       writer.WriteLine ("\tvar theForm = document.getElementById ('{0}');", formUniqueID);
+
                writer.WriteLine ("\tfunction __doPostBack(eventTarget, eventArgument) {");
-               writer.WriteLine ("\t\tvar theform = document.getElementById ('{0}');", formUniqueID);
-               writer.WriteLine ("\t\ttheform.{0}.value = eventTarget;", postEventSourceID);
-               writer.WriteLine ("\t\ttheform.{0}.value = eventArgument;", postEventArgumentID);
-               writer.WriteLine ("\t\ttheform.submit();");
+               writer.WriteLine ("\t\ttheForm.{0}.value = eventTarget;", postEventSourceID);
+               writer.WriteLine ("\t\ttheForm.{0}.value = eventArgument;", postEventArgumentID);
+               writer.WriteLine ("\t\ttheForm.submit();");
                writer.WriteLine ("\t}");
                writer.WriteLine ("// -->");
                writer.WriteLine ("</script>");
        }
 
-       static void WriteScripts (HtmlTextWriter writer, Hashtable scripts)
-       {
-               if (scripts == null)
-                       return;
-
-               foreach (string key in scripts.Values)
-                       writer.WriteLine (key);
-       }
-       
-       void WriteHiddenFields (HtmlTextWriter writer)
-       {
-               if (hiddenFields == null)
-                       return;
-
-               foreach (string key in hiddenFields.Keys) {
-                       string value = hiddenFields [key] as string;
-                       writer.WriteLine ("\n<input type=\"hidden\" name=\"{0}\" value=\"{1}\" />", key, value);
-               }
-
-               hiddenFields = null;
-       }
-
        internal void OnFormRender (HtmlTextWriter writer, string formUniqueID)
        {
                if (renderingForm)
@@ -544,7 +697,7 @@ public class Page : TemplateControl, IHttpHandler
 
                renderingForm = true;
                writer.WriteLine ();
-               WriteHiddenFields (writer);
+               scriptManager.WriteHiddenFields (writer);
                if (requiresPostBackScript) {
                        RenderPostBackScript (writer, formUniqueID);
                        postBackScriptRendered = true;
@@ -556,11 +709,13 @@ public class Page : TemplateControl, IHttpHandler
                        writer.WriteLine ("value=\"{0}\" />", vs);
                }
 
-               WriteScripts (writer, clientScriptBlocks);
+               scriptManager.WriteClientScriptBlocks (writer);
        }
 
        internal string GetViewStateString ()
        {
+               if (_savedViewState == null)
+                       return null;
                StringWriter sr = new StringWriter ();
                LosFormatter fmt = new LosFormatter ();
                fmt.Serialize (sr, _savedViewState);
@@ -569,36 +724,14 @@ public class Page : TemplateControl, IHttpHandler
 
        internal void OnFormPostRender (HtmlTextWriter writer, string formUniqueID)
        {
-               if (registeredArrayDeclares != null) {
-                       writer.WriteLine();
-                       writer.WriteLine("<script language=\"javascript\">");
-                       writer.WriteLine("<!--");
-                       IDictionaryEnumerator arrayEnum = registeredArrayDeclares.GetEnumerator();
-                       while (arrayEnum.MoveNext()) {
-                               writer.Write("\tvar ");
-                               writer.Write(arrayEnum.Key);
-                               writer.Write(" =  new Array(");
-                               IEnumerator arrayListEnum = ((ArrayList) arrayEnum.Value).GetEnumerator();
-                               bool isFirst = true;
-                               while (arrayListEnum.MoveNext()) {
-                                       if (isFirst)
-                                               isFirst = false;
-                                       else
-                                               writer.Write(", ");
-                                       writer.Write(arrayListEnum.Current);
-                               }
-                               writer.WriteLine(");");
-                       }
-                       writer.WriteLine("// -->");
-                       writer.WriteLine("</script>");
-                       writer.WriteLine();
-               }
+               scriptManager.WriteArrayDeclares (writer);
 
                if (!postBackScriptRendered && requiresPostBackScript)
                        RenderPostBackScript (writer, formUniqueID);
 
-               WriteHiddenFields (writer);
-               WriteScripts (writer, startupScriptBlocks);
+               scriptManager.WriteHiddenFields (writer);
+               scriptManager.WriteClientScriptIncludes (writer);
+               scriptManager.WriteStartupScriptBlocks (writer);
                renderingForm = false;
                postBackScriptRendered = false;
        }
@@ -651,22 +784,27 @@ public class Page : TemplateControl, IHttpHandler
                        }
                }
 
+               ArrayList list1 = null;
                if (_requiresPostBackCopy != null && _requiresPostBackCopy.Count > 0) {
                        string [] handlers = (string []) _requiresPostBackCopy.ToArray (typeof (string));
                        foreach (string id in handlers) {
                                IPostBackDataHandler pbdh = FindControl (id) as IPostBackDataHandler;
-                               if (pbdh == null)
-                                       continue;
-                       
-                               _requiresPostBackCopy.Remove (id);
-                               if (pbdh.LoadPostData (id, data)) {
-                                       if (requiresPostDataChanged == null)
-                                               requiresPostDataChanged = new ArrayList ();
-
-                                       requiresPostDataChanged.Add (pbdh);
+                               if (pbdh != null) {                     
+                                       _requiresPostBackCopy.Remove (id);
+                                       if (pbdh.LoadPostData (id, data)) {
+                                               if (requiresPostDataChanged == null)
+                                                       requiresPostDataChanged = new ArrayList ();
+       
+                                               requiresPostDataChanged.Add (pbdh);
+                                       }
+                               } else if (second) {
+                                       if (list1 == null)
+                                               list1 = new ArrayList ();
+                                       list1.Add (id);
                                }
                        }
                }
+               _requiresPostBack = list1;
        }
 
        [EditorBrowsable (EditorBrowsableState.Never)]
@@ -691,18 +829,45 @@ public class Page : TemplateControl, IHttpHandler
                        try {
                                UnloadRecursive (true);
                        } catch {}
-                       Thread.CurrentThread.CurrentCulture = culture;
-                       Thread.CurrentThread.CurrentUICulture = uiculture;
+                       if (Thread.CurrentThread.CurrentCulture.Equals (culture) == false)
+                               Thread.CurrentThread.CurrentCulture = culture;
+
+                       if (Thread.CurrentThread.CurrentUICulture.Equals (uiculture) == false)
+                               Thread.CurrentThread.CurrentUICulture = uiculture;
                }
        }
+       
+#if NET_2_0
+       internal void ProcessCrossPagePostBack (HttpContext context)
+       {
+               isCrossPagePostBack = true;
+               ProcessRequest (context);
+       }
+#endif
 
        void InternalProcessRequest ()
        {
                _requestValueCollection = this.DeterminePostBackMode();
+
+#if NET_2_0
+               if (!IsCrossPagePostBack)
+                       LoadPreviousPageReference ();
+                       
+               OnPreInit (EventArgs.Empty);
+#endif
                Trace.Write ("aspx.page", "Begin Init");
                InitRecursive (null);
                Trace.Write ("aspx.page", "End Init");
-             
+
+#if NET_2_0
+               OnInitComplete (EventArgs.Empty);
+               
+               if (masterPageFile != null) {
+                       Controls.Add (Master);
+                       Master.FillPlaceHolders ();
+               }
+#endif
+                       
                renderingForm = false;  
                if (IsPostBack) {
                        Trace.Write ("aspx.page", "Begin LoadViewState");
@@ -712,6 +877,13 @@ public class Page : TemplateControl, IHttpHandler
                        ProcessPostData (_requestValueCollection, false);
                        Trace.Write ("aspx.page", "End ProcessPostData");
                }
+               
+#if NET_2_0
+               if (IsCrossPagePostBack)
+                       return;
+
+               OnPreLoad (EventArgs.Empty);
+#endif
 
                LoadRecursive ();
                if (IsPostBack) {
@@ -725,14 +897,35 @@ public class Page : TemplateControl, IHttpHandler
                        RaisePostBackEvents ();
                        Trace.Write ("aspx.page", "End Raise PostBackEvent");
                }
+               
+#if NET_2_0
+               OnLoadComplete (EventArgs.Empty);
+
+               if (IsCallback) {
+                       string result = ProcessCallbackData ();
+                       HtmlTextWriter callbackOutput = new HtmlTextWriter (_context.Response.Output);
+                       callbackOutput.Write (result);
+                       callbackOutput.Flush ();
+                       return;
+               }
+#endif
+               
                Trace.Write ("aspx.page", "Begin PreRender");
                PreRenderRecursiveInternal ();
                Trace.Write ("aspx.page", "End PreRender");
+               
+#if NET_2_0
+               OnPreRenderComplete (EventArgs.Empty);
+#endif
 
                Trace.Write ("aspx.page", "Begin SaveViewState");
                SavePageViewState ();
                Trace.Write ("aspx.page", "End SaveViewState");
                
+#if NET_2_0
+               OnSaveStateComplete (EventArgs.Empty);
+#endif
+               
                //--
                Trace.Write ("aspx.page", "Begin Render");
                HtmlTextWriter output = new HtmlTextWriter (_context.Response.Output);
@@ -740,19 +933,21 @@ public class Page : TemplateControl, IHttpHandler
                Trace.Write ("aspx.page", "End Render");
                
                RenderTrace (output);
-               _context = null;
        }
 
        private void RenderTrace (HtmlTextWriter output)
        {
-               TraceManager manager = HttpRuntime.TraceManager;
-               
-               if (!Trace.IsEnabled && !manager.Enabled)
+               TraceManager traceManager = HttpRuntime.TraceManager;
+
+               if (Trace.HaveTrace && !Trace.IsEnabled || !Trace.HaveTrace && !traceManager.Enabled)
                        return;
                
                Trace.SaveData ();
-               
-               if (Trace.IsEnabled || manager.PageOutput)
+
+               if (!Trace.HaveTrace && traceManager.Enabled && !traceManager.PageOutput) 
+                       return;
+
+               if (!traceManager.LocalOnly || Context.Request.IsLocal)
                        Trace.Render (output);
        }
        
@@ -798,38 +993,31 @@ public class Page : TemplateControl, IHttpHandler
                sourceControl.RaisePostBackEvent (eventArgument);
        }
        
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public void RegisterArrayDeclaration (string arrayName, string arrayValue)
        {
-               if (registeredArrayDeclares == null)
-                       registeredArrayDeclares = new Hashtable();
-
-               if (!registeredArrayDeclares.ContainsKey (arrayName))
-                       registeredArrayDeclares.Add (arrayName, new ArrayList());
-
-               ((ArrayList) registeredArrayDeclares[arrayName]).Add(arrayValue);
+               scriptManager.RegisterArrayDeclaration (arrayName, arrayValue);
        }
 
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public virtual void RegisterClientScriptBlock (string key, string script)
        {
-               if (IsClientScriptBlockRegistered (key))
-                       return;
-
-               if (clientScriptBlocks == null)
-                       clientScriptBlocks = new Hashtable ();
-
-               clientScriptBlocks.Add (key, script);
+               scriptManager.RegisterClientScriptBlock (key, script);
        }
 
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public virtual void RegisterHiddenField (string hiddenFieldName, string hiddenFieldInitialValue)
        {
-               if (hiddenFields == null)
-                       hiddenFields = new Hashtable ();
-
-               if (!hiddenFields.ContainsKey (hiddenFieldName))
-                       hiddenFields.Add (hiddenFieldName, hiddenFieldInitialValue);
+               scriptManager.RegisterHiddenField (hiddenFieldName, hiddenFieldInitialValue);
        }
 
        [MonoTODO("Used in HtmlForm")]
@@ -838,18 +1026,13 @@ public class Page : TemplateControl, IHttpHandler
                throw new NotImplementedException ();
        }
 
-
-       [MonoTODO]
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public void RegisterOnSubmitStatement (string key, string script)
        {
-               if (submitStatements == null)
-                       submitStatements = new Hashtable ();
-
-               if (submitStatements.ContainsKey (key))
-                       return;
-
-               submitStatements.Add (key, script);
+               scriptManager.RegisterOnSubmitStatement (key, script);
        }
 
        [EditorBrowsable (EditorBrowsableState.Advanced)]
@@ -867,16 +1050,13 @@ public class Page : TemplateControl, IHttpHandler
                requiresRaiseEvent = control;
        }
 
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public virtual void RegisterStartupScript (string key, string script)
        {
-               if (IsStartupScriptRegistered (key))
-                       return;
-
-               if (startupScriptBlocks == null)
-                       startupScriptBlocks = new Hashtable ();
-
-               startupScriptBlocks.Add (key, script);
+               scriptManager.RegisterStartupScript (key, script);
        }
 
        [EditorBrowsable (EditorBrowsableState.Advanced)]
@@ -915,9 +1095,16 @@ public class Page : TemplateControl, IHttpHandler
        {
                object sState = LoadPageStateFromPersistenceMedium ();
                if (sState != null) {
+#if NET_2_0
+                       Triplet data = (Triplet) sState;
+                       LoadPageControlState (data.Third);
+                       LoadViewStateRecursive (data.First);
+                       _requiresPostBack = data.Second as ArrayList;
+#else
                        Pair pair = (Pair) sState;
                        LoadViewStateRecursive (pair.First);
                        _requiresPostBack = pair.Second as ArrayList;
+#endif
                }
        }
 
@@ -926,26 +1113,49 @@ public class Page : TemplateControl, IHttpHandler
                if (!handleViewState)
                        return;
 
+#if NET_2_0
+               object controlState = SavePageControlState ();
+#endif
+
+               object viewState = SaveViewStateRecursive ();
+               object reqPostback = (_requiresPostBack != null && _requiresPostBack.Count > 0) ? _requiresPostBack : null;
+
+#if NET_2_0
+               Triplet triplet = new Triplet ();
+               triplet.First = viewState;
+               triplet.Second = reqPostback;
+               triplet.Third = controlState;
+
+               if (triplet.First == null && triplet.Second == null && triplet.Third == null)
+                       triplet = null;
+                       
+               SavePageStateToPersistenceMedium (triplet);
+#else
                Pair pair = new Pair ();
-               pair.First = SaveViewStateRecursive ();
-               if (_requiresPostBack != null && _requiresPostBack.Count > 0)
-                       pair.Second = _requiresPostBack;
+               pair.First = viewState;
+               pair.Second = reqPostback;
 
                if (pair.First == null && pair.Second == null)
                        pair = null;
-
+                       
                SavePageStateToPersistenceMedium (pair);
+#endif
        }
 
        public virtual void Validate ()
        {
-               if (_validators == null || _validators.Count == 0){
+               ValidateCollection (_validators);
+       }
+       
+       void ValidateCollection (ValidatorCollection validators)
+       {
+               if (validators == null || validators.Count == 0){
                        _isValid = true;
                        return;
                }
 
                bool all_valid = true;
-               foreach (IValidator v in _validators){
+               foreach (IValidator v in validators){
                        v.Validate ();
                        if (v.IsValid == false)
                                all_valid = false;
@@ -962,73 +1172,267 @@ public class Page : TemplateControl, IHttpHandler
                        throw new HttpException ("Control '" + control.ClientID + " " + control.GetType () + 
                                                 "' must be rendered within a HtmlForm");
        }
-
+       
        #endregion
        
        #if NET_2_0
-       public string GetWebResourceUrl(Type type, string resourceName)
+       public
+       #else
+       internal
+       #endif
+               ClientScriptManager ClientScript {
+               get { return scriptManager; }
+       }
+       
+       #if NET_2_0
+       
+       static readonly object InitCompleteEvent = new object ();
+       static readonly object LoadCompleteEvent = new object ();
+       static readonly object PreInitEvent = new object ();
+       static readonly object PreLoadEvent = new object ();
+       static readonly object PreRenderCompleteEvent = new object ();
+       static readonly object SaveStateCompleteEvent = new object ();
+       
+       public event EventHandler InitComplete {
+               add { Events.AddHandler (InitCompleteEvent, value); }
+               remove { Events.RemoveHandler (InitCompleteEvent, value); }
+       }
+       
+       public event EventHandler LoadComplete {
+               add { Events.AddHandler (LoadCompleteEvent, value); }
+               remove { Events.RemoveHandler (LoadCompleteEvent, value); }
+       }
+       
+       public event EventHandler PreInit {
+               add { Events.AddHandler (PreInitEvent, value); }
+               remove { Events.RemoveHandler (PreInitEvent, value); }
+       }
+       
+       public event EventHandler PreLoad {
+               add { Events.AddHandler (PreLoadEvent, value); }
+               remove { Events.RemoveHandler (PreLoadEvent, value); }
+       }
+       
+       public event EventHandler PreRenderComplete {
+               add { Events.AddHandler (PreRenderCompleteEvent, value); }
+               remove { Events.RemoveHandler (PreRenderCompleteEvent, value); }
+       }
+       
+       public event EventHandler SaveStateComplete {
+               add { Events.AddHandler (SaveStateCompleteEvent, value); }
+               remove { Events.RemoveHandler (SaveStateCompleteEvent, value); }
+       }
+       
+       protected virtual void OnInitComplete (EventArgs e)
        {
-               if (type == null)
-                       throw new ArgumentNullException ("type");
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [InitCompleteEvent]);
+                       if (eh != null) eh (this, e);
+               }
+       }
        
-               if (resourceName == null || resourceName.Length == 0)
-                       throw new ArgumentNullException ("type");
+       protected virtual void OnLoadComplete (EventArgs e)
+       {
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [LoadCompleteEvent]);
+                       if (eh != null) eh (this, e);
+               }
+       }
        
-               return System.Web.Handlers.AssemblyResourceLoader.GetResourceUrl (type, resourceName); 
+       protected virtual void OnPreInit (EventArgs e)
+       {
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [PreInitEvent]);
+                       if (eh != null) eh (this, e);
+               }
        }
        
-       Stack dataItemCtx;
+       protected virtual void OnPreLoad (EventArgs e)
+       {
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [PreLoadEvent]);
+                       if (eh != null) eh (this, e);
+               }
+       }
        
-       internal void PushDataItemContext (object o)
+       protected virtual void OnPreRenderComplete (EventArgs e)
        {
-               if (dataItemCtx == null)
-                       dataItemCtx = new Stack ();
-               
-               dataItemCtx.Push (o);
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [PreRenderCompleteEvent]);
+                       if (eh != null) eh (this, e);
+               }
        }
        
-       internal void PopDataItemContext ()
+       protected virtual void OnSaveStateComplete (EventArgs e)
        {
-               if (dataItemCtx == null)
-                       throw new InvalidOperationException ();
-               
-               dataItemCtx.Pop ();
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [SaveStateCompleteEvent]);
+                       if (eh != null) eh (this, e);
+               }
+       }
+       
+       public HtmlForm Form {
+               get { return _form; }
        }
        
-       internal object CurrentDataItem {
+       internal void RegisterForm (HtmlForm form)
+       {
+               _form = form;
+       }
+       
+    [BrowsableAttribute (false)]
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+       public Page PreviousPage {
+               get { return previousPage; }
+       }
+
+       
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public bool IsCallback {
+               get { return _requestValueCollection != null && _requestValueCollection [CallbackArgumentID] != null; }
+       }
+       
+    [BrowsableAttribute (false)]
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+       public bool IsCrossPagePostBack {
+               get { return _requestValueCollection != null && isCrossPagePostBack; }
+       }
+       
+       string ProcessCallbackData ()
+       {
+               string callbackTarget = _requestValueCollection [CallbackSourceID];
+               if (callbackTarget == null || callbackTarget.Length == 0)
+                       throw new HttpException ("Callback target not provided.");
+
+               ICallbackEventHandler target = FindControl (callbackTarget) as ICallbackEventHandler;
+               if (target == null)
+                       throw new HttpException (string.Format ("Invalid callback target '{0}'.", callbackTarget));
+
+               string callbackArgument = _requestValueCollection [CallbackArgumentID];
+               return target.RaiseCallbackEvent (callbackArgument);
+       }
+
+    [BrowsableAttribute (false)]
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+       public IPageHeader Header {
+               get { return htmlHeader; }
+       }
+       
+       internal void SetHeader (IPageHeader header)
+       {
+               htmlHeader = header;
+       }
+       
+    [DefaultValueAttribute ("")]
+       public string MasterPageFile {
+               get { return masterPageFile; }
+               set { masterPageFile = value; masterPage = null; }
+       }
+       
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
+       public MasterPage Master {
                get {
-                       if (dataItemCtx == null)
-                               throw new InvalidOperationException ("No data item");
-                       
-                       return dataItemCtx.Peek ();
+                       if (masterPage == null)
+                               masterPage = MasterPageParser.GetCompiledMasterInstance (masterPageFile, Server.MapPath (masterPageFile), Context);
+                       return masterPage;
                }
        }
        
-       protected object Eval (string expression)
+       [EditorBrowsable (EditorBrowsableState.Advanced)]
+       public void RegisterRequiresControlState (Control control)
        {
-               return DataBinder.Eval (CurrentDataItem, expression);
+               if (requireStateControls == null) requireStateControls = new ArrayList ();
+               requireStateControls.Add (control);
        }
        
-       protected object Eval (string expression, string format)
+       public bool RequiresControlState (Control control)
        {
-               return DataBinder.Eval (CurrentDataItem, expression, format);
+               if (requireStateControls == null) return false;
+               return requireStateControls.Contains (control);
        }
        
-       protected object XPath (string xpathexpression)
+       [EditorBrowsable (EditorBrowsableState.Advanced)]
+       public void UnregisterRequiresControlState (Control control)
        {
-               return XPathBinder.Eval (CurrentDataItem, xpathexpression);
+               if (requireStateControls != null)
+                       requireStateControls.Remove (control);
        }
        
-       protected object XPath (string xpathexpression, string format)
+       public ValidatorCollection GetValidators (string validationGroup)
        {
-               return XPathBinder.Eval (CurrentDataItem, xpathexpression, format);
+               if (validationGroup == null || validationGroup == "")
+                       return Validators;
+
+               if (_validatorsByGroup == null) _validatorsByGroup = new Hashtable ();
+               ValidatorCollection col = _validatorsByGroup [validationGroup] as ValidatorCollection;
+               if (col == null) {
+                       col = new ValidatorCollection ();
+                       _validatorsByGroup [validationGroup] = col;
+               }
+               return col;
        }
        
-       protected IEnumerable XPathSelect (string xpathexpression)
+       public virtual void Validate (string validationGroup)
        {
-               return XPathBinder.Select (CurrentDataItem, xpathexpression);
+               if (validationGroup == null || validationGroup == "")
+                       ValidateCollection (_validators);
+               else {
+                       if (_validatorsByGroup != null) {
+                               ValidateCollection (_validatorsByGroup [validationGroup] as ValidatorCollection);
+                       } else {
+                               _isValid = true;
+                       }
+               }
        }
        
+       object SavePageControlState ()
+       {
+               if (requireStateControls == null) return null;
+               object[] state = new object [requireStateControls.Count];
+               
+               bool allNull = true;
+               for (int n=0; n<state.Length; n++) {
+                       state [n] = ((Control) requireStateControls [n]).SaveControlState ();
+                       if (state [n] != null) allNull = false;
+               }
+               if (allNull) return null;
+               else return state;
+       }
+       
+       void LoadPageControlState (object data)
+       {
+               if (requireStateControls == null) return;
+
+               object[] state = (object[]) data;
+               int max = Math.Min (requireStateControls.Count, state != null ? state.Length : requireStateControls.Count);
+               for (int n=0; n < max; n++) {
+                       Control ctl = (Control) requireStateControls [n];
+                       ctl.LoadControlState (state != null ? state [n] : null);
+               }
+       }
+
+       void LoadPreviousPageReference ()
+       {
+               if (_requestValueCollection != null) {
+                       string prevPage = _requestValueCollection [PreviousPageID];
+                       if (prevPage != null) {
+                               previousPage = (Page) PageParser.GetCompiledPageInstance (prevPage, Server.MapPath (prevPage), Context);
+                               previousPage.ProcessCrossPagePostBack (_context);
+                       } else {
+                               previousPage = _context.LastPage;
+                       }
+               }
+               _context.LastPage = this;
+       }
+
+
+       protected internal void AddContentTemplate (string templateName, ITemplate template)
+       {
+               Master.AddContentTemplate (templateName, template);
+       }
+               
        #endif
 }
 }