2007-07-24 Igor Zelmanovich <igorz@mainsoft.com>
[mono.git] / mcs / class / System.Web / System.Web.UI / Page.cs
index cdbd22384df18fa2d164a73d10e5cca7bf4ed006..9714b9c35edcc3489eca8ae593160b9d567f12e1 100644 (file)
@@ -51,6 +51,8 @@ using System.Web.UI.HtmlControls;
 using System.Web.UI.WebControls;
 #if NET_2_0
 using System.Web.UI.Adapters;
+using System.Collections.Generic;
+using System.Reflection;
 #endif
 
 namespace System.Web.UI
@@ -70,12 +72,14 @@ namespace System.Web.UI
 #endif
 public partial class Page : TemplateControl, IHttpHandler
 {
+       static string machineKeyConfigPath = "system.web/machineKey";
 #if NET_2_0
        private PageLifeCycle _lifeCycle = PageLifeCycle.Unknown;
        private bool _eventValidation = true;
        private object [] _savedControlState;
        private bool _doLoadPreviousPage;
        string _focusedControlID;
+       bool _hasEnabledControlArray;
 #endif
        private bool _viewState = true;
        private bool _viewStateMac;
@@ -121,13 +125,15 @@ public partial class Page : TemplateControl, IHttpHandler
 #if NET_2_0
        const string ScrollPositionXID = "__SCROLLPOSITIONX";
        const string ScrollPositionYID = "__SCROLLPOSITIONY";
+       const string EnabledControlArrayID = "__enabledControlArray";
 #endif
 
 #if NET_2_0
+       internal const string LastFocusID = "__LASTFOCUS";
        internal const string CallbackArgumentID = "__CALLBACKARGUMENT";
        internal const string CallbackSourceID = "__CALLBACKTARGET";
        internal const string PreviousPageID = "__PREVIOUSPAGE";
-       
+
        HtmlHead htmlHeader;
        
        MasterPage masterPage;
@@ -147,6 +153,15 @@ public partial class Page : TemplateControl, IHttpHandler
        Hashtable items;
 
        bool _maintainScrollPositionOnPostBack;
+
+       private bool asyncMode = false;
+       private TimeSpan asyncTimeout;
+       private const double DefaultAsyncTimeout = 45.0;
+       private List<PageAsyncTask> parallelTasks;
+       private List<PageAsyncTask> serialTasks;
+
+       private ViewStateEncryptionMode viewStateEncryptionMode;
+       private bool controlRegisteredForViewStateEncryption = false;
 #endif
 
        #region Constructor
@@ -155,6 +170,16 @@ public partial class Page : TemplateControl, IHttpHandler
                scriptManager = new ClientScriptManager (this);
                Page = this;
                ID = "__Page";
+#if NET_2_0
+               PagesSection ps = WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
+               if (ps != null) {
+                       asyncTimeout = ps.AsyncTimeout;
+                       viewStateEncryptionMode = ps.ViewStateEncryptionMode;
+               } else {
+                       asyncTimeout = TimeSpan.FromSeconds (DefaultAsyncTimeout);
+                       viewStateEncryptionMode = ViewStateEncryptionMode.Auto;
+               }
+#endif
        }
 
        #endregion              
@@ -440,11 +465,15 @@ public partial class Page : TemplateControl, IHttpHandler
 #endif
 
 #if !TARGET_J2EE
-       internal string PostBackFunctionName {
+       internal string theForm {
                get {
-                       return "__doPostBack";
+                       return "theForm";
                }
        }
+       
+       internal bool IsMultiForm {
+               get { return false; }
+       }
 #endif
 
        [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
@@ -706,18 +735,22 @@ public partial class Page : TemplateControl, IHttpHandler
                if (culture == null)
                        return deflt;
                CultureInfo ret = null;
-               if (culture.StartsWith ("auto")) {
+               if (culture.StartsWith ("auto", StringComparison.InvariantCultureIgnoreCase)) {
+#if TARGET_J2EE
+                       if (Context.IsPortletRequest)
+                               return deflt;
+#endif
                        string[] languages = Request.UserLanguages;
                        try {
                                if (languages != null && languages.Length > 0)
-                                       ret = new CultureInfo (languages[0]);
+                                       ret = CultureInfo.CreateSpecificCulture (languages[0]);
                        } catch {
                        }
                        
                        if (ret == null)
                                ret = deflt;
                } else
-                       ret = new CultureInfo (culture);
+                       ret = CultureInfo.CreateSpecificCulture (culture);
 
                return ret;
        }
@@ -760,22 +793,21 @@ public partial class Page : TemplateControl, IHttpHandler
                        return null;
 
                NameValueCollection coll = null;
-               if (0 == String.Compare (Request.HttpMethod, "POST", true, CultureInfo.InvariantCulture)) {
-                       coll =  req.Form;
-                       WebROCollection c = (WebROCollection) coll;
-                       allow_load = !c.GotID;
-                       if (allow_load) {
-                               c.ID = GetTypeHashCode ();
-                       } else {
-                               allow_load = (c.ID == GetTypeHashCode ());
-                       }
-               } else  {
-                       coll = req.QueryString;
-               }
-
+               if (0 == String.Compare (Request.HttpMethod, "POST", true, CultureInfo.InvariantCulture))
+                       coll = req.Form;
 #if TARGET_J2EE
-               coll = LoadViewStateForPortlet((WebROCollection)coll);
+               else if (IsPortletRender && req.Form ["__VIEWSTATE"] != null)
+                       coll = req.Form;
 #endif
+               else
+                       coll = req.QueryString;
+
+               WebROCollection c = (WebROCollection) coll;
+               allow_load = !c.GotID;
+               if (allow_load)
+                       c.ID = GetTypeHashCode ();
+               else
+                       allow_load = (c.ID == GetTypeHashCode ());
 
                if (coll != null && coll ["__VIEWSTATE"] == null && coll ["__EVENTTARGET"] == null)
                        return null;
@@ -830,6 +862,12 @@ public partial class Page : TemplateControl, IHttpHandler
 
        internal void RequiresPostBackScript ()
        {
+#if NET_2_0
+               if (requiresPostBackScript)
+                       return;
+               ClientScript.RegisterHiddenField (postEventSourceID, String.Empty);
+               ClientScript.RegisterHiddenField (postEventArgumentID, String.Empty);
+#endif
                requiresPostBackScript = true;
        }
 
@@ -939,11 +977,7 @@ public partial class Page : TemplateControl, IHttpHandler
 #if NET_2_0
        protected internal override void Render (HtmlTextWriter writer) {
                if (MaintainScrollPositionOnPostBack) {
-                       RequiresPostBackScript ();
-
-                       string scriptUrl = ClientScript.GetWebResourceUrl (typeof (Page), "MaintainScrollPositionOnPostBack.js");
-
-                       ClientScript.RegisterClientScriptInclude (typeof (Page), "MaintainScrollPositionOnPostBack.js", scriptUrl);
+                       ClientScript.RegisterWebFormClientScript ();
 
                        ClientScript.RegisterHiddenField (ScrollPositionXID, Request [ScrollPositionXID]);
                        ClientScript.RegisterHiddenField (ScrollPositionYID, Request [ScrollPositionYID]);
@@ -951,13 +985,13 @@ public partial class Page : TemplateControl, IHttpHandler
                        StringBuilder script = new StringBuilder ();
                        script.AppendLine ("<script type=\"text/javascript\">");
                        script.AppendLine ("<!--");
-                       script.AppendLine ("theForm.oldSubmit = theForm.submit");
-                       script.AppendLine ("theForm.submit = WebForm_SaveScrollPositionSubmit");
-                       script.AppendLine ("theForm.oldOnSubmit = theForm.onsubmit");
-                       script.AppendLine ("theForm.onsubmit = WebForm_SaveScrollPositionOnSubmit");
+                       script.AppendLine (theForm + ".oldSubmit = " + theForm + ".submit;");
+                       script.AppendLine (theForm + ".submit = WebForm_SaveScrollPositionSubmit;");
+                       script.AppendLine (theForm + ".oldOnSubmit = " + theForm + ".onsubmit;");
+                       script.AppendLine (theForm + ".onsubmit = WebForm_SaveScrollPositionOnSubmit;");
                        if (IsPostBack) {
-                               script.AppendLine ("theForm.oldOnLoad = window.onload");
-                               script.AppendLine ("window.onload = WebForm_RestoreScrollPosition");
+                               script.AppendLine (theForm + ".oldOnLoad = window.onload;");
+                               script.AppendLine ("window.onload = function () { WebForm_RestoreScrollPosition (" + theForm + "); };");
                        }
                        script.AppendLine ("// -->");
                        script.AppendLine ("</script>");
@@ -970,22 +1004,46 @@ public partial class Page : TemplateControl, IHttpHandler
 
        private void RenderPostBackScript (HtmlTextWriter writer, string formUniqueID)
        {
+#if ONLY_1_1
                writer.WriteLine ("<input type=\"hidden\" name=\"{0}\" value=\"\" />", postEventSourceID);
                writer.WriteLine ("<input type=\"hidden\" name=\"{0}\" value=\"\" />", postEventArgumentID);
+#endif
                writer.WriteLine ();
-               writer.WriteLine ("<script language=\"javascript\">");
-               writer.WriteLine ("<!--");
+               
+               ClientScriptManager.WriteBeginScriptBlock (writer);
+
+#if ONLY_1_1
+               RenderClientScriptFormDeclaration (writer, formUniqueID);
+#endif
+               if (IsMultiForm) {
+                       writer.WriteLine ("{0}._form = {0};", theForm);
+                       writer.Write (theForm + ".");
+               }
+               else {
+                       writer.WriteLine ("window._form = {0};", theForm);
+               }
+               writer.WriteLine ("__doPostBack = function (eventTarget, eventArgument) {");
+#if NET_2_0
+               writer.WriteLine ("\tif(this._form.onsubmit && this._form.onsubmit() == false) return;");
+#else
+               writer.WriteLine ("\tif(document.ValidatorOnSubmit && !ValidatorOnSubmit()) return;");
+#endif
+               writer.WriteLine ("\tthis._form.{0}.value = eventTarget;", postEventSourceID);
+               writer.WriteLine ("\tthis._form.{0}.value = eventArgument;", postEventArgumentID);
+               writer.WriteLine ("\tthis._form.submit();");
+               writer.WriteLine ("}");
+               ClientScriptManager.WriteEndScriptBlock (writer);
+       }
 
-               writer.WriteLine ("\tvar theForm;\n\tif (document.getElementById) {{ theForm = document.getElementById ('{0}'); }}", formUniqueID);
-               writer.WriteLine ("\telse {{ theForm = document.{0}; }}", formUniqueID);
-               writer.WriteLine ("\tfunction " + PostBackFunctionName + "(eventTarget, eventArgument) {");
-               writer.WriteLine ("\t\tif(document.ValidatorOnSubmit && !ValidatorOnSubmit()) return;");
-               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>");
+       void RenderClientScriptFormDeclaration (HtmlTextWriter writer, string formUniqueID)
+       {
+               writer.WriteLine ("\tvar {0};\n\tif (document.getElementById) {{ {0} = document.getElementById ('{1}'); }}", theForm, formUniqueID);
+               writer.WriteLine ("\telse {{ {0} = document.{1}; }}", theForm, formUniqueID);
+               writer.WriteLine ("\t{0}._instanceVariableName = '{0}';", theForm);
+#if TARGET_J2EE
+               string serverUrl = Context.ServletResponse.encodeURL (Request.RawUrl);
+               writer.WriteLine ("\t{0}.serverURL = {1};", theForm, ClientScriptManager.GetScriptLiteral (serverUrl));
+#endif
        }
 
        internal void OnFormRender (HtmlTextWriter writer, string formUniqueID)
@@ -996,6 +1054,12 @@ public partial class Page : TemplateControl, IHttpHandler
                renderingForm = true;
                writer.WriteLine ();
 
+#if NET_2_0
+               ClientScriptManager.WriteBeginScriptBlock (writer);
+               RenderClientScriptFormDeclaration (writer, formUniqueID);
+               ClientScriptManager.WriteEndScriptBlock (writer);
+#endif
+
                if (handleViewState)
                        scriptManager.RegisterHiddenField ("__VIEWSTATE", _savedViewState);
 
@@ -1005,9 +1069,8 @@ public partial class Page : TemplateControl, IHttpHandler
                        postBackScriptRendered = true;
                }
 #if NET_2_0
-               scriptManager.RegisterWebFormClientScript ();
+               scriptManager.WriteWebFormClientScript (writer);
 #endif
-               scriptManager.WriteClientScriptIncludes (writer);
                scriptManager.WriteClientScriptBlocks (writer);
        }
 
@@ -1023,16 +1086,18 @@ public partial class Page : TemplateControl, IHttpHandler
 
        internal void OnFormPostRender (HtmlTextWriter writer, string formUniqueID)
        {
-               scriptManager.WriteArrayDeclares (writer);
-
-               if (!postBackScriptRendered && requiresPostBackScript)
-                       RenderPostBackScript (writer, formUniqueID);
-               
 #if NET_2_0
                scriptManager.SaveEventValidationState ();
                scriptManager.WriteExpandoAttributes (writer);
 #endif
                scriptManager.WriteHiddenFields (writer);
+               if (!postBackScriptRendered && requiresPostBackScript)
+                       RenderPostBackScript (writer, formUniqueID);
+#if NET_2_0
+               scriptManager.WriteWebFormClientScript (writer);
+#endif
+
+               scriptManager.WriteArrayDeclares (writer);
                scriptManager.WriteStartupScriptBlocks (writer);
                renderingForm = false;
                postBackScriptRendered = false;
@@ -1041,49 +1106,48 @@ public partial class Page : TemplateControl, IHttpHandler
        private void ProcessPostData (NameValueCollection data, bool second)
        {
                if (data != null) {
+                       Hashtable used = new Hashtable ();
+                       foreach (string id in data.AllKeys){
+                               if (id == "__VIEWSTATE" || id == postEventSourceID || id == postEventArgumentID)
+                                       continue;
 
-               Hashtable used = new Hashtable ();
-               foreach (string id in data.AllKeys){
-                       if (id == "__VIEWSTATE" || id == postEventSourceID || id == postEventArgumentID)
-                               continue;
-
-                       string real_id = id;
-                       int dot = real_id.IndexOf ('.');
-                       if (dot >= 1)
-                               real_id = real_id.Substring (0, dot);
+                               string real_id = id;
+                               int dot = real_id.IndexOf ('.');
+                               if (dot >= 1)
+                                       real_id = real_id.Substring (0, dot);
                        
-                       if (real_id == null || used.ContainsKey (real_id))
-                               continue;
+                               if (real_id == null || used.ContainsKey (real_id))
+                                       continue;
 
-                       used.Add (real_id, real_id);
+                               used.Add (real_id, real_id);
 
-                       Control ctrl = FindControl (real_id);
-                       if (ctrl != null){
-                               IPostBackDataHandler pbdh = ctrl as IPostBackDataHandler;
-                               IPostBackEventHandler pbeh = ctrl as IPostBackEventHandler;
+                               Control ctrl = FindControl (real_id);
+                               if (ctrl != null){
+                                       IPostBackDataHandler pbdh = ctrl as IPostBackDataHandler;
+                                       IPostBackEventHandler pbeh = ctrl as IPostBackEventHandler;
 
-                               if (pbdh == null) {
-                                       if (pbeh != null)
-                                               RegisterRequiresRaiseEvent (pbeh);
-                                       continue;
-                               }
+                                       if (pbdh == null) {
+                                               if (pbeh != null)
+                                                       RegisterRequiresRaiseEvent (pbeh);
+                                               continue;
+                                       }
                
-                               if (pbdh.LoadPostData (real_id, data) == true) {
-                                       if (requiresPostDataChanged == null)
-                                               requiresPostDataChanged = new ArrayList ();
-                                       requiresPostDataChanged.Add (pbdh);
-                               }
+                                       if (pbdh.LoadPostData (real_id, data) == true) {
+                                               if (requiresPostDataChanged == null)
+                                                       requiresPostDataChanged = new ArrayList ();
+                                               requiresPostDataChanged.Add (pbdh);
+                                       }
                                
-                               if (_requiresPostBackCopy != null)
-                                       _requiresPostBackCopy.Remove (real_id);
+                                       if (_requiresPostBackCopy != null)
+                                               _requiresPostBackCopy.Remove (real_id);
 
-                       } else if (!second) {
-                               if (secondPostData == null)
-                                       secondPostData = new NameValueCollection ();
-                               secondPostData.Add (real_id, data [id]);
+                               } else if (!second) {
+                                       if (secondPostData == null)
+                                               secondPostData = new NameValueCollection ();
+                                       secondPostData.Add (real_id, data [id]);
+                               }
                        }
                }
-               }
 
                ArrayList list1 = null;
                if (_requiresPostBackCopy != null && _requiresPostBackCopy.Count > 0) {
@@ -1111,7 +1175,7 @@ public partial class Page : TemplateControl, IHttpHandler
        }
 
        [EditorBrowsable (EditorBrowsableState.Never)]
-#if NET_2_0 || TARGET_JVM
+#if NET_2_0
        public virtual void ProcessRequest (HttpContext context)
 #else
        public void ProcessRequest (HttpContext context)
@@ -1165,6 +1229,65 @@ public partial class Page : TemplateControl, IHttpHandler
        }
        
 #if NET_2_0
+       delegate void ProcessRequestDelegate (HttpContext context);
+
+       private sealed class DummyAsyncResult : IAsyncResult
+       {
+               readonly object state;
+               readonly WaitHandle asyncWaitHandle;
+               readonly bool completedSynchronously;
+               readonly bool isCompleted;
+
+               public DummyAsyncResult (bool isCompleted, bool completedSynchronously, object state) 
+               {
+                       this.isCompleted = isCompleted;
+                       this.completedSynchronously = completedSynchronously;
+                       this.state = state;
+                       if (isCompleted) {
+                               asyncWaitHandle = new ManualResetEvent (true);
+                       }
+                       else {
+                               asyncWaitHandle = new ManualResetEvent (false);
+                       }
+               }
+
+               #region IAsyncResult Members
+
+               public object AsyncState {
+                       get { return state; }
+               }
+
+               public WaitHandle AsyncWaitHandle {
+                       get { return asyncWaitHandle; }
+               }
+
+               public bool CompletedSynchronously {
+                       get { return completedSynchronously; }
+               }
+
+               public bool IsCompleted {
+                       get { return isCompleted; }
+               }
+
+               #endregion
+       }
+
+       protected IAsyncResult AsyncPageBeginProcessRequest (HttpContext context, AsyncCallback callback, object extraData) 
+       {
+               ProcessRequest (context);
+               DummyAsyncResult asyncResult = new DummyAsyncResult (true, true, extraData);
+
+               if (callback != null) {
+                       callback (asyncResult);
+               }
+               
+               return asyncResult;
+       }
+
+       protected void AsyncPageEndProcessRequest (IAsyncResult result) 
+       {
+       }
+
        internal void ProcessCrossPagePostBack (HttpContext context)
        {
                isCrossPagePostBack = true;
@@ -1185,7 +1308,13 @@ public partial class Page : TemplateControl, IHttpHandler
                        }
                        else {
                                isCallback = _requestValueCollection [CallbackArgumentID] != null;
-                               isPostBack = !isCallback;
+                               // LAMESPEC: on Callback IsPostBack is set to false, but true.
+                               //isPostBack = !isCallback;
+                               isPostBack = true;
+                       }
+                       string lastFocus = _requestValueCollection [LastFocusID];
+                       if (!String.IsNullOrEmpty (lastFocus)) {
+                               _focusedControlID = UniqueID2ClientID (lastFocus);
                        }
                }
                
@@ -1222,6 +1351,9 @@ public partial class Page : TemplateControl, IHttpHandler
                        LoadPageViewState ();
                        Trace.Write ("aspx.page", "End LoadViewState");
                        Trace.Write ("aspx.page", "Begin ProcessPostData");
+#if TARGET_J2EE
+                       if (!IsGetBack)
+#endif
                        ProcessPostData (_requestValueCollection, false);
                        Trace.Write ("aspx.page", "End ProcessPostData");
                }
@@ -1233,6 +1365,9 @@ public partial class Page : TemplateControl, IHttpHandler
 
                LoadRecursive ();
 #if NET_2_0
+#if TARGET_J2EE
+               if (!IsGetBack)
+#endif
                if (IsPostBack || IsCallback) {
                        _lifeCycle = PageLifeCycle.ControlEvents;
 #else
@@ -1272,6 +1407,8 @@ public partial class Page : TemplateControl, IHttpHandler
                Trace.Write ("aspx.page", "End PreRender");
                
 #if NET_2_0
+               ExecuteRegisteredAsyncTasks ();
+
                _lifeCycle = PageLifeCycle.PreRenderComplete;
                OnPreRenderComplete (EventArgs.Empty);
 #endif
@@ -1283,15 +1420,15 @@ public partial class Page : TemplateControl, IHttpHandler
 #if NET_2_0
                _lifeCycle = PageLifeCycle.SaveStateComplete;
                OnSaveStateComplete (EventArgs.Empty);
-#endif
-
 #if TARGET_J2EE
-               if (SaveViewStateForNextPortletRender())
+               if (OnSaveStateCompleteForPortlet ())
                        return;
-#endif
+#endif // TARGET_J2EE
+#endif // NET_2_0
 
 #if NET_2_0
                _lifeCycle = PageLifeCycle.Render;
+               scriptManager.ResetEventValidationState ();
 #endif
                
                //--
@@ -1325,7 +1462,7 @@ public partial class Page : TemplateControl, IHttpHandler
                if (targetControl == null)
                        return false;
                Type type = targetControl.GetType ();
-               object[] attributes = type.GetCustomAttributes (true);
+               object[] attributes = type.GetCustomAttributes (false);
                foreach (object attr in attributes)
                        if (attr is SupportsEventValidationAttribute)
                                return true;
@@ -1339,11 +1476,6 @@ public partial class Page : TemplateControl, IHttpHandler
                Control targetControl;
 #endif
                if (requiresRaiseEvent != null) {
-#if NET_2_0
-                       targetControl = requiresRaiseEvent as Control;
-                       if (targetControl != null && CheckForValidationSupport (targetControl))
-                               scriptManager.ValidateEvent (targetControl.UniqueID, null);
-#endif
                        RaisePostBackEvent (requiresRaiseEvent, null);
                        return;
                }
@@ -1369,10 +1501,6 @@ public partial class Page : TemplateControl, IHttpHandler
                        return;
 
                string eventArgument = postdata [postEventArgumentID];
-#if NET_2_0
-               if (CheckForValidationSupport (targetControl))
-                       scriptManager.ValidateEvent (targetControl.UniqueID, eventArgument);
-#endif
                RaisePostBackEvent (target, eventArgument);
        }
 
@@ -1390,6 +1518,11 @@ public partial class Page : TemplateControl, IHttpHandler
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        protected virtual void RaisePostBackEvent (IPostBackEventHandler sourceControl, string eventArgument)
        {
+#if NET_2_0
+               Control targetControl = sourceControl as Control;
+               if (targetControl != null && CheckForValidationSupport (targetControl))
+                       scriptManager.ValidateEvent (targetControl.UniqueID, eventArgument);
+#endif
                sourceControl.RaisePostBackEvent (eventArgument);
        }
        
@@ -1443,6 +1576,11 @@ public partial class Page : TemplateControl, IHttpHandler
        [EditorBrowsable (EditorBrowsableState.Advanced)]
        public void RegisterRequiresPostBack (Control control)
        {
+#if NET_2_0
+               if (!(control is IPostBackDataHandler))
+                       throw new HttpException ("The control to register does not implement the IPostBackDataHandler interface.");
+#endif
+               
                if (_requiresPostBack == null)
                        _requiresPostBack = new ArrayList ();
 
@@ -1632,7 +1770,10 @@ public partial class Page : TemplateControl, IHttpHandler
        {
                if (_context == null)
                        return;
-
+#if NET_2_0
+               if (IsCallback)
+                       return;
+#endif
                if (!renderingForm)
                        throw new HttpException ("Control '" +
                                                 control.ClientID +
@@ -1780,11 +1921,8 @@ public partial class Page : TemplateControl, IHttpHandler
                                _focusedControlID = Form.DefaultButton;
                }
 
-               if (!String.IsNullOrEmpty (_focusedControlID) || Form.SubmitDisabledControls) {
-
-                       RequiresPostBackScript ();
-
                        if (!String.IsNullOrEmpty (_focusedControlID)) {
+                               ClientScript.RegisterWebFormClientScript ();
                                ClientScript.RegisterStartupScript ("HtmlForm-DefaultButton-StartupScript",
                                                                         String.Format ("<script type=\"text/javascript\">\n" +
                                                                                        "<!--\n" +
@@ -1792,19 +1930,19 @@ public partial class Page : TemplateControl, IHttpHandler
                                                                                        "</script>\n", _focusedControlID));
                        }
 
-                       if (Form.SubmitDisabledControls) {
+                       if (Form.SubmitDisabledControls && _hasEnabledControlArray) {
+                               ClientScript.RegisterWebFormClientScript ();
                                ClientScript.RegisterOnSubmitStatement ("HtmlForm-SubmitDisabledControls-SubmitStatement",
-                                                                                "javascript: return WebForm_OnSubmit();");
-                               ClientScript.RegisterStartupScript ("HtmlForm-SubmitDisabledControls-StartupScript",
-@"<script language=""JavaScript"">
-<!--
-function WebForm_OnSubmit() {
-WebForm_ReEnableControls();
-return true;
-} // -->
-</script>");
+                                                                                "WebForm_ReEnableControls(this);");
                        }
-               }
+       }
+
+       internal void RegisterEnabledControl (Control control)
+       {
+               if (Form == null || !Page.Form.SubmitDisabledControls || !Page.Form.DetermineRenderUplevel ())
+                       return;
+               _hasEnabledControlArray = true;
+               Page.ClientScript.RegisterArrayDeclaration (EnabledControlArrayID, String.Format ("'{0}'", control.ClientID));
        }
        
        protected virtual void OnSaveStateComplete (EventArgs e)
@@ -1867,9 +2005,26 @@ return true;
                if (target == null)
                        throw new HttpException (string.Format ("Invalid callback target '{0}'.", callbackTarget));
 
+               string callbackEventError = String.Empty;
+               string callBackResult;
                string callbackArgument = _requestValueCollection [CallbackArgumentID];
-               target.RaiseCallbackEvent (callbackArgument);
-               return target.GetCallbackResult ();
+
+               try {
+                       target.RaiseCallbackEvent (callbackArgument);
+               }
+               catch (Exception ex) {
+                       callbackEventError = String.Format ("e{0}", ex.Message);
+               }
+               
+               try {
+                       callBackResult = target.GetCallbackResult ();
+               }
+               catch (Exception ex) {
+                       return String.Format ("e{0}", ex.Message);
+               }
+               
+               string eventValidation = ClientScript.GetEventValidationStateFormatted ();
+               return String.Format ("{0}{1}|{2}{3}", callbackEventError, eventValidation == null ? 0 : eventValidation.Length, eventValidation, callBackResult);
        }
 
        [BrowsableAttribute (false)]
@@ -1887,31 +2042,18 @@ return true;
                }
        }
 
-       [MonoTODO("Not Implemented")]
        protected bool AsyncMode {
-               get {
-                       throw new NotImplementedException ();
-               }
-               set {
-                       throw new NotImplementedException ();
-               }
+               get { return asyncMode; }
+               set { asyncMode = value; }
        }
 
-       [MonoTODO ("Not Implemented")]
        public TimeSpan AsyncTimeout {
-               get {
-                       throw new NotImplementedException ();
-               }
-               set {
-                       throw new NotImplementedException ();
-               }
+               get { return asyncTimeout; }
+               set { asyncTimeout = value; }
        }
 
-       [MonoTODO ("Not Implemented")]
        public bool IsAsync {
-               get {
-                       throw new NotImplementedException ();
-               }
+               get { return AsyncMode; }
        }
        
        [MonoTODO ("Not Implemented")]
@@ -1931,44 +2073,271 @@ return true;
                }
        }
 
-       [MonoTODO ("Not Implemented")]
-       public ViewStateEncryptionMode ViewStateEncryptionMode {
-               get {
-                       throw new NotImplementedException ();
+       public void AddOnPreRenderCompleteAsync (BeginEventHandler beginHandler, EndEventHandler endHandler)
+       {
+               AddOnPreRenderCompleteAsync (beginHandler, endHandler, null);
+       }
+
+       public void AddOnPreRenderCompleteAsync (BeginEventHandler beginHandler, EndEventHandler endHandler, Object state)
+       {
+               if (!IsAsync) {
+                       throw new InvalidOperationException ("AddOnPreRenderCompleteAsync called and Page.IsAsync == false");
                }
-               set {
-                       throw new NotImplementedException ();
+
+               if (_lifeCycle >= PageLifeCycle.PreRender) {
+                       throw new InvalidOperationException ("AddOnPreRenderCompleteAsync can only be called before PreRender.");
+               }
+
+               if (beginHandler == null) {
+                       throw new ArgumentNullException ("beginHandler");
+               }
+
+               if (endHandler == null) {
+                       throw new ArgumentNullException ("endHandler");
+               }
+
+               RegisterAsyncTask (new PageAsyncTask (beginHandler, endHandler, null, state, false));
+       }
+
+       private List<PageAsyncTask> ParallelTasks {
+               get
+               {
+                       if (parallelTasks == null) {
+                               parallelTasks = new List<PageAsyncTask>();
+                       }
+                       return parallelTasks;
                }
        }
 
-       [MonoTODO ("Not Implemented")]
-       public void AddOnPreRenderCompleteAsync (BeginEventHandler beginHandler, EndEventHandler endHandler)
-       {
-               throw new NotImplementedException ();
+       private List<PageAsyncTask> SerialTasks {
+               get {
+                       if (serialTasks == null) {
+                               serialTasks = new List<PageAsyncTask> ();
+                       }
+                       return serialTasks;
+               }
        }
 
-       [MonoTODO ("Not Implemented")]
-       public void AddOnPreRenderCompleteAsync (BeginEventHandler beginHandler, EndEventHandler endHandler, Object state)
+       public void RegisterAsyncTask (PageAsyncTask task) 
        {
-               throw new NotImplementedException ();
+               if (task == null) {
+                       throw new ArgumentNullException ("task");
+               }
+
+               if (task.ExecuteInParallel) {
+                       ParallelTasks.Add (task);
+               }
+               else {
+                       SerialTasks.Add (task);
+               }
        }
 
-       [MonoTODO ("Not Implemented")]
        public void ExecuteRegisteredAsyncTasks ()
        {
-               throw new NotImplementedException ();
+               if ((parallelTasks == null || parallelTasks.Count == 0) &&
+                       (serialTasks == null || serialTasks.Count == 0)){
+                       return;
+               }
+
+               if (parallelTasks != null) {
+                       DateTime startExecution = DateTime.Now;
+                       List<PageAsyncTask> localParallelTasks = parallelTasks;
+                       parallelTasks = null; // Shouldn't execute tasks twice
+                       List<IAsyncResult> asyncResults = new List<IAsyncResult>();
+                       foreach (PageAsyncTask parallelTask in localParallelTasks) {
+                               IAsyncResult result = parallelTask.BeginHandler (this, EventArgs.Empty, new AsyncCallback (EndAsyncTaskCallback), parallelTask.State);
+                               if (result.CompletedSynchronously) {
+                                       parallelTask.EndHandler (result);
+                               }
+                               else {
+                                       asyncResults.Add (result);
+                               }
+                       }
+
+                       if (asyncResults.Count > 0) {
+#if TARGET_JVM
+                               TimeSpan timeout = AsyncTimeout;
+                               long t1 = DateTime.Now.Ticks;
+                               bool signalled = true;
+                               for (int i = 0; i < asyncResults.Count; i++) {
+                                       if (asyncResults [i].IsCompleted)
+                                               continue;
+
+                                       if (signalled)
+                                               signalled = asyncResults [i].AsyncWaitHandle.WaitOne (timeout, false);
+
+                                       if (signalled) {
+                                               long t2 = DateTime.Now.Ticks;
+                                               timeout = AsyncTimeout - TimeSpan.FromTicks (t2 - t1);
+                                               if (timeout.Ticks <= 0)
+                                                       signalled = false;
+                                       }
+                                       else {
+                                               localParallelTasks [i].TimeoutHandler (asyncResults [i]);
+                                       }
+                               }
+#else
+                               WaitHandle [] waitArray = new WaitHandle [asyncResults.Count];
+                               int i = 0;
+                               for (i = 0; i < asyncResults.Count; i++) {
+                                       waitArray [i] = asyncResults [i].AsyncWaitHandle;
+                               }
+                               bool allSignalled = WaitHandle.WaitAll (waitArray, AsyncTimeout, false);
+                               if (!allSignalled) {
+                                       for (i = 0; i < asyncResults.Count; i++) {
+                                               if (!asyncResults [i].IsCompleted) {
+                                                       localParallelTasks [i].TimeoutHandler (asyncResults [i]);
+                                               }
+                                       }
+                               }
+#endif
+                       }
+                       DateTime endWait = DateTime.Now;
+                       TimeSpan elapsed = endWait - startExecution;
+                       if (elapsed <= AsyncTimeout) {
+                               AsyncTimeout -= elapsed;
+                       }
+                       else {
+                               AsyncTimeout = TimeSpan.FromTicks(0);
+                       }
+               }
+
+               if (serialTasks != null) {
+                       List<PageAsyncTask> localSerialTasks = serialTasks;
+                       serialTasks = null; // Shouldn't execute tasks twice
+                       foreach (PageAsyncTask serialTask in localSerialTasks) {
+                               DateTime startExecution = DateTime.Now;
+
+                               IAsyncResult result = serialTask.BeginHandler (this, EventArgs.Empty, new AsyncCallback (EndAsyncTaskCallback), serialTask);
+                               if (result.CompletedSynchronously) {
+                                       serialTask.EndHandler (result);
+                               }
+                               else {
+                                       bool done = result.AsyncWaitHandle.WaitOne (AsyncTimeout, false);
+                                       if (!done && !result.IsCompleted) {
+                                               serialTask.TimeoutHandler (result);
+                                       }
+                               }
+                               DateTime endWait = DateTime.Now;
+                               TimeSpan elapsed = endWait - startExecution;
+                               if (elapsed <= AsyncTimeout) {
+                                       AsyncTimeout -= elapsed;
+                               }
+                               else {
+                                       AsyncTimeout = TimeSpan.FromTicks (0);
+                               }
+                       }
+               }
+               AsyncTimeout = TimeSpan.FromSeconds (DefaultAsyncTimeout);
+       }
+
+       void EndAsyncTaskCallback (IAsyncResult result) 
+       {
+               PageAsyncTask task = (PageAsyncTask)result.AsyncState;
+               task.EndHandler (result);
        }
 
-       [MonoTODO ("Not Implemented")]
        public static HtmlTextWriter CreateHtmlTextWriterFromType (TextWriter tw, Type writerType)
        {
-               throw new NotImplementedException ();
+               Type htmlTextWriterType = typeof (HtmlTextWriter);
+               
+               if (!htmlTextWriterType.IsAssignableFrom (writerType)) {
+                       throw new HttpException (String.Format ("Type '{0}' cannot be assigned to HtmlTextWriter", writerType.FullName));
+               }
+
+               ConstructorInfo constructor = writerType.GetConstructor (new Type [] { typeof (TextWriter) });
+               if (constructor == null) {
+                       throw new HttpException (String.Format ("Type '{0}' does not have a consturctor that takes a TextWriter as parameter", writerType.FullName));
+               }
+
+               return (HtmlTextWriter) Activator.CreateInstance(writerType, tw);
+       }
+
+       public ViewStateEncryptionMode ViewStateEncryptionMode {
+               get { return viewStateEncryptionMode; }
+               set { viewStateEncryptionMode = value; }
        }
 
-       [MonoTODO ("Not Implemented")]
        public void RegisterRequiresViewStateEncryption ()
        {
-               throw new NotImplementedException ();
+               controlRegisteredForViewStateEncryption = true;
+       }
+
+       private static byte [] AES_IV = null;
+       private static byte [] TripleDES_IV = null;
+       private static object locker = new object ();
+       private static bool isEncryptionInitialized = false;
+
+       private static void InitializeEncryption () 
+       {
+               if (isEncryptionInitialized) {
+                       return;
+               }
+
+               lock (locker) {
+                       if (isEncryptionInitialized) {
+                               return;
+                       }
+
+                       string iv_string = "0BA48A9E-736D-40f8-954B-B2F62241F282";
+                       AES_IV = new byte [16];
+                       TripleDES_IV = new byte [8];
+
+                       int i;
+                       for (i = 0; i < AES_IV.Length; i++) {
+                               AES_IV [i] = (byte) iv_string [i];
+                       }
+
+                       for (i = 0; i < TripleDES_IV.Length; i++) {
+                               TripleDES_IV [i] = (byte) iv_string [i];
+                       }
+
+                       isEncryptionInitialized = true;
+               }
+       }
+
+       internal ICryptoTransform GetCryptoTransform (CryptoStreamMode cryptoStreamMode) 
+       {
+               ICryptoTransform transform = null;
+               MachineKeySection config = (MachineKeySection) WebConfigurationManager.GetSection (machineKeyConfigPath);
+               byte [] vk = config.ValidationKeyBytes;
+
+               switch (config.Validation) {
+               case MachineKeyValidation.SHA1:
+                       transform = SHA1.Create ();
+                       break;
+
+               case MachineKeyValidation.MD5:
+                       transform = MD5.Create ();
+                       break;
+
+               case MachineKeyValidation.AES:
+                       if (cryptoStreamMode == CryptoStreamMode.Read){
+                               transform = Rijndael.Create().CreateDecryptor(vk, AES_IV);
+                       } else {
+                               transform = Rijndael.Create().CreateEncryptor(vk, AES_IV);
+                       }
+                       break;
+
+               case MachineKeyValidation.TripleDES:
+                       if (cryptoStreamMode == CryptoStreamMode.Read){
+                               transform = TripleDES.Create().CreateDecryptor(vk, TripleDES_IV);
+                       } else {
+                               transform = TripleDES.Create().CreateEncryptor(vk, TripleDES_IV);
+                       }
+                       break;
+               }
+
+               return transform;
+       }
+
+       internal bool NeedViewStateEncryption {
+               get {
+                       return (ViewStateEncryptionMode == ViewStateEncryptionMode.Always ||
+                                       (ViewStateEncryptionMode == ViewStateEncryptionMode.Auto &&
+                                        controlRegisteredForViewStateEncryption));
+
+               }
        }
 
        void ApplyMasterPage ()
@@ -2178,8 +2547,6 @@ return true;
        protected internal override void OnInit (EventArgs e)
        {
                base.OnInit (e);
-               if (Header == null)
-                       return;
 
                ArrayList themes = new ArrayList();
 
@@ -2188,6 +2555,9 @@ return true;
                if (PageTheme != null && PageTheme.GetStyleSheets () != null)
                        themes.AddRange (PageTheme.GetStyleSheets ());
 
+               if (themes.Count > 0 && Header == null)
+                       throw new InvalidOperationException ("Using themed css files requires a header control on the page.");
+
                foreach (string lss in themes) {
                        HtmlLink hl = new HtmlLink ();
                        hl.Href = ResolveUrl (lss);
@@ -2203,7 +2573,7 @@ return true;
        [MonoTODO ("Not implemented.  Only used by .net aspx parser")]
        protected object GetWrappedFileDependencies (string [] list)
        {
-               return null;
+               return list;
        }
 
        [MonoTODO ("Does nothing.  Used by .net aspx parser")]