Switch to compiler-tester
[mono.git] / mcs / class / System.Web / System.Web.UI / Page.cs
index 7010cadd01d7c87df45eae8599cc53b8250c7ec4..8f5efede3efd0d31f0884692e7568d8eb98d9042 100755 (executable)
@@ -46,14 +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
 {
 
+#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;
@@ -77,7 +82,7 @@ public class Page : TemplateControl, IHttpHandler
        string viewStateUserKey;
        NameValueCollection _requestValueCollection;
        string clientTarget;
-       ClientScriptManager scriptManager = new ClientScriptManager ();
+       ClientScriptManager scriptManager;
 
        [EditorBrowsable (EditorBrowsableState.Never)]
        protected const string postEventArgumentID = "__EVENTARGUMENT";
@@ -85,20 +90,26 @@ public class Page : TemplateControl, IHttpHandler
        protected const string postEventSourceID = "__EVENTTARGET";
 
 #if NET_2_0
-       private const string callbackArgumentID = "__CALLBACKARGUMENT";
-       private const string callbackSourceID = "__CALLBACKTARGET";
+       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;
        }
 
@@ -114,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)]
@@ -132,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.")]
@@ -146,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
        {
@@ -168,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
@@ -180,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
        {
@@ -200,6 +266,9 @@ public class Page : TemplateControl, IHttpHandler
                }
        }
 
+#if NET_2_0
+       [Obsolete]
+#endif
        [EditorBrowsable (EditorBrowsableState.Never)]
        protected ArrayList FileDependencies
        {
@@ -238,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)]
@@ -257,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)]
@@ -285,6 +373,9 @@ public class Page : TemplateControl, IHttpHandler
                }
        }
 
+#if NET_2_0
+    [FilterableAttribute (false)]
+#endif
        [Browsable (false)]
        public bool SmartNavigation
        {
@@ -300,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)]
@@ -407,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 ()
@@ -663,8 +803,8 @@ public class Page : TemplateControl, IHttpHandler
                                        list1.Add (id);
                                }
                        }
-                       _requiresPostBack = list1;
                }
+               _requiresPostBack = list1;
        }
 
        [EditorBrowsable (EditorBrowsableState.Never)]
@@ -689,19 +829,39 @@ 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 ();
@@ -717,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) {
@@ -732,6 +899,8 @@ public class Page : TemplateControl, IHttpHandler
                }
                
 #if NET_2_0
+               OnLoadComplete (EventArgs.Empty);
+
                if (IsCallback) {
                        string result = ProcessCallbackData ();
                        HtmlTextWriter callbackOutput = new HtmlTextWriter (_context.Response.Output);
@@ -744,11 +913,19 @@ public class Page : TemplateControl, IHttpHandler
                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);
@@ -818,9 +995,8 @@ public class Page : TemplateControl, IHttpHandler
        
 #if NET_2_0
        [Obsolete]
-#else
-       [EditorBrowsable (EditorBrowsableState.Advanced)]
 #endif
+       [EditorBrowsable (EditorBrowsableState.Advanced)]
        public void RegisterArrayDeclaration (string arrayName, string arrayValue)
        {
                scriptManager.RegisterArrayDeclaration (arrayName, arrayValue);
@@ -828,9 +1004,8 @@ public class Page : TemplateControl, IHttpHandler
 
 #if NET_2_0
        [Obsolete]
-#else
-       [EditorBrowsable (EditorBrowsableState.Advanced)]
 #endif
+       [EditorBrowsable (EditorBrowsableState.Advanced)]
        public virtual void RegisterClientScriptBlock (string key, string script)
        {
                scriptManager.RegisterClientScriptBlock (key, script);
@@ -838,9 +1013,8 @@ public class Page : TemplateControl, IHttpHandler
 
 #if NET_2_0
        [Obsolete]
-#else
-       [EditorBrowsable (EditorBrowsableState.Advanced)]
 #endif
+       [EditorBrowsable (EditorBrowsableState.Advanced)]
        public virtual void RegisterHiddenField (string hiddenFieldName, string hiddenFieldInitialValue)
        {
                scriptManager.RegisterHiddenField (hiddenFieldName, hiddenFieldInitialValue);
@@ -854,9 +1028,8 @@ public class Page : TemplateControl, IHttpHandler
 
 #if NET_2_0
        [Obsolete]
-#else
-       [EditorBrowsable (EditorBrowsableState.Advanced)]
 #endif
+       [EditorBrowsable (EditorBrowsableState.Advanced)]
        public void RegisterOnSubmitStatement (string key, string script)
        {
                scriptManager.RegisterOnSubmitStatement (key, script);
@@ -879,9 +1052,8 @@ public class Page : TemplateControl, IHttpHandler
 
 #if NET_2_0
        [Obsolete]
-#else
-       [EditorBrowsable (EditorBrowsableState.Advanced)]
 #endif
+       [EditorBrowsable (EditorBrowsableState.Advanced)]
        public virtual void RegisterStartupScript (string key, string script)
        {
                scriptManager.RegisterStartupScript (key, script);
@@ -925,9 +1097,9 @@ public class Page : TemplateControl, IHttpHandler
                if (sState != null) {
 #if NET_2_0
                        Triplet data = (Triplet) sState;
+                       LoadPageControlState (data.Third);
                        LoadViewStateRecursive (data.First);
                        _requiresPostBack = data.Second as ArrayList;
-                       LoadPageControlState (data.Third);
 #else
                        Pair pair = (Pair) sState;
                        LoadViewStateRecursive (pair.First);
@@ -941,6 +1113,10 @@ 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;
 
@@ -948,7 +1124,7 @@ public class Page : TemplateControl, IHttpHandler
                Triplet triplet = new Triplet ();
                triplet.First = viewState;
                triplet.Second = reqPostback;
-               triplet.Third = SavePageControlState ();
+               triplet.Third = controlState;
 
                if (triplet.First == null && triplet.Second == null && triplet.Third == null)
                        triplet = null;
@@ -968,13 +1144,18 @@ public class Page : TemplateControl, IHttpHandler
 
        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;
@@ -1004,89 +1185,123 @@ public class Page : TemplateControl, IHttpHandler
        }
        
        #if NET_2_0
-       public string GetWebResourceUrl(Type type, string resourceName)
-       {
-               if (type == null)
-                       throw new ArgumentNullException ("type");
        
-               if (resourceName == null || resourceName.Length == 0)
-                       throw new ArgumentNullException ("type");
+       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 ();
        
-               return System.Web.Handlers.AssemblyResourceLoader.GetResourceUrl (type, resourceName); 
+       public event EventHandler InitComplete {
+               add { Events.AddHandler (InitCompleteEvent, value); }
+               remove { Events.RemoveHandler (InitCompleteEvent, value); }
        }
        
-       Stack dataItemCtx;
+       public event EventHandler LoadComplete {
+               add { Events.AddHandler (LoadCompleteEvent, value); }
+               remove { Events.RemoveHandler (LoadCompleteEvent, value); }
+       }
        
-       internal void PushDataItemContext (object o)
-       {
-               if (dataItemCtx == null)
-                       dataItemCtx = new Stack ();
-               
-               dataItemCtx.Push (o);
+       public event EventHandler PreInit {
+               add { Events.AddHandler (PreInitEvent, value); }
+               remove { Events.RemoveHandler (PreInitEvent, value); }
        }
        
-       internal void PopDataItemContext ()
-       {
-               if (dataItemCtx == null)
-                       throw new InvalidOperationException ();
-               
-               dataItemCtx.Pop ();
+       public event EventHandler PreLoad {
+               add { Events.AddHandler (PreLoadEvent, value); }
+               remove { Events.RemoveHandler (PreLoadEvent, value); }
        }
        
-       internal object CurrentDataItem {
-               get {
-                       if (dataItemCtx == null)
-                               throw new InvalidOperationException ("No data item");
-                       
-                       return dataItemCtx.Peek ();
-               }
+       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 object Eval (string expression)
+       protected virtual void OnInitComplete (EventArgs e)
        {
-               return DataBinder.Eval (CurrentDataItem, expression);
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [InitCompleteEvent]);
+                       if (eh != null) eh (this, e);
+               }
        }
        
-       protected object Eval (string expression, string format)
+       protected virtual void OnLoadComplete (EventArgs e)
        {
-               return DataBinder.Eval (CurrentDataItem, expression, format);
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [LoadCompleteEvent]);
+                       if (eh != null) eh (this, e);
+               }
        }
        
-       protected object XPath (string xpathexpression)
+       protected virtual void OnPreInit (EventArgs e)
        {
-               return XPathBinder.Eval (CurrentDataItem, xpathexpression);
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [PreInitEvent]);
+                       if (eh != null) eh (this, e);
+               }
        }
        
-       protected object XPath (string xpathexpression, string format)
+       protected virtual void OnPreLoad (EventArgs e)
        {
-               return XPathBinder.Eval (CurrentDataItem, xpathexpression, format);
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [PreLoadEvent]);
+                       if (eh != null) eh (this, e);
+               }
        }
        
-       protected IEnumerable XPathSelect (string xpathexpression)
+       protected virtual void OnPreRenderComplete (EventArgs e)
        {
-               return XPathBinder.Select (CurrentDataItem, xpathexpression);
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [PreRenderCompleteEvent]);
+                       if (eh != null) eh (this, e);
+               }
        }
        
-       public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context)
+       protected virtual void OnSaveStateComplete (EventArgs e)
        {
-               return GetCallbackEventReference (control, argument, clientCallback, context, null);
+               if (Events != null) {
+                       EventHandler eh = (EventHandler) (Events [SaveStateCompleteEvent]);
+                       if (eh != null) eh (this, e);
+               }
        }
        
-       public string GetCallbackEventReference (Control control, string argument, string clientCallback, string context, string clientErrorCallback)
+       public HtmlForm Form {
+               get { return _form; }
+       }
+       
+       internal void RegisterForm (HtmlForm form)
        {
-               if (!ClientScript.IsClientScriptIncludeRegistered (typeof(Page), "callback"))
-                       ClientScript.RegisterClientScriptInclude (typeof(Page), "callback", GetWebResourceUrl (typeof(Page), "callback.js"));
-               
-               return string.Format ("WebForm_DoCallback ('{0}', {1}, {2}, {3}, {4})", control.UniqueID, argument, clientCallback, context, clientErrorCallback);
+               _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; }
+               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];
+               string callbackTarget = _requestValueCollection [CallbackSourceID];
                if (callbackTarget == null || callbackTarget.Length == 0)
                        throw new HttpException ("Callback target not provided.");
 
@@ -1094,10 +1309,12 @@ public class Page : TemplateControl, IHttpHandler
                if (target == null)
                        throw new HttpException (string.Format ("Invalid callback target '{0}'.", callbackTarget));
 
-               string callbackArgument = _requestValueCollection [callbackArgumentID];
+               string callbackArgument = _requestValueCollection [CallbackArgumentID];
                return target.RaiseCallbackEvent (callbackArgument);
        }
-       
+
+    [BrowsableAttribute (false)]
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
        public IPageHeader Header {
                get { return htmlHeader; }
        }
@@ -1107,11 +1324,14 @@ public class Page : TemplateControl, IHttpHandler
                htmlHeader = header;
        }
        
+    [DefaultValueAttribute ("")]
        public string MasterPageFile {
                get { return masterPageFile; }
                set { masterPageFile = value; masterPage = null; }
        }
        
+    [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+    [BrowsableAttribute (false)]
        public MasterPage Master {
                get {
                        if (masterPage == null)
@@ -1120,12 +1340,53 @@ public class Page : TemplateControl, IHttpHandler
                }
        }
        
+       [EditorBrowsable (EditorBrowsableState.Advanced)]
        public void RegisterRequiresControlState (Control control)
        {
                if (requireStateControls == null) requireStateControls = new ArrayList ();
                requireStateControls.Add (control);
        }
        
+       public bool RequiresControlState (Control control)
+       {
+               if (requireStateControls == null) return false;
+               return requireStateControls.Contains (control);
+       }
+       
+       [EditorBrowsable (EditorBrowsableState.Advanced)]
+       public void UnregisterRequiresControlState (Control control)
+       {
+               if (requireStateControls != null)
+                       requireStateControls.Remove (control);
+       }
+       
+       public ValidatorCollection GetValidators (string validationGroup)
+       {
+               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;
+       }
+       
+       public virtual void Validate (string validationGroup)
+       {
+               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;
@@ -1145,12 +1406,33 @@ public class Page : TemplateControl, IHttpHandler
                if (requireStateControls == null) return;
 
                object[] state = (object[]) data;
-               for (int n=0; n<state.Length && n < requireStateControls.Count; n++) {
+               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 [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
 }
 }