Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Web / UI / WebControls / ChangePassword.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="ChangePassword.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6
7 namespace System.Web.UI.WebControls {
8     using System;
9     using System.Collections;
10     using System.Collections.Specialized;
11     using System.ComponentModel;
12     using System.Diagnostics.CodeAnalysis;
13     using System.Drawing;
14     using System.Drawing.Design;
15     using System.Globalization;
16     using System.Net.Mail;
17     using System.Security.Permissions;
18     using System.Web.Configuration;
19     using System.Web.Management;
20     using System.Web.Security;
21     using System.Web.UI;
22
23     /// <devdoc>
24     ///     Displays UI that allows a user to change his password.  Uses a Membership provider
25     ///     or custom authentication logic in the OnAuthenticate event.  UI can be customized
26     ///     using control properties or a template.
27     /// </devdoc>
28     [
29     Bindable(false),
30     DefaultEvent("ChangedPassword"),
31     Designer("System.Web.UI.Design.WebControls.ChangePasswordDesigner, " + AssemblyRef.SystemDesign)
32     ]
33     public class ChangePassword : CompositeControl, IBorderPaddingControl, INamingContainer, IRenderOuterTableControl {
34         public static readonly string ChangePasswordButtonCommandName = "ChangePassword";
35         public static readonly string CancelButtonCommandName = "Cancel";
36         public static readonly string ContinueButtonCommandName = "Continue";
37
38         private ITemplate _changePasswordTemplate;
39         private ChangePasswordContainer _changePasswordContainer;
40         private ITemplate _successTemplate;
41         private SuccessContainer _successContainer;
42
43         private string _userName;
44         private string _password;
45         private string _newPassword;
46         private string _confirmNewPassword;
47
48         private bool _convertingToTemplate = false;
49         private bool _renderDesignerRegion = false;
50         private View _currentView = View.ChangePassword;
51
52         // Needed for user template feature
53         private const string _userNameID = "UserName";
54         private const string _currentPasswordID = "CurrentPassword";
55         private const string _newPasswordID = "NewPassword";
56         private const string _confirmNewPasswordID = "ConfirmNewPassword";
57         private const string _failureTextID = "FailureText";
58
59         // Needed only for "convert to template" feature, otherwise unnecessary
60         private const string _userNameRequiredID = "UserNameRequired";
61         private const string _currentPasswordRequiredID = "CurrentPasswordRequired";
62         private const string _newPasswordRequiredID = "NewPasswordRequired";
63         private const string _confirmNewPasswordRequiredID = "ConfirmNewPasswordRequired";
64         private const string _newPasswordCompareID = "NewPasswordCompare";
65         private const string _newPasswordRegExpID = "NewPasswordRegExp";
66         private const string _changePasswordPushButtonID = "ChangePasswordPushButton";
67         private const string _changePasswordImageButtonID = "ChangePasswordImageButton";
68         private const string _changePasswordLinkButtonID = "ChangePasswordLinkButton";
69         private const string _cancelPushButtonID = "CancelPushButton";
70         private const string _cancelImageButtonID = "CancelImageButton";
71         private const string _cancelLinkButtonID = "CancelLinkButton";
72         private const string _continuePushButtonID = "ContinuePushButton";
73         private const string _continueImageButtonID = "ContinueImageButton";
74         private const string _continueLinkButtonID = "ContinueLinkButton";
75         private const string _passwordRecoveryLinkID = "PasswordRecoveryLink";
76         private const string _helpLinkID = "HelpLink";
77         private const string _createUserLinkID = "CreateUserLink";
78         private const string _editProfileLinkID = "EditProfileLink";
79         private const string _editProfileSuccessLinkID = "EditProfileLinkSuccess";
80
81         private const string _changePasswordViewContainerID = "ChangePasswordContainerID";
82         private const string _successViewContainerID = "SuccessContainerID";
83
84         private const ValidatorDisplay _requiredFieldValidatorDisplay = ValidatorDisplay.Static;
85         private const ValidatorDisplay _compareFieldValidatorDisplay = ValidatorDisplay.Dynamic;
86         private const ValidatorDisplay _regexpFieldValidatorDisplay = ValidatorDisplay.Dynamic;
87
88         private const string _userNameReplacementKey = "<%\\s*UserName\\s*%>";
89         private const string _passwordReplacementKey = "<%\\s*Password\\s*%>";
90
91         private const int _viewStateArrayLength = 14;
92         private Style _changePasswordButtonStyle;
93         private TableItemStyle _labelStyle;
94         private Style _textBoxStyle;
95         private TableItemStyle _hyperLinkStyle;
96         private TableItemStyle _instructionTextStyle;
97         private TableItemStyle _titleTextStyle;
98         private TableItemStyle _failureTextStyle;
99         private TableItemStyle _successTextStyle;
100         private TableItemStyle _passwordHintStyle;
101         private Style _cancelButtonStyle;
102         private Style _continueButtonStyle;
103         private Style _validatorTextStyle;
104
105         private MailDefinition _mailDefinition;
106
107         private Control _validatorRow;
108         private Control _passwordHintTableRow;
109         private Control _userNameTableRow;
110
111         private static readonly object EventChangePasswordError = new object();
112         private static readonly object EventCancelButtonClick = new object();
113         private static readonly object EventContinueButtonClick = new object();
114         private static readonly object EventChangingPassword = new object();
115         private static readonly object EventChangedPassword = new object();
116         private static readonly object EventSendingMail = new object();
117         private static readonly object EventSendMailError = new object();
118
119         
120         [
121         WebCategory("Appearance"),
122         DefaultValue(1),
123         WebSysDescription(SR.Login_BorderPadding),
124         SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces",
125             Justification = "Interface denotes existence of property, not used for security.")
126         ]
127         public virtual int BorderPadding {
128             get {
129                 object obj = ViewState["BorderPadding"];
130                 return (obj == null) ? 1 : (int)obj;
131             }
132             set {
133                 if (value < -1) {
134                     throw new ArgumentOutOfRangeException("value", SR.GetString(SR.ChangePassword_InvalidBorderPadding));
135                 }
136                 ViewState["BorderPadding"] = value;
137             }
138         }
139
140
141         /// <devdoc>
142         ///     Gets or sets the URL of an image to be displayed for the cancel button.
143         /// </devdoc>
144         [
145         WebCategory("Appearance"),
146         DefaultValue(""),
147         WebSysDescription(SR.ChangePassword_CancelButtonImageUrl),
148         Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
149         UrlProperty()
150         ]
151         public virtual string CancelButtonImageUrl {
152             get {
153                 object obj = ViewState["CancelButtonImageUrl"];
154                 return (obj == null) ? String.Empty : (string) obj;
155             }
156             set {
157                 ViewState["CancelButtonImageUrl"] = value;
158             }
159         }
160
161
162         /// <devdoc>
163         ///     Gets the style of cancel button.
164         /// </devdoc>
165         [
166         WebCategory("Styles"),
167         DefaultValue(null),
168         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
169         NotifyParentProperty(true),
170         PersistenceMode(PersistenceMode.InnerProperty),
171         WebSysDescription(SR.ChangePassword_CancelButtonStyle)
172         ]
173         public Style CancelButtonStyle {
174             get {
175                 if (_cancelButtonStyle == null) {
176                     _cancelButtonStyle = new Style();
177                     if (IsTrackingViewState) {
178                         ((IStateManager) _cancelButtonStyle).TrackViewState();
179                     }
180                 }
181                 return _cancelButtonStyle;
182             }
183         }
184
185
186         /// <devdoc>
187         ///     Gets or sets the text to be shown for the cancel button.
188         /// </devdoc>
189         [
190         Localizable(true),
191         WebCategory("Appearance"),
192         WebSysDefaultValue(SR.ChangePassword_DefaultCancelButtonText),
193         WebSysDescription(SR.ChangePassword_CancelButtonText)
194         ]
195         public virtual string CancelButtonText {
196             get {
197                 object obj = ViewState["CancelButtonText"];
198                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultCancelButtonText) : (string) obj;
199             }
200             set {
201                 ViewState["CancelButtonText"] = value;
202             }
203         }
204
205
206         /// <devdoc>
207         ///     Gets or sets the type of the cancel button.
208         /// </devdoc>
209         [
210         WebCategory("Appearance"),
211         DefaultValue(ButtonType.Button),
212         WebSysDescription(SR.ChangePassword_CancelButtonType)
213         ]
214         public virtual ButtonType CancelButtonType {
215             get {
216                 object obj = ViewState["CancelButtonType"];
217                 return (obj == null) ? ButtonType.Button : (ButtonType) obj;
218             }
219             set {
220                 if (value < ButtonType.Button || value > ButtonType.Link) {
221                     throw new ArgumentOutOfRangeException("value");
222                 }
223                 ViewState["CancelButtonType"] = value;
224             }
225         }
226
227
228         /// <devdoc>
229         ///     Gets or sets the URL of an image to be displayed for the continue button.
230         /// </devdoc>
231         [
232         WebCategory("Behavior"),
233         DefaultValue(""),
234         WebSysDescription(SR.ChangePassword_CancelDestinationPageUrl),
235         Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
236         Themeable(false),
237         UrlProperty()
238         ]
239         public virtual string CancelDestinationPageUrl {
240             get {
241                 object obj = ViewState["CancelDestinationPageUrl"];
242                 return (obj == null) ? String.Empty : (string) obj;
243             }
244             set {
245                 ViewState["CancelDestinationPageUrl"] = value;
246             }
247         }
248
249
250         /// <devdoc>
251         ///     Gets or sets the URL of an image to be displayed for the change password button.
252         /// </devdoc>
253         [
254         WebCategory("Appearance"),
255         DefaultValue(""),
256         WebSysDescription(SR.ChangePassword_ChangePasswordButtonImageUrl),
257         Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
258         UrlProperty()
259         ]
260         public virtual string ChangePasswordButtonImageUrl {
261             get {
262                 object obj = ViewState["ChangePasswordButtonImageUrl"];
263                 return (obj == null) ? String.Empty : (string) obj;
264             }
265             set {
266                 ViewState["ChangePasswordButtonImageUrl"] = value;
267             }
268         }
269
270
271         /// <devdoc>
272         ///     Gets the style of change password button.
273         /// </devdoc>
274         [
275         WebCategory("Styles"),
276         DefaultValue(null),
277         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
278         NotifyParentProperty(true),
279         PersistenceMode(PersistenceMode.InnerProperty),
280         WebSysDescription(SR.ChangePassword_ChangePasswordButtonStyle)
281         ]
282         public Style ChangePasswordButtonStyle {
283             get {
284                 if (_changePasswordButtonStyle == null) {
285                     _changePasswordButtonStyle = new Style();
286                     if (IsTrackingViewState) {
287                         ((IStateManager) _changePasswordButtonStyle).TrackViewState();
288                     }
289                 }
290                 return _changePasswordButtonStyle;
291             }
292         }
293
294
295         /// <devdoc>
296         ///     Gets or sets the text to be shown for the change password button.
297         /// </devdoc>
298         [
299         Localizable(true),
300         WebCategory("Appearance"),
301         WebSysDefaultValue(SR.ChangePassword_DefaultChangePasswordButtonText),
302         WebSysDescription(SR.ChangePassword_ChangePasswordButtonText)
303         ]
304         public virtual string ChangePasswordButtonText {
305             get {
306                 object obj = ViewState["ChangePasswordButtonText"];
307                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultChangePasswordButtonText) : (string) obj;
308             }
309             set {
310                 ViewState["ChangePasswordButtonText"] = value;
311             }
312         }
313
314
315         /// <devdoc>
316         ///     Gets or sets the type of the create user button.
317         /// </devdoc>
318         [
319         WebCategory("Appearance"),
320         DefaultValue(ButtonType.Button),
321         WebSysDescription(SR.ChangePassword_ChangePasswordButtonType)
322         ]
323         public virtual ButtonType ChangePasswordButtonType {
324             get {
325                 object obj = ViewState["ChangePasswordButtonType"];
326                 return (obj == null) ? ButtonType.Button : (ButtonType) obj;
327             }
328             set {
329                 if (value < ButtonType.Button || value > ButtonType.Link) {
330                     throw new ArgumentOutOfRangeException("value");
331                 }
332                 ViewState["ChangePasswordButtonType"] = value;
333             }
334         }
335
336
337         /// <devdoc>
338         ///     Gets or sets the text to be shown when a change password attempt fails.
339         /// </devdoc>
340         [
341         Localizable(true),
342         WebCategory("Appearance"),
343         WebSysDefaultValue(SR.ChangePassword_DefaultChangePasswordFailureText),
344         WebSysDescription(SR.ChangePassword_ChangePasswordFailureText)
345         ]
346         public virtual string ChangePasswordFailureText {
347             get {
348                 object obj = ViewState["ChangePasswordFailureText"];
349                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultChangePasswordFailureText) : (string) obj;
350             }
351             set {
352                 ViewState["ChangePasswordFailureText"] = value;
353             }
354         }
355
356
357         /// <devdoc>
358         ///     Gets or sets the template that is used to render the control.  If null, a
359         ///     default template is used.
360         /// </devdoc>
361         [
362         Browsable(false),
363         PersistenceMode(PersistenceMode.InnerProperty),
364         TemplateContainer(typeof(ChangePassword))
365         ]
366         public virtual ITemplate ChangePasswordTemplate {
367             get {
368                 return _changePasswordTemplate;
369             }
370             set {
371                 _changePasswordTemplate = value;
372                 ChildControlsCreated = false;
373             }
374         }
375
376         /// <devdoc>
377         ///     Gets the container into which the template is instantiated.
378         /// </devdoc>
379         [
380         Browsable(false),
381         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
382         ]
383         public Control ChangePasswordTemplateContainer {
384             get {
385                 EnsureChildControls();
386                 return _changePasswordContainer;
387             }
388         }
389
390
391         /// <devdoc>
392         ///     Gets or sets the title text to be shown for the change password view
393         /// </devdoc>
394         [
395         Localizable(true),
396         WebCategory("Appearance"),
397         WebSysDefaultValue(SR.ChangePassword_DefaultChangePasswordTitleText),
398         WebSysDescription(SR.LoginControls_TitleText)
399         ]
400         public virtual string ChangePasswordTitleText {
401             get {
402                 object obj = ViewState["ChangePasswordTitleText"];
403                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultChangePasswordTitleText) : (string) obj;
404             }
405             set {
406                 ViewState["ChangePasswordTitleText"] = value;
407             }
408         }
409
410
411         /// <devdoc>
412         ///     Gets the confirm new password entered by the user.
413         /// </devdoc>
414         [
415         Browsable(false),
416         Themeable(false),
417         Filterable(false),
418         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
419         ]
420         public virtual string ConfirmNewPassword {
421             get {
422                 return (_confirmNewPassword == null) ? String.Empty : _confirmNewPassword;
423             }
424         }
425
426
427         /// <devdoc>
428         ///     Gets or sets the text that identifies the new password textbox.
429         /// </devdoc>
430         [
431         Localizable(true),
432         WebCategory("Appearance"),
433         WebSysDefaultValue(SR.ChangePassword_DefaultConfirmNewPasswordLabelText),
434         WebSysDescription(SR.ChangePassword_ConfirmNewPasswordLabelText)
435         ]
436         public virtual string ConfirmNewPasswordLabelText {
437             get {
438                 object obj = ViewState["ConfirmNewPasswordLabelText"];
439                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultConfirmNewPasswordLabelText) : (string) obj;
440             }
441             set {
442                 ViewState["ConfirmNewPasswordLabelText"] = value;
443             }
444         }
445
446
447         /// <devdoc>
448         ///     Gets or sets the text that is displayed when the new password does not match the confirm password.
449         /// </devdoc>
450         [
451         Localizable(true),
452         WebCategory("Validation"),
453         WebSysDefaultValue(SR.ChangePassword_DefaultConfirmPasswordCompareErrorMessage),
454         WebSysDescription(SR.ChangePassword_ConfirmPasswordCompareErrorMessage)
455         ]
456         public virtual string ConfirmPasswordCompareErrorMessage {
457             get {
458                 object obj = ViewState["ConfirmPasswordCompareErrorMessage"];
459                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultConfirmPasswordCompareErrorMessage) : (string) obj;
460             }
461             set {
462                 ViewState["ConfirmPasswordCompareErrorMessage"] = value;
463             }
464         }
465
466
467         /// <devdoc>
468         ///     Gets or sets the text to be shown in the validation summary when the confirm password is empty.
469         /// </devdoc>
470         [
471         Localizable(true),
472         WebCategory("Validation"),
473         WebSysDefaultValue(SR.ChangePassword_DefaultConfirmPasswordRequiredErrorMessage),
474         WebSysDescription(SR.LoginControls_ConfirmPasswordRequiredErrorMessage)
475         ]
476         public virtual string ConfirmPasswordRequiredErrorMessage {
477             get {
478                 object obj = ViewState["ConfirmPasswordRequiredErrorMessage"];
479                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultConfirmPasswordRequiredErrorMessage) : (string) obj;
480             }
481             set {
482                 ViewState["ConfirmPasswordRequiredErrorMessage"] = value;
483             }
484         }
485
486
487         /// <devdoc>
488         ///     Gets or sets the URL of an image to be displayed for the continue button.
489         /// </devdoc>
490         [
491         WebCategory("Appearance"),
492         DefaultValue(""),
493         WebSysDescription(SR.ChangePassword_ContinueButtonImageUrl),
494         Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
495         UrlProperty()
496         ]
497         public virtual string ContinueButtonImageUrl {
498             get {
499                 object obj = ViewState["ContinueButtonImageUrl"];
500                 return (obj == null) ? String.Empty : (string) obj;
501             }
502             set {
503                 ViewState["ContinueButtonImageUrl"] = value;
504             }
505         }
506
507
508         /// <devdoc>
509         ///     Gets the style of change password button.
510         /// </devdoc>
511         [
512         WebCategory("Styles"),
513         DefaultValue(null),
514         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
515         NotifyParentProperty(true),
516         PersistenceMode(PersistenceMode.InnerProperty),
517         WebSysDescription(SR.ChangePassword_ContinueButtonStyle)
518         ]
519         public Style ContinueButtonStyle {
520             get {
521                 if (_continueButtonStyle == null) {
522                     _continueButtonStyle = new Style();
523                     if (IsTrackingViewState) {
524                         ((IStateManager) _continueButtonStyle).TrackViewState();
525                     }
526                 }
527                 return _continueButtonStyle;
528             }
529         }
530
531
532         /// <devdoc>
533         ///     Gets or sets the text to be shown for the continue button.
534         /// </devdoc>
535         [
536         Localizable(true),
537         WebCategory("Appearance"),
538         WebSysDefaultValue(SR.ChangePassword_DefaultContinueButtonText),
539         WebSysDescription(SR.ChangePassword_ContinueButtonText)
540         ]
541         public virtual string ContinueButtonText {
542             get {
543                 object obj = ViewState["ContinueButtonText"];
544                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultContinueButtonText) : (string) obj;
545             }
546             set {
547                 ViewState["ContinueButtonText"] = value;
548             }
549         }
550
551
552         /// <devdoc>
553         ///     Gets or sets the type of the continue button.
554         /// </devdoc>
555         [
556         WebCategory("Appearance"),
557         DefaultValue(ButtonType.Button),
558         WebSysDescription(SR.ChangePassword_ContinueButtonType)
559         ]
560         public virtual ButtonType ContinueButtonType {
561             get {
562                 object obj = ViewState["ContinueButtonType"];
563                 return (obj == null) ? ButtonType.Button : (ButtonType) obj;
564             }
565             set {
566                 if (value < ButtonType.Button || value > ButtonType.Link) {
567                     throw new ArgumentOutOfRangeException("value");
568                 }
569                 ViewState["ContinueButtonType"] = value;
570             }
571         }
572
573
574         /// <devdoc>
575         ///     Gets or sets the URL for the continue button.
576         /// </devdoc>
577         [
578         WebCategory("Behavior"),
579         DefaultValue(""),
580         WebSysDescription(SR.LoginControls_ContinueDestinationPageUrl),
581         Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
582         Themeable(false),
583         UrlProperty()
584         ]
585         public virtual string ContinueDestinationPageUrl {
586             get {
587                 object obj = ViewState["ContinueDestinationPageUrl"];
588                 return (obj == null) ? String.Empty : (string) obj;
589             }
590             set {
591                 ViewState["ContinueDestinationPageUrl"] = value;
592             }
593         }
594
595         private bool ConvertingToTemplate {
596             get {
597                 return (DesignMode && _convertingToTemplate);
598             }
599         }
600
601
602         /// <devdoc>
603         ///     Gets or sets the URL of an icon to be displayed for the create user link.
604         /// </devdoc>
605         [
606         WebCategory("Links"),
607         DefaultValue(""),
608         WebSysDescription(SR.ChangePassword_CreateUserIconUrl),
609         Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
610         UrlProperty()
611         ]
612         public virtual string CreateUserIconUrl {
613             get {
614                 object obj = ViewState["CreateUserIconUrl"];
615                 return (obj == null) ? String.Empty : (string) obj;
616             }
617             set {
618                 ViewState["CreateUserIconUrl"] = value;
619             }
620         }
621
622
623         /// <devdoc>
624         ///     Gets or sets the text to be shown for the create user link.
625         /// </devdoc>
626         [
627         Localizable(true),
628         WebCategory("Links"),
629         DefaultValue(""),
630         WebSysDescription(SR.ChangePassword_CreateUserText)
631         ]
632         public virtual string CreateUserText {
633             get {
634                 object obj = ViewState["CreateUserText"];
635                 return (obj == null) ? String.Empty : (string) obj;
636             }
637             set {
638                 ViewState["CreateUserText"] = value;
639             }
640         }
641
642
643         /// <devdoc>
644         ///     Gets or sets the URL of the create user page.
645         /// </devdoc>
646         [
647         WebCategory("Links"),
648         DefaultValue(""),
649         WebSysDescription(SR.ChangePassword_CreateUserUrl),
650         Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
651         UrlProperty()
652         ]
653         public virtual string CreateUserUrl {
654             get {
655                 object obj = ViewState["CreateUserUrl"];
656                 return (obj == null) ? String.Empty : (string) obj;
657             }
658             set {
659                 ViewState["CreateUserUrl"] = value;
660             }
661         }
662
663
664         /// <devdoc>
665         ///     Gets the current password entered by the user.
666         /// </devdoc>
667         [
668         Browsable(false),
669         Themeable(false),
670         Filterable(false),
671         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
672         ]
673         public virtual string CurrentPassword {
674             get {
675                 return (_password == null) ? String.Empty : _password;
676             }
677         }
678
679         private string CurrentPasswordInternal {
680             get {
681                 string password = CurrentPassword;
682                 if (String.IsNullOrEmpty(password) && _changePasswordContainer != null) {
683                     ITextControl passwordTextBox = (ITextControl)_changePasswordContainer.CurrentPasswordTextBox;
684                     if (passwordTextBox != null) {
685                         return passwordTextBox.Text;
686                     }
687                 }
688                 return password;
689             }
690         }
691
692         /// <devdoc>
693         /// Internal because used from ChangePasswordAdapter.
694         /// </devdoc>
695         internal View CurrentView {
696             get {
697                 return _currentView;
698             }
699             set {
700                 if (value < View.ChangePassword || value > View.Success) {
701                     throw new ArgumentOutOfRangeException("value");
702                 }
703                 if (value != CurrentView) {
704                     _currentView = value;
705                 }
706             }
707         }
708
709
710         /// <devdoc>
711         ///     Gets or sets whether the user name is shown
712         /// </devdoc>
713         [
714         WebCategory("Behavior"),
715         DefaultValue(false),
716         WebSysDescription(SR.ChangePassword_DisplayUserName)
717         ]
718         public virtual bool DisplayUserName {
719             get {
720                 object obj = ViewState["DisplayUserName"];
721                 return (obj == null) ? false : (bool) obj;
722             }
723             set {
724                 if (DisplayUserName != value) {
725                     ViewState["DisplayUserName"] = value;
726                     UpdateValidators();
727                 }
728             }
729         }
730
731
732         /// <devdoc>
733         ///     Gets or sets the URL for the image shown next to the profile page.
734         /// </devdoc>
735         [
736         WebCategory("Links"),
737         DefaultValue(""),
738         WebSysDescription(SR.LoginControls_EditProfileIconUrl),
739         Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
740         UrlProperty()
741         ]
742         public virtual string EditProfileIconUrl {
743             get {
744                 object obj = ViewState["EditProfileIconUrl"];
745                 return (obj == null) ? String.Empty : (string) obj;
746             }
747             set {
748                 ViewState["EditProfileIconUrl"] = value;
749             }
750         }
751
752
753         /// <devdoc>
754         ///     Gets or sets the text to be shown for the edit profile page
755         /// </devdoc>
756         [
757         Localizable(true),
758         WebCategory("Links"),
759         DefaultValue(""),
760         WebSysDescription(SR.ChangePassword_EditProfileText)
761         ]
762         public virtual string EditProfileText {
763             get {
764                 object obj = ViewState["EditProfileText"];
765                 return (obj == null) ? String.Empty : (string) obj;
766             }
767             set {
768                 ViewState["EditProfileText"] = value;
769             }
770         }
771
772
773         /// <devdoc>
774         ///     Gets or sets the URL of the edit profile page.
775         /// </devdoc>
776         [
777         WebCategory("Links"),
778         DefaultValue(""),
779         WebSysDescription(SR.ChangePassword_EditProfileUrl),
780         Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
781         UrlProperty()
782         ]
783         public virtual string EditProfileUrl {
784             get {
785                 object obj = ViewState["EditProfileUrl"];
786                 return (obj == null) ? String.Empty : (string) obj;
787             }
788             set {
789                 ViewState["EditProfileUrl"] = value;
790             }
791         }
792
793
794         /// <devdoc>
795         ///     Gets the style of the failure text.
796         /// </devdoc>
797         [
798         WebCategory("Styles"),
799         DefaultValue(null),
800         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
801         NotifyParentProperty(true),
802         PersistenceMode(PersistenceMode.InnerProperty),
803         WebSysDescription(SR.WebControl_FailureTextStyle)
804         ]
805         public TableItemStyle FailureTextStyle {
806             get {
807                 if (_failureTextStyle == null) {
808                     _failureTextStyle = new ErrorTableItemStyle();
809                     if (IsTrackingViewState) {
810                         ((IStateManager) _failureTextStyle).TrackViewState();
811                     }
812                 }
813                 return _failureTextStyle;
814             }
815         }
816
817
818         /// <devdoc>
819         ///     Gets or sets the URL of an icon to be displayed for the help link.
820         /// </devdoc>
821         [
822         WebCategory("Links"),
823         DefaultValue(""),
824         WebSysDescription(SR.LoginControls_HelpPageIconUrl),
825         Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
826         UrlProperty()
827         ]
828         public virtual string HelpPageIconUrl {
829             get {
830                 object obj = ViewState["HelpPageIconUrl"];
831                 return (obj == null) ? String.Empty : (string) obj;
832             }
833             set {
834                 ViewState["HelpPageIconUrl"] = value;
835             }
836         }
837
838
839         /// <devdoc>
840         ///     Gets or sets the text to be shown for the help link.
841         /// </devdoc>
842         [
843         Localizable(true),
844         WebCategory("Links"),
845         DefaultValue(""),
846         WebSysDescription(SR.ChangePassword_HelpPageText)
847         ]
848         public virtual string HelpPageText {
849             get {
850                 object obj = ViewState["HelpPageText"];
851                 return (obj == null) ? String.Empty : (string) obj;
852             }
853             set {
854                 ViewState["HelpPageText"] = value;
855             }
856         }
857
858
859         /// <devdoc>
860         ///     Gets or sets the URL of the help page.
861         /// </devdoc>
862         [
863         WebCategory("Links"),
864         DefaultValue(""),
865         WebSysDescription(SR.LoginControls_HelpPageUrl),
866         Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
867         UrlProperty()
868         ]
869         public virtual string HelpPageUrl {
870             get {
871                 object obj = ViewState["HelpPageUrl"];
872                 return (obj == null) ? String.Empty : (string) obj;
873             }
874             set {
875                 ViewState["HelpPageUrl"] = value;
876             }
877         }
878
879
880         /// <devdoc>
881         ///     Gets the style of the hyperlinks.
882         /// </devdoc>
883         [
884         WebCategory("Styles"),
885         DefaultValue(null),
886         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
887         NotifyParentProperty(true),
888         PersistenceMode(PersistenceMode.InnerProperty),
889         WebSysDescription(SR.WebControl_HyperLinkStyle)
890         ]
891         public TableItemStyle HyperLinkStyle {
892             get {
893                 if (_hyperLinkStyle == null) {
894                     _hyperLinkStyle = new TableItemStyle();
895                     if (IsTrackingViewState) {
896                         ((IStateManager) _hyperLinkStyle).TrackViewState();
897                     }
898                 }
899                 return _hyperLinkStyle;
900             }
901         }
902
903
904
905         /// <devdoc>
906         ///     Gets or sets the text that is displayed to give instructions.
907         /// </devdoc>
908         [
909         Localizable(true),
910         WebCategory("Appearance"),
911         DefaultValue(""),
912         WebSysDescription(SR.WebControl_InstructionText)
913         ]
914         public virtual string InstructionText {
915             get {
916                 object obj = ViewState["InstructionText"];
917                 return (obj == null) ? String.Empty : (string) obj;
918             }
919             set {
920                 ViewState["InstructionText"] = value;
921             }
922         }
923
924
925         /// <devdoc>
926         ///     Gets the style of the instructions.
927         /// </devdoc>
928         [
929         WebCategory("Styles"),
930         DefaultValue(null),
931         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
932         NotifyParentProperty(true),
933         PersistenceMode(PersistenceMode.InnerProperty),
934         WebSysDescription(SR.WebControl_InstructionTextStyle)
935         ]
936         public TableItemStyle InstructionTextStyle {
937             get {
938                 if (_instructionTextStyle == null) {
939                     _instructionTextStyle = new TableItemStyle();
940                     if (IsTrackingViewState) {
941                         ((IStateManager) _instructionTextStyle).TrackViewState();
942                     }
943                 }
944                 return _instructionTextStyle;
945             }
946         }
947
948
949         /// <devdoc>
950         ///     Gets the style of the textbox labels.
951         /// </devdoc>
952         [
953         WebCategory("Styles"),
954         DefaultValue(null),
955         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
956         NotifyParentProperty(true),
957         PersistenceMode(PersistenceMode.InnerProperty),
958         WebSysDescription(SR.LoginControls_LabelStyle)
959         ]
960         public TableItemStyle LabelStyle {
961             get {
962                 if (_labelStyle == null) {
963                     _labelStyle = new TableItemStyle();
964                     if (IsTrackingViewState) {
965                         ((IStateManager) _labelStyle).TrackViewState();
966                     }
967                 }
968                 return _labelStyle;
969             }
970         }
971
972
973         /// <devdoc>
974         ///     Gets or sets the name of the membership provider.  If null or empty, the default provider is used.
975         /// </devdoc>
976         [
977         WebCategory("Data"),
978         DefaultValue(""),
979         Themeable(false),
980         WebSysDescription(SR.MembershipProvider_Name)
981         ]
982         public virtual string MembershipProvider {
983             get {
984                 object obj = ViewState["MembershipProvider"];
985                 return (obj == null) ? String.Empty : (string) obj;
986             }
987             set {
988                 ViewState["MembershipProvider"] = value;
989             }
990         }
991
992
993
994         /// <devdoc>
995         ///     Gets the new password entered by the user.
996         /// </devdoc>
997         [
998         Browsable(false),
999         Themeable(false),
1000         Filterable(false),
1001         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
1002         ]
1003         public virtual string NewPassword {
1004             get {
1005                 return (_newPassword == null) ? String.Empty : _newPassword;
1006             }
1007         }
1008
1009         private string NewPasswordInternal {
1010             get {
1011                 string password = NewPassword;
1012                 if (String.IsNullOrEmpty(password) && _changePasswordContainer != null) {
1013                     ITextControl passwordTextBox = (ITextControl)_changePasswordContainer.NewPasswordTextBox;
1014                     if (passwordTextBox != null) {
1015                         return passwordTextBox.Text;
1016                     }
1017                 }
1018                 return password;
1019             }
1020         }
1021
1022
1023         /// <devdoc>
1024         ///     The text that is displayed when the new password regular expression fails
1025         /// </devdoc>
1026         [
1027         WebCategory("Validation"),
1028         WebSysDefaultValue(SR.Password_InvalidPasswordErrorMessage),
1029         WebSysDescription(SR.ChangePassword_NewPasswordRegularExpressionErrorMessage)
1030         ]
1031         public virtual string NewPasswordRegularExpressionErrorMessage {
1032             get {
1033                 object obj = ViewState["NewPasswordRegularExpressionErrorMessage"];
1034                 return (obj == null) ?  SR.GetString(SR.Password_InvalidPasswordErrorMessage) : (string) obj;
1035             }
1036             set {
1037                 ViewState["NewPasswordRegularExpressionErrorMessage"] = value;
1038             }
1039         }
1040
1041
1042         /// <devdoc>
1043         ///     Gets or sets the text that identifies the new password textbox.
1044         /// </devdoc>
1045         [
1046         Localizable(true),
1047         WebCategory("Appearance"),
1048         WebSysDefaultValue(SR.ChangePassword_DefaultNewPasswordLabelText),
1049         WebSysDescription(SR.ChangePassword_NewPasswordLabelText)
1050         ]
1051         public virtual string NewPasswordLabelText {
1052             get {
1053                 object obj = ViewState["NewPasswordLabelText"];
1054                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultNewPasswordLabelText) : (string) obj;
1055             }
1056             set {
1057                 ViewState["NewPasswordLabelText"] = value;
1058             }
1059         }
1060
1061
1062         /// <devdoc>
1063         ///     Regular expression used to validate the new password
1064         /// </devdoc>
1065         [
1066         WebCategory("Validation"),
1067         WebSysDefaultValue(""),
1068         WebSysDescription(SR.ChangePassword_NewPasswordRegularExpression)
1069         ]
1070         public virtual string NewPasswordRegularExpression {
1071             get {
1072                 object obj = ViewState["NewPasswordRegularExpression"];
1073                 return (obj == null) ? String.Empty : (string) obj;
1074             }
1075             set {
1076                 if (NewPasswordRegularExpression != value) {
1077                     ViewState["NewPasswordRegularExpression"] = value;
1078                     UpdateValidators();
1079                 }
1080             }
1081         }
1082
1083
1084         /// <devdoc>
1085         ///     Gets or sets the text to be shown in the validation summary when the new password is empty.
1086         /// </devdoc>
1087         [
1088         Localizable(true),
1089         WebCategory("Validation"),
1090         WebSysDefaultValue(SR.ChangePassword_DefaultNewPasswordRequiredErrorMessage),
1091         WebSysDescription(SR.ChangePassword_NewPasswordRequiredErrorMessage)
1092         ]
1093         public virtual string NewPasswordRequiredErrorMessage {
1094             get {
1095                 object obj = ViewState["NewPasswordRequiredErrorMessage"];
1096                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultNewPasswordRequiredErrorMessage) : (string) obj;
1097             }
1098             set {
1099                 ViewState["NewPasswordRequiredErrorMessage"] = value;
1100             }
1101         }
1102
1103
1104         /// <devdoc>
1105         /// The style of the password hint text.
1106         /// </devdoc>
1107         [
1108         WebCategory("Styles"),
1109         DefaultValue(null),
1110         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
1111         NotifyParentProperty(true),
1112         PersistenceMode(PersistenceMode.InnerProperty),
1113         WebSysDescription(SR.ChangePassword_PasswordHintStyle)
1114         ]
1115         public TableItemStyle PasswordHintStyle {
1116             get {
1117                 if (_passwordHintStyle == null) {
1118                     _passwordHintStyle = new TableItemStyle();
1119                     if (IsTrackingViewState) {
1120                         ((IStateManager) _passwordHintStyle).TrackViewState();
1121                     }
1122                 }
1123                 return _passwordHintStyle;
1124             }
1125         }
1126
1127
1128         /// <devdoc>
1129         ///     Gets or sets the text to be shown for the password hint.
1130         /// </devdoc>
1131         [
1132         Localizable(true),
1133         WebCategory("Appearance"),
1134         DefaultValue(""),
1135         WebSysDescription(SR.ChangePassword_PasswordHintText)
1136         ]
1137         public virtual string PasswordHintText {
1138             get {
1139                 object obj = ViewState["PasswordHintText"];
1140                 return (obj == null) ? String.Empty : (string) obj;
1141             }
1142             set {
1143                 ViewState["PasswordHintText"] = value;
1144             }
1145         }
1146
1147
1148
1149         /// <devdoc>
1150         ///     Gets or sets the text that identifies the password textbox.
1151         /// </devdoc>
1152         [
1153         Localizable(true),
1154         WebCategory("Appearance"),
1155         WebSysDefaultValue(SR.LoginControls_DefaultPasswordLabelText),
1156         WebSysDescription(SR.LoginControls_PasswordLabelText)
1157         ]
1158         public virtual string PasswordLabelText {
1159             get {
1160                 object obj = ViewState["PasswordLabelText"];
1161                 return (obj == null) ? SR.GetString(SR.LoginControls_DefaultPasswordLabelText) : (string) obj;
1162             }
1163             set {
1164                 ViewState["PasswordLabelText"] = value;
1165             }
1166         }
1167
1168
1169         /// <devdoc>
1170         ///     Gets or sets the URL of an icon to be displayed for the password recovery link.
1171         /// </devdoc>
1172         [
1173         WebCategory("Links"),
1174         DefaultValue(""),
1175         WebSysDescription(SR.ChangePassword_PasswordRecoveryIconUrl),
1176         Editor("System.Web.UI.Design.ImageUrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
1177         UrlProperty()
1178         ]
1179         public virtual string PasswordRecoveryIconUrl {
1180             get {
1181                 object obj = ViewState["PasswordRecoveryIconUrl"];
1182                 return (obj == null) ? String.Empty : (string) obj;
1183             }
1184             set {
1185                 ViewState["PasswordRecoveryIconUrl"] = value;
1186             }
1187         }
1188
1189
1190         /// <devdoc>
1191         ///     Gets or sets the text to be shown for the password recovery link.
1192         /// </devdoc>
1193         [
1194         Localizable(true),
1195         WebCategory("Links"),
1196         DefaultValue(""),
1197         WebSysDescription(SR.ChangePassword_PasswordRecoveryText)
1198         ]
1199         public virtual string PasswordRecoveryText {
1200             get {
1201                 object obj = ViewState["PasswordRecoveryText"];
1202                 return (obj == null) ? String.Empty : (string) obj;
1203             }
1204             set {
1205                 ViewState["PasswordRecoveryText"] = value;
1206             }
1207         }
1208
1209
1210         /// <devdoc>
1211         ///     Gets or sets the URL of the password recovery page.
1212         /// </devdoc>
1213         [
1214         WebCategory("Links"),
1215         DefaultValue(""),
1216         WebSysDescription(SR.ChangePassword_PasswordRecoveryUrl),
1217         Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
1218         UrlProperty()
1219         ]
1220         public virtual string PasswordRecoveryUrl {
1221             get {
1222                 object obj = ViewState["PasswordRecoveryUrl"];
1223                 return (obj == null) ? String.Empty : (string) obj;
1224             }
1225             set {
1226                 ViewState["PasswordRecoveryUrl"] = value;
1227             }
1228         }
1229
1230
1231         /// <devdoc>
1232         ///     Gets or sets the text to be shown in the validation summary when the password is empty.
1233         /// </devdoc>
1234         [
1235         Localizable(true),
1236         WebCategory("Validation"),
1237         WebSysDefaultValue(SR.ChangePassword_DefaultPasswordRequiredErrorMessage),
1238         WebSysDescription(SR.ChangePassword_PasswordRequiredErrorMessage)
1239         ]
1240         public virtual string PasswordRequiredErrorMessage {
1241             get {
1242                 object obj = ViewState["PasswordRequiredErrorMessage"];
1243                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultPasswordRequiredErrorMessage) : (string) obj;
1244             }
1245             set {
1246                 ViewState["PasswordRequiredErrorMessage"] = value;
1247             }
1248         }
1249
1250         /// <devdoc>
1251         /// Determines whether we create the regular expression validator
1252         /// </devdoc>
1253         private bool RegExpEnabled {
1254             get {
1255                 return (NewPasswordRegularExpression.Length > 0);
1256             }
1257         }
1258
1259
1260         /// <devdoc>
1261         /// The content and format of the e-mail message that contains a successful change password notification.
1262         /// </devdoc>
1263         [
1264         WebCategory("Behavior"),
1265         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
1266         NotifyParentProperty(true),
1267         PersistenceMode(PersistenceMode.InnerProperty),
1268         Themeable(false),
1269         WebSysDescription(SR.ChangePassword_MailDefinition)
1270         ]
1271         public MailDefinition MailDefinition {
1272             get {
1273                 if (_mailDefinition == null) {
1274                     _mailDefinition = new MailDefinition();
1275                     if (IsTrackingViewState) {
1276                         ((IStateManager) _mailDefinition).TrackViewState();
1277                     }
1278                 }
1279                 return _mailDefinition;
1280             }
1281         }
1282
1283         [
1284         WebCategory("Layout"),
1285         DefaultValue(true),
1286         WebSysDescription(SR.LoginControls_RenderOuterTable),
1287         SuppressMessage("Microsoft.Security", "CA2119:SealMethodsThatSatisfyPrivateInterfaces",
1288             Justification = "Interface denotes existence of property, not used for security.")
1289         ]
1290         public virtual bool RenderOuterTable {
1291             get {
1292                 object obj = ViewState["RenderOuterTable"];
1293                 return (obj == null) ? true : (bool)obj;
1294             }
1295             set {
1296                 ViewState["RenderOuterTable"] = value;
1297             }
1298         }
1299
1300         /// <devdoc>
1301         /// The URL that the user is directed to after the password has been changed.
1302         /// If non-null, always redirect the user to this page after successful password change.  Else, perform the refresh action.
1303         /// </devdoc>
1304         [
1305         WebCategory("Behavior"),
1306         DefaultValue(""),
1307         WebSysDescription(SR.LoginControls_SuccessPageUrl),
1308         Editor("System.Web.UI.Design.UrlEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
1309         Themeable(false),
1310         UrlProperty()
1311         ]
1312         public virtual string SuccessPageUrl {
1313             get {
1314                 object obj = ViewState["SuccessPageUrl"];
1315                 return (obj == null) ? String.Empty : (string) obj;
1316             }
1317             set {
1318                 ViewState["SuccessPageUrl"] = value;
1319             }
1320         }
1321
1322
1323         /// <devdoc>
1324         /// Template rendered after the password has been changed.
1325         /// </devdoc>
1326         [
1327         Browsable(false),
1328         PersistenceMode(PersistenceMode.InnerProperty),
1329         TemplateContainer(typeof(ChangePassword))
1330         ]
1331         public virtual ITemplate SuccessTemplate {
1332             get {
1333                 return _successTemplate;
1334             }
1335             set {
1336                 _successTemplate = value;
1337                 ChildControlsCreated = false;
1338             }
1339         }
1340
1341         /// <devdoc>
1342         /// Internal because used from ChangePasswordAdapter.
1343         /// </devdoc>
1344         [
1345         Browsable(false),
1346         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
1347         ]
1348         public Control SuccessTemplateContainer {
1349             get {
1350                 EnsureChildControls();
1351                 return _successContainer;
1352             }
1353         }
1354
1355
1356         /// <devdoc>
1357         /// The text to be shown after the password has been changed.
1358         /// </devdoc>
1359         [
1360         Localizable(true),
1361         WebCategory("Appearance"),
1362         WebSysDefaultValue(SR.ChangePassword_DefaultSuccessText),
1363         WebSysDescription(SR.ChangePassword_SuccessText)
1364         ]
1365         public virtual string SuccessText {
1366             get {
1367                 object obj = ViewState["SuccessText"];
1368                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultSuccessText) : (string) obj;
1369             }
1370             set {
1371                 ViewState["SuccessText"] = value;
1372             }
1373         }
1374
1375
1376
1377
1378         /// <devdoc>
1379         /// The style of the success text.
1380         /// </devdoc>
1381         [
1382         WebCategory("Styles"),
1383         DefaultValue(null),
1384         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
1385         NotifyParentProperty(true),
1386         PersistenceMode(PersistenceMode.InnerProperty),
1387         WebSysDescription(SR.ChangePassword_SuccessTextStyle)
1388         ]
1389         public TableItemStyle SuccessTextStyle {
1390             get {
1391                 if (_successTextStyle == null) {
1392                     _successTextStyle = new TableItemStyle();
1393                     if (IsTrackingViewState) {
1394                         ((IStateManager) _successTextStyle).TrackViewState();
1395                     }
1396                 }
1397                 return _successTextStyle;
1398             }
1399         }
1400
1401
1402         /// <devdoc>
1403         ///     Gets or sets the title text to be shown for success
1404         /// </devdoc>
1405         [
1406         Localizable(true),
1407         WebCategory("Appearance"),
1408         WebSysDefaultValue(SR.ChangePassword_DefaultSuccessTitleText),
1409         WebSysDescription(SR.ChangePassword_SuccessTitleText)
1410         ]
1411         public virtual string SuccessTitleText {
1412             get {
1413                 object obj = ViewState["SuccessTitleText"];
1414                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultSuccessTitleText) : (string) obj;
1415             }
1416             set {
1417                 ViewState["SuccessTitleText"] = value;
1418             }
1419         }
1420
1421         protected override HtmlTextWriterTag TagKey {
1422             get {
1423                 return HtmlTextWriterTag.Table;
1424             }
1425         }
1426
1427
1428         /// <devdoc>
1429         ///     Gets or sets the style of the textboxes.
1430         /// </devdoc>
1431         [
1432         WebCategory("Styles"),
1433         DefaultValue(null),
1434         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
1435         NotifyParentProperty(true),
1436         PersistenceMode(PersistenceMode.InnerProperty),
1437         WebSysDescription(SR.LoginControls_TextBoxStyle)
1438         ]
1439         public Style TextBoxStyle {
1440             get {
1441                 if (_textBoxStyle == null) {
1442                     _textBoxStyle = new Style();
1443                     if (IsTrackingViewState) {
1444                         ((IStateManager) _textBoxStyle).TrackViewState();
1445                     }
1446                 }
1447                 return _textBoxStyle;
1448             }
1449         }
1450
1451
1452         /// <devdoc>
1453         ///     Gets the style of the title.
1454         /// </devdoc>
1455         [
1456         WebCategory("Styles"),
1457         DefaultValue(null),
1458         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
1459         NotifyParentProperty(true),
1460         PersistenceMode(PersistenceMode.InnerProperty),
1461         WebSysDescription(SR.LoginControls_TitleTextStyle)
1462         ]
1463         public TableItemStyle TitleTextStyle {
1464             get {
1465                 if (_titleTextStyle == null) {
1466                     _titleTextStyle = new TableItemStyle();
1467                     if (IsTrackingViewState) {
1468                         ((IStateManager) _titleTextStyle).TrackViewState();
1469                     }
1470                 }
1471                 return _titleTextStyle;
1472             }
1473         }
1474
1475
1476         /// <devdoc>
1477         ///     Gets or sets the initial value in the user name textbox.
1478         /// </devdoc>
1479         [
1480         WebCategory("Appearance"),
1481         DefaultValue(""),
1482         WebSysDescription(SR.UserName_InitialValue)
1483         ]
1484         public virtual string UserName {
1485             get {
1486                 return (_userName == null) ? String.Empty : _userName;
1487             }
1488             set {
1489                 _userName = value;
1490             }
1491         }
1492
1493         private string UserNameInternal {
1494             get {
1495                 string userName = UserName;
1496                 if (String.IsNullOrEmpty(userName) && _changePasswordContainer != null && DisplayUserName) {
1497                     ITextControl userTextBox = (ITextControl)_changePasswordContainer.UserNameTextBox;
1498                     if (userTextBox != null) {
1499                         return userTextBox.Text;
1500                     }
1501                 }
1502                 return userName;
1503             }
1504         }
1505
1506
1507         /// <devdoc>
1508         ///     Gets or sets the text that identifies the user name textbox.
1509         /// </devdoc>
1510         [
1511         Localizable(true),
1512         WebCategory("Appearance"),
1513         WebSysDefaultValue(SR.ChangePassword_DefaultUserNameLabelText),
1514         WebSysDescription(SR.LoginControls_UserNameLabelText)
1515         ]
1516         public virtual string UserNameLabelText {
1517             get {
1518                 object obj = ViewState["UserNameLabelText"];
1519                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultUserNameLabelText) : (string) obj;
1520             }
1521             set {
1522                 ViewState["UserNameLabelText"] = value;
1523             }
1524         }
1525
1526
1527
1528
1529         /// <devdoc>
1530         ///     Gets or sets the text to be shown in the validation summary when the user name is empty.
1531         /// </devdoc>
1532         [
1533         Localizable(true),
1534         WebCategory("Validation"),
1535         WebSysDefaultValue(SR.ChangePassword_DefaultUserNameRequiredErrorMessage),
1536         WebSysDescription(SR.ChangePassword_UserNameRequiredErrorMessage)
1537         ]
1538         public virtual string UserNameRequiredErrorMessage {
1539             get {
1540                 object obj = ViewState["UserNameRequiredErrorMessage"];
1541                 return (obj == null) ? SR.GetString(SR.ChangePassword_DefaultUserNameRequiredErrorMessage) : (string) obj;
1542             }
1543             set {
1544                 ViewState["UserNameRequiredErrorMessage"] = value;
1545             }
1546         }
1547
1548         internal Control ValidatorRow {
1549             get {
1550                 return _validatorRow;
1551             }
1552             set {
1553                 _validatorRow = value;
1554             }
1555         }
1556
1557         [
1558         WebCategory("Styles"),
1559         DefaultValue(null),
1560         DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
1561         NotifyParentProperty(true),
1562         PersistenceMode(PersistenceMode.InnerProperty),
1563         WebSysDescription(SR.ChangePassword_ValidatorTextStyle)
1564         ]
1565         public Style ValidatorTextStyle {
1566             get {
1567                 if (_validatorTextStyle == null) {
1568                     _validatorTextStyle = new ErrorStyle();
1569                     if (IsTrackingViewState) {
1570                         ((IStateManager) _validatorTextStyle).TrackViewState();
1571                     }
1572                 }
1573                 return _validatorTextStyle;
1574             }
1575         }
1576
1577         ///////////////////// EVENTS //////////////////////////////
1578
1579
1580         /// <devdoc>
1581         ///     Raised on the click of the cancel button.
1582         /// </devdoc>
1583         [
1584         WebCategory("Action"),
1585         WebSysDescription(SR.ChangePassword_CancelButtonClick)
1586         ]
1587         public event EventHandler CancelButtonClick {
1588             add {
1589                 Events.AddHandler(EventCancelButtonClick, value);
1590             }
1591             remove {
1592                 Events.RemoveHandler(EventCancelButtonClick, value);
1593             }
1594         }
1595
1596
1597         /// <devdoc>
1598         ///     Raised after the password has been changed successfully.
1599         /// </devdoc>
1600         [
1601         WebCategory("Action"),
1602         WebSysDescription(SR.ChangePassword_ChangedPassword)
1603         ]
1604         public event EventHandler ChangedPassword {
1605             add {
1606                 Events.AddHandler(EventChangedPassword, value);
1607             }
1608             remove {
1609                 Events.RemoveHandler(EventChangedPassword, value);
1610             }
1611         }
1612
1613
1614         /// <devdoc>
1615         ///     Raised if the change password attempt fails.
1616         /// </devdoc>
1617         [
1618         WebCategory("Action"),
1619         WebSysDescription(SR.ChangePassword_ChangePasswordError)
1620         ]
1621         public event EventHandler ChangePasswordError {
1622             add {
1623                 Events.AddHandler(EventChangePasswordError, value);
1624             }
1625             remove {
1626                 Events.RemoveHandler(EventChangePasswordError, value);
1627             }
1628         }
1629
1630
1631         /// <devdoc>
1632         ///     Raised before changing the password.
1633         /// </devdoc>
1634         [
1635         WebCategory("Action"),
1636         WebSysDescription(SR.ChangePassword_ChangingPassword)
1637         ]
1638         public event LoginCancelEventHandler ChangingPassword {
1639             add {
1640                 Events.AddHandler(EventChangingPassword, value);
1641             }
1642             remove {
1643                 Events.RemoveHandler(EventChangingPassword, value);
1644             }
1645         }
1646
1647
1648         /// <devdoc>
1649         ///     Raised on the click of the continue button.
1650         /// </devdoc>
1651         [
1652         WebCategory("Action"),
1653         WebSysDescription(SR.ChangePassword_ContinueButtonClick)
1654         ]
1655         public event EventHandler ContinueButtonClick {
1656             add {
1657                 Events.AddHandler(EventContinueButtonClick, value);
1658             }
1659             remove {
1660                 Events.RemoveHandler(EventContinueButtonClick, value);
1661             }
1662         }
1663
1664
1665         /// <devdoc>
1666         /// Raised before the e-mail is sent.
1667         /// </devdoc>
1668         [
1669         WebCategory("Action"),
1670         WebSysDescription(SR.ChangePassword_SendingMail)
1671         ]
1672         public event MailMessageEventHandler SendingMail {
1673             add {
1674                 Events.AddHandler(EventSendingMail, value);
1675             }
1676             remove {
1677                 Events.RemoveHandler(EventSendingMail, value);
1678             }
1679         }
1680
1681
1682         /// <devdoc>
1683         ///     Raised when there is an error sending mail.
1684         /// </devdoc>
1685         [
1686         WebCategory("Action"),
1687         WebSysDescription(SR.ChangePassword_SendMailError)
1688         ]
1689         public event SendMailErrorEventHandler SendMailError {
1690             add {
1691                 Events.AddHandler(EventSendMailError, value);
1692             }
1693             remove {
1694                 Events.RemoveHandler(EventSendMailError, value);
1695             }
1696         }
1697
1698         /// <devdoc>
1699         ///     Attempts to change the password for the user.
1700         ///     Raises appropriate events along the way for login, changing password, mail.
1701         /// </devdoc>
1702         private void AttemptChangePassword() {
1703             if (Page != null && !Page.IsValid) {
1704                 return;
1705             }
1706
1707             LoginCancelEventArgs cancelArgs = new LoginCancelEventArgs();
1708             OnChangingPassword(cancelArgs);
1709             if (cancelArgs.Cancel) {
1710                 return;
1711             }
1712
1713             MembershipProvider provider = LoginUtil.GetProvider(MembershipProvider);
1714             MembershipUser user = provider.GetUser(UserNameInternal, /*userIsOnline*/ false, /*throwOnError*/ false);
1715             string newPassword = NewPasswordInternal;
1716             if (user != null && user.ChangePassword(CurrentPasswordInternal, newPassword, /*throwOnError*/ false)) {
1717                 // Only log the user in if approved and not locked out
1718                 if (user.IsApproved && !user.IsLockedOut) {
1719                     System.Web.Security.FormsAuthentication.SetAuthCookie(UserNameInternal, false);
1720                 }
1721
1722                 OnChangedPassword(EventArgs.Empty);
1723                 PerformSuccessAction(user.Email, user.UserName, newPassword);
1724             }
1725             else {
1726                 OnChangePasswordError(EventArgs.Empty);
1727                 string failureText = ChangePasswordFailureText;
1728                 if (!String.IsNullOrEmpty(failureText)) {
1729                     failureText = String.Format(CultureInfo.CurrentCulture, failureText, provider.MinRequiredPasswordLength,
1730                         provider.MinRequiredNonAlphanumericCharacters);
1731                 }
1732                 SetFailureTextLabel(_changePasswordContainer, failureText);
1733             }
1734         }
1735
1736         private void ConfirmNewPasswordTextChanged(object source, EventArgs e) {
1737             _confirmNewPassword = ((ITextControl) source).Text;
1738         }
1739
1740         /// <devdoc>
1741         /// Creates the controls needed for the change password view
1742         /// </devdoc>
1743         private void CreateChangePasswordViewControls() {
1744             _changePasswordContainer = new ChangePasswordContainer(this);
1745             _changePasswordContainer.ID = _changePasswordViewContainerID;
1746             _changePasswordContainer.RenderDesignerRegion = _renderDesignerRegion;
1747
1748             ITemplate template = ChangePasswordTemplate;
1749             bool defaultTemplate = (template == null);
1750             if (defaultTemplate) {
1751                 // Only disable viewstate if using default template
1752                 _changePasswordContainer.EnableViewState = false;
1753
1754                 // Disable theming if using default template (VSWhidbey 86010)
1755                 _changePasswordContainer.EnableTheming = false;
1756
1757                 template = new DefaultChangePasswordTemplate(this);
1758            }
1759
1760             template.InstantiateIn(_changePasswordContainer);
1761             Controls.Add(_changePasswordContainer);
1762
1763             IEditableTextControl userNameTextBox = _changePasswordContainer.UserNameTextBox as IEditableTextControl;
1764             if (userNameTextBox != null) {
1765                 userNameTextBox.TextChanged += new EventHandler(UserNameTextChanged);
1766             }
1767
1768             IEditableTextControl passwordTextBox = _changePasswordContainer.CurrentPasswordTextBox as IEditableTextControl;
1769             if (passwordTextBox != null) {
1770                 passwordTextBox.TextChanged += new EventHandler(PasswordTextChanged);
1771             }
1772
1773             IEditableTextControl newPasswordTextBox = _changePasswordContainer.NewPasswordTextBox as IEditableTextControl;
1774             if (newPasswordTextBox != null) {
1775                 newPasswordTextBox.TextChanged += new EventHandler(NewPasswordTextChanged);
1776             }
1777
1778             IEditableTextControl confirmNewPasswordTextBox = _changePasswordContainer.ConfirmNewPasswordTextBox as IEditableTextControl;
1779             if (confirmNewPasswordTextBox != null) {
1780                 confirmNewPasswordTextBox.TextChanged += new EventHandler(ConfirmNewPasswordTextChanged);
1781             }
1782
1783             // Set the editable child control properties here for two reasons:
1784             // - So change events will be raised if viewstate is disabled on the child controls
1785             //   - Viewstate is always disabled for default template, and might be for user template
1786             // - So the controls render correctly in the designer
1787             SetEditableChildProperties();
1788         }
1789
1790
1791         /// <devdoc>
1792         ///     Instantiates the template in the template container, and wires up necessary events.
1793         /// </devdoc>
1794         protected internal override void CreateChildControls() {
1795             Controls.Clear();
1796
1797             CreateChangePasswordViewControls();
1798             CreateSuccessViewControls();
1799             UpdateValidators();
1800         }
1801
1802         private void CreateSuccessViewControls() {
1803             ITemplate template = null;
1804             _successContainer = new SuccessContainer(this);
1805             _successContainer.ID = _successViewContainerID;
1806             _successContainer.RenderDesignerRegion = _renderDesignerRegion;
1807             if (SuccessTemplate != null) {
1808                 template = SuccessTemplate;
1809             }
1810             else {
1811                 // 
1812                 template = new DefaultSuccessTemplate(this);
1813                 _successContainer.EnableViewState = false;
1814
1815                 // Disable theming if using default template (VSWhidbey 86010)
1816                 _successContainer.EnableTheming = false;
1817             }
1818             template.InstantiateIn(_successContainer);
1819             Controls.Add(_successContainer);
1820         }
1821
1822         /// <devdoc>
1823         /// Loads the control state for those properties that should persist across postbacks
1824         /// even when EnableViewState=false.
1825         /// </devdoc>
1826         protected internal override void LoadControlState(object savedState) {
1827             if (savedState != null) {
1828                 Triplet state = (Triplet)savedState;
1829                 if (state.First != null) {
1830                     base.LoadControlState(state.First);
1831                 }
1832                 if (state.Second != null) {
1833                     _currentView = (View)(int)state.Second;
1834                 }
1835                 if (state.Third != null) {
1836                     _userName = (string)state.Third;
1837                 }
1838             }
1839         }
1840
1841
1842         /// <internalonly/>
1843         /// <devdoc>
1844         ///     Loads a saved state of the <see cref='System.Web.UI.WebControls.ChangePassword'/>.
1845         /// </devdoc>
1846         protected override void LoadViewState(object savedState) {
1847             if (savedState == null) {
1848                 base.LoadViewState(null);
1849             }
1850             else {
1851                 object[] myState = (object[]) savedState;
1852                 if (myState.Length != _viewStateArrayLength) {
1853                     throw new ArgumentException(SR.GetString(SR.ViewState_InvalidViewState));
1854                 }
1855
1856                 base.LoadViewState(myState[0]);
1857                 if (myState[1] != null) {
1858                     ((IStateManager) ChangePasswordButtonStyle).LoadViewState(myState[1]);
1859                 }
1860                 if (myState[2] != null) {
1861                     ((IStateManager) LabelStyle).LoadViewState(myState[2]);
1862                 }
1863                 if (myState[3] != null) {
1864                     ((IStateManager) TextBoxStyle).LoadViewState(myState[3]);
1865                 }
1866                 if (myState[4] != null) {
1867                     ((IStateManager) HyperLinkStyle).LoadViewState(myState[4]);
1868                 }
1869                 if (myState[5] != null) {
1870                     ((IStateManager) InstructionTextStyle).LoadViewState(myState[5]);
1871                 }
1872                 if (myState[6] != null) {
1873                     ((IStateManager) TitleTextStyle).LoadViewState(myState[6]);
1874                 }
1875                 if (myState[7] != null) {
1876                     ((IStateManager) PasswordHintStyle).LoadViewState(myState[7]);
1877                 }
1878                 if (myState[8] != null) {
1879                     ((IStateManager) FailureTextStyle).LoadViewState(myState[8]);
1880                 }
1881                 if (myState[9] != null) {
1882                     ((IStateManager) MailDefinition).LoadViewState(myState[9]);
1883                 }
1884                 if (myState[10] != null) {
1885                     ((IStateManager) CancelButtonStyle).LoadViewState(myState[10]);
1886                 }
1887                 if (myState[11] != null) {
1888                     ((IStateManager) ContinueButtonStyle).LoadViewState(myState[11]);
1889                 }
1890                 if (myState[12] != null) {
1891                     ((IStateManager) SuccessTextStyle).LoadViewState(myState[12]);
1892                 }
1893                 if (myState[13] != null) {
1894                     ((IStateManager) ValidatorTextStyle).LoadViewState(myState[13]);
1895                 }
1896             }
1897
1898             UpdateValidators();
1899         }
1900
1901         private void NewPasswordTextChanged(object source, EventArgs e) {
1902             _newPassword = ((ITextControl) source).Text;
1903         }
1904
1905
1906         /// <devdoc>
1907         /// Called when an event is raised by a control inside our template.  Attempts to login
1908         /// if the event was raised by the submit button.
1909         /// </devdoc>
1910         protected override bool OnBubbleEvent(object source, EventArgs e) {
1911             bool handled = false;
1912             if (e is CommandEventArgs) {
1913                 CommandEventArgs ce = (CommandEventArgs) e;
1914                 if (ce.CommandName.Equals(ChangePasswordButtonCommandName, StringComparison.CurrentCultureIgnoreCase)) {
1915                     AttemptChangePassword();
1916                     handled = true;
1917                 }
1918                 else if (ce.CommandName.Equals(CancelButtonCommandName, StringComparison.CurrentCultureIgnoreCase)) {
1919                     OnCancelButtonClick(ce);
1920                     handled = true;
1921                 }
1922                 else if (ce.CommandName.Equals(ContinueButtonCommandName, StringComparison.CurrentCultureIgnoreCase)) {
1923                     OnContinueButtonClick(ce);
1924                     handled = true;
1925                 }
1926             }
1927             return handled;
1928         }
1929
1930
1931         /// <devdoc>
1932         ///     Raises the CancelClick event.
1933         /// </devdoc>
1934         protected virtual void OnCancelButtonClick(EventArgs e) {
1935             EventHandler handler = (EventHandler)Events[EventCancelButtonClick];
1936             if (handler != null) {
1937                 handler(this, e);
1938             }
1939
1940             string cancelPageUrl = CancelDestinationPageUrl;
1941             if (!String.IsNullOrEmpty(cancelPageUrl)) {
1942                 // Microsoft suggested that we should not terminate execution of current page, to give
1943                 // page a chance to cleanup its resources.  This may be less performant though.
1944                 // Microsoft suggested that we need to call ResolveClientUrl before redirecting.
1945                 // Example is this control inside user control, want redirect relative to user control dir.
1946                 Page.Response.Redirect(ResolveClientUrl(cancelPageUrl), false);
1947             }
1948         }
1949
1950
1951         /// <devdoc>
1952         ///     Raises the ChangedPassword event.
1953         /// </devdoc>
1954         protected virtual void OnChangedPassword(EventArgs e) {
1955             EventHandler handler = (EventHandler)Events[EventChangedPassword];
1956             if (handler != null) {
1957                 handler(this, e);
1958             }
1959         }
1960
1961
1962         /// <devdoc>
1963         ///     Raises the ChangePasswordError event.
1964         /// </devdoc>
1965         protected virtual void OnChangePasswordError(EventArgs e) {
1966             EventHandler handler = (EventHandler)Events[EventChangePasswordError];
1967             if (handler != null) {
1968                 handler(this, e);
1969             }
1970         }
1971
1972
1973         /// <devdoc>
1974         ///     Raises the ChangingPassword event.
1975         /// </devdoc>
1976         protected virtual void OnChangingPassword(LoginCancelEventArgs e) {
1977             LoginCancelEventHandler handler = (LoginCancelEventHandler)Events[EventChangingPassword];
1978             if (handler != null) {
1979                 handler(this, e);
1980             }
1981         }
1982
1983
1984         /// <devdoc>
1985         ///     Raises the ContinueButtonClick event.
1986         /// </devdoc>
1987         protected virtual void OnContinueButtonClick(EventArgs e) {
1988             EventHandler handler = (EventHandler)Events[EventContinueButtonClick];
1989             if (handler != null) {
1990                 handler(this, e);
1991             }
1992
1993             string continuePageUrl = ContinueDestinationPageUrl;
1994             if (!String.IsNullOrEmpty(continuePageUrl)) {
1995
1996                 // Microsoft suggested that we should not terminate execution of current page, to give
1997                 // page a chance to cleanup its resources.  This may be less performant though.
1998                 // Microsoft suggested that we need to call ResolveClientUrl before redirecting.
1999                 // Example is this control inside user control, want redirect relative to user control dir.
2000                 Page.Response.Redirect(ResolveClientUrl(continuePageUrl), false);
2001             }
2002        }
2003
2004
2005         protected internal override void OnInit(EventArgs e) {
2006             // Fill in the User name if authenticated
2007             if (!DesignMode) {
2008                 string userName = LoginUtil.GetUserName(this);
2009                 if (!String.IsNullOrEmpty(userName)) {
2010                     UserName = userName;
2011                 }
2012             }
2013
2014             base.OnInit(e);
2015             Page.RegisterRequiresControlState(this);
2016         }
2017
2018
2019         /// <devdoc>
2020         ///     Overridden to set the editable child control properteries and hide the control when appropriate.
2021         /// </devdoc>
2022         protected internal override void OnPreRender(EventArgs e) {
2023             base.OnPreRender(e);
2024
2025             // Set the editable child control properties here instead of Render, so they get into viewstate for the user template.
2026             switch (CurrentView) {
2027                 case View.ChangePassword:
2028                     SetEditableChildProperties();
2029                     break;
2030             }
2031         }
2032
2033
2034         /// <devdoc>
2035         /// Raises the SendingMail event.
2036         /// </devdoc>
2037         protected virtual void OnSendingMail(MailMessageEventArgs e) {
2038             MailMessageEventHandler handler = (MailMessageEventHandler)Events[EventSendingMail];
2039             if (handler != null) {
2040                 handler(this, e);
2041             }
2042         }
2043
2044
2045         /// <devdoc>
2046         /// Raises the SendMailError event.
2047         /// </devdoc>
2048         protected virtual void OnSendMailError(SendMailErrorEventArgs e) {
2049             SendMailErrorEventHandler handler = (SendMailErrorEventHandler)Events[EventSendMailError];
2050             if (handler != null) {
2051                 handler(this, e);
2052             }
2053         }
2054
2055         private void PasswordTextChanged(object source, EventArgs e) {
2056             _password = ((ITextControl) source).Text;
2057         }
2058
2059         private void PerformSuccessAction(string email, string userName, string newPassword) {
2060             // Try to send mail only if a MailDefinition is specified for success,
2061             // and the user has an email address.
2062             if (_mailDefinition != null && !String.IsNullOrEmpty(email)) {
2063                 LoginUtil.SendPasswordMail(email, userName, newPassword, MailDefinition, /*defaultSubject*/ null,
2064                                            /*defaultBody*/ null, OnSendingMail, OnSendMailError, this);
2065             }
2066
2067             string successPageUrl = SuccessPageUrl;
2068             if (!String.IsNullOrEmpty(successPageUrl)) {
2069                 // Microsoft suggested that we should not terminate execution of current page, to give
2070                 // page a chance to cleanup its resources.  This may be less performant though.
2071                 // Microsoft suggested that we need to call ResolveClientUrl before redirecting.
2072                 // Example is this control inside user control, want redirect relative to user control dir.
2073                 Page.Response.Redirect(ResolveClientUrl(successPageUrl), false);
2074             }
2075             else {
2076                 CurrentView = View.Success;
2077             }
2078         }
2079
2080
2081         /// <devdoc>
2082         ///     Adds the ClientID and renders contents, because we don't want the outer <span>.
2083         /// </devdoc>
2084         protected internal override void Render(HtmlTextWriter writer) {
2085             if (Page != null) {
2086                 Page.VerifyRenderingInServerForm(this);
2087             }
2088             
2089             // Copied from CompositeControl.cs
2090             if (DesignMode) {
2091                 ChildControlsCreated = false;
2092             }
2093             EnsureChildControls();
2094
2095             SetChildProperties();
2096             RenderContents(writer);
2097         }
2098
2099
2100         /// <devdoc>
2101         /// Saves the control state for those properties that should persist across postbacks
2102         /// even when EnableViewState=false.
2103         /// </devdoc>
2104         protected internal override object SaveControlState() {
2105             object baseState = base.SaveControlState();
2106
2107             // Save the int value of the enum (instead of the enum value itself)
2108             // to save space in ControlState
2109             object currentViewState = null;
2110             object userNameState = null;
2111
2112             currentViewState = (int)_currentView;
2113
2114             // Don't save _userName once we have reached the success view (VSWhidbey 81327)
2115             if (_userName != null && _currentView != View.Success) {
2116                 userNameState = _userName;
2117             }
2118             return new Triplet(baseState, currentViewState, userNameState);
2119         }
2120
2121
2122         /// <internalonly/>
2123         /// <devdoc>
2124         ///     Saves the state of the <see cref='System.Web.UI.WebControls.ChangePassword'/>.
2125         /// </devdoc>
2126         protected override object SaveViewState() {
2127             object[] myState = new object[_viewStateArrayLength];
2128
2129             myState[0] = base.SaveViewState();
2130             myState[1] = (_changePasswordButtonStyle != null) ? ((IStateManager)_changePasswordButtonStyle).SaveViewState() : null;
2131             myState[2] = (_labelStyle != null) ? ((IStateManager)_labelStyle).SaveViewState() : null;
2132             myState[3] = (_textBoxStyle != null) ? ((IStateManager)_textBoxStyle).SaveViewState() : null;
2133             myState[4] = (_hyperLinkStyle != null) ? ((IStateManager)_hyperLinkStyle).SaveViewState() : null;
2134             myState[5] =
2135                 (_instructionTextStyle != null) ? ((IStateManager)_instructionTextStyle).SaveViewState() : null;
2136             myState[6] = (_titleTextStyle != null) ? ((IStateManager)_titleTextStyle).SaveViewState() : null;
2137             myState[7] = (_passwordHintStyle != null) ? ((IStateManager)_passwordHintStyle).SaveViewState() : null;
2138             myState[8] =
2139                 (_failureTextStyle != null) ? ((IStateManager)_failureTextStyle).SaveViewState() : null;
2140             myState[9] = (_mailDefinition != null) ? ((IStateManager)_mailDefinition).SaveViewState() : null;
2141             myState[10] = (_cancelButtonStyle != null) ? ((IStateManager)_cancelButtonStyle).SaveViewState() : null;
2142             myState[11] = (_continueButtonStyle != null) ? ((IStateManager)_continueButtonStyle).SaveViewState() : null;
2143             myState[12] = (_successTextStyle != null) ? ((IStateManager)_successTextStyle).SaveViewState() : null;
2144             myState[13] = (_validatorTextStyle != null) ? ((IStateManager)_validatorTextStyle).SaveViewState() : null;
2145
2146             for (int i=0; i < _viewStateArrayLength; i++) {
2147                 if (myState[i] != null) {
2148                     return myState;
2149                 }
2150             }
2151
2152             // More performant to return null than an array of null values
2153             return null;
2154         }
2155
2156         /// <devdoc>
2157         /// Used frequently, so extracted into method.
2158         /// </devdoc>
2159         private void SetFailureTextLabel(ChangePasswordContainer container, string failureText) {
2160             ITextControl failureTextLabel = (ITextControl)container.FailureTextLabel;
2161             if (failureTextLabel != null) {
2162                 failureTextLabel.Text = failureText;
2163             }
2164         }
2165
2166         /// <devdoc>
2167         ///     Internal for access from LoginAdapter
2168         /// </devdoc>
2169         internal void SetChildProperties() {
2170             switch (CurrentView) {
2171             case View.ChangePassword:
2172                 SetCommonChangePasswordViewProperties();
2173                 if (ChangePasswordTemplate == null) {
2174                     SetDefaultChangePasswordViewProperties();
2175                 }
2176                 break;
2177             case View.Success:
2178                 SetCommonSuccessViewProperties();
2179                 if (SuccessTemplate == null) {
2180                     SetDefaultSuccessViewProperties();
2181                 }
2182                 break;
2183             }
2184         }
2185
2186         /// <devdoc>
2187         ///     Sets change password view control properties that apply to both default and user templates.
2188         /// </devdoc>
2189         private void SetCommonChangePasswordViewProperties() {
2190             // Clear out the access key/tab index so it doesn't get applied to the tables in the container
2191             Util.CopyBaseAttributesToInnerControl(this, _changePasswordContainer);
2192
2193             _changePasswordContainer.ApplyStyle(ControlStyle);
2194             _successContainer.Visible = false;
2195         }
2196
2197         /// <devdoc>
2198         ///     Sets success view control properties that apply to both default and user templates.
2199         /// </devdoc>
2200         private void SetCommonSuccessViewProperties() {
2201             // Clear out the tab index so it doesn't get applied to the tables in the container
2202             Util.CopyBaseAttributesToInnerControl(this, _successContainer);
2203
2204             _successContainer.ApplyStyle(ControlStyle);
2205             _changePasswordContainer.Visible = false;
2206         }
2207
2208
2209         /// <internalonly/>
2210         /// <devdoc>
2211         /// Allows the designer to set the CurrentView, so the different templates can be shown in the designer.
2212         /// </devdoc>
2213         [SecurityPermission(SecurityAction.Demand, Unrestricted = true)]
2214         protected override void SetDesignModeState(IDictionary data) {
2215             if (data != null) {
2216                 object o = data["CurrentView"];
2217                 if (o != null) {
2218                     CurrentView = (View)o;
2219                 }
2220                 o = data["ConvertToTemplate"];
2221                 if (o != null) {
2222                     _convertingToTemplate = (bool)o;
2223                 }
2224                 o = data["RegionEditing"];
2225                 if (o != null) {
2226                     _renderDesignerRegion = (bool)o;
2227                 }
2228             }
2229         }
2230
2231
2232         /// <devdoc>
2233         ///     Sets child control properties that apply only to the default template.
2234         /// </devdoc>
2235         private void SetDefaultChangePasswordViewProperties() {
2236             ChangePasswordContainer container = _changePasswordContainer;
2237
2238             // Need to set the BorderPadding on the BorderTable instead of the LayoutTable, since
2239             // setting it on the LayoutTable would cause all of the controls inside the Login to be
2240             // separated by the BorderPadding amount.
2241             container.BorderTable.CellPadding = BorderPadding;
2242             container.BorderTable.CellSpacing = 0;
2243
2244             LoginUtil.ApplyStyleToLiteral(container.Title, ChangePasswordTitleText, TitleTextStyle, true);
2245             LoginUtil.ApplyStyleToLiteral(container.Instruction, InstructionText, InstructionTextStyle, true);
2246             LoginUtil.ApplyStyleToLiteral(container.UserNameLabel, UserNameLabelText, LabelStyle, false);
2247             LoginUtil.ApplyStyleToLiteral(container.CurrentPasswordLabel, PasswordLabelText, LabelStyle, false);
2248             LoginUtil.ApplyStyleToLiteral(container.NewPasswordLabel, NewPasswordLabelText, LabelStyle, false);
2249             LoginUtil.ApplyStyleToLiteral(container.ConfirmNewPasswordLabel, ConfirmNewPasswordLabelText, LabelStyle, false);
2250             LoginUtil.ApplyStyleToLiteral(container.PasswordHintLabel, PasswordHintText, PasswordHintStyle, false);
2251
2252             // Apply style to all the text boxes if necessary
2253             if (_textBoxStyle != null) {
2254                 if (DisplayUserName) ((WebControl)container.UserNameTextBox).ApplyStyle(TextBoxStyle);
2255                 ((WebControl)container.CurrentPasswordTextBox).ApplyStyle(TextBoxStyle);
2256                 ((WebControl)container.NewPasswordTextBox).ApplyStyle(TextBoxStyle);
2257                 ((WebControl)container.ConfirmNewPasswordTextBox).ApplyStyle(TextBoxStyle);
2258             }
2259
2260             _passwordHintTableRow.Visible = !String.IsNullOrEmpty(PasswordHintText);
2261             _userNameTableRow.Visible = DisplayUserName;
2262
2263             // Tab Index
2264             if (DisplayUserName) {
2265                 ((WebControl)container.UserNameTextBox).TabIndex = TabIndex;
2266                 ((WebControl)container.UserNameTextBox).AccessKey = AccessKey;
2267             } else {
2268                 ((WebControl)container.CurrentPasswordTextBox).AccessKey = AccessKey;
2269             }
2270             ((WebControl)container.CurrentPasswordTextBox).TabIndex = TabIndex;
2271             ((WebControl)container.NewPasswordTextBox).TabIndex = TabIndex;
2272             ((WebControl)container.ConfirmNewPasswordTextBox).TabIndex = TabIndex;
2273
2274             // Validator setup
2275             bool enableValidation = true;
2276             ValidatorRow.Visible = enableValidation;
2277
2278             RequiredFieldValidator userNameRequired = container.UserNameRequired;
2279             userNameRequired.ErrorMessage = UserNameRequiredErrorMessage;
2280             userNameRequired.ToolTip = UserNameRequiredErrorMessage;
2281             userNameRequired.Enabled = enableValidation;
2282             userNameRequired.Visible = enableValidation;
2283             if (_validatorTextStyle != null) {
2284                 userNameRequired.ApplyStyle(_validatorTextStyle);
2285             }
2286
2287             RequiredFieldValidator passwordRequired = container.PasswordRequired;
2288             passwordRequired.ErrorMessage = PasswordRequiredErrorMessage;
2289             passwordRequired.ToolTip = PasswordRequiredErrorMessage;
2290             passwordRequired.Enabled = enableValidation;
2291             passwordRequired.Visible = enableValidation;
2292
2293             RequiredFieldValidator newPasswordRequired = container.NewPasswordRequired;
2294             newPasswordRequired.ErrorMessage = NewPasswordRequiredErrorMessage;
2295             newPasswordRequired.ToolTip = NewPasswordRequiredErrorMessage;
2296             newPasswordRequired.Enabled = enableValidation;
2297             newPasswordRequired.Visible = enableValidation;
2298
2299             RequiredFieldValidator confirmNewPasswordRequired = container.ConfirmNewPasswordRequired;
2300             confirmNewPasswordRequired.ErrorMessage = ConfirmPasswordRequiredErrorMessage;
2301             confirmNewPasswordRequired.ToolTip = ConfirmPasswordRequiredErrorMessage;
2302             confirmNewPasswordRequired.Enabled = enableValidation;
2303             confirmNewPasswordRequired.Visible = enableValidation;
2304
2305             CompareValidator newPasswordCompareValidator = container.NewPasswordCompareValidator;
2306             newPasswordCompareValidator.ErrorMessage = ConfirmPasswordCompareErrorMessage;
2307             newPasswordCompareValidator.Enabled = enableValidation;
2308             newPasswordCompareValidator.Visible = enableValidation;
2309
2310             if (_validatorTextStyle != null) {
2311                 passwordRequired.ApplyStyle(_validatorTextStyle);
2312                 newPasswordRequired.ApplyStyle(_validatorTextStyle);
2313                 confirmNewPasswordRequired.ApplyStyle(_validatorTextStyle);
2314                 newPasswordCompareValidator.ApplyStyle(_validatorTextStyle);
2315             }
2316
2317             RegularExpressionValidator regExpValidator = container.RegExpValidator;
2318             regExpValidator.ErrorMessage = NewPasswordRegularExpressionErrorMessage;
2319             regExpValidator.Enabled = enableValidation;
2320             regExpValidator.Visible = enableValidation;
2321             if (_validatorTextStyle != null) {
2322                 regExpValidator.ApplyStyle(_validatorTextStyle);
2323             }
2324
2325             //Button setup
2326             LinkButton linkButton = container.ChangePasswordLinkButton;
2327             LinkButton cancelLinkButton = container.CancelLinkButton;
2328             ImageButton imageButton = container.ChangePasswordImageButton;
2329             ImageButton cancelImageButton = container.CancelImageButton;
2330             Button pushButton = container.ChangePasswordPushButton;
2331             Button cancelPushButton = container.CancelPushButton;
2332
2333             WebControl changePasswordButton = null;
2334             WebControl cancelButton = null;
2335             switch (CancelButtonType) {
2336                 case ButtonType.Link:
2337                     cancelLinkButton.Text = CancelButtonText;
2338                     cancelButton = cancelLinkButton;
2339                     break;
2340                 case ButtonType.Image:
2341                     cancelImageButton.ImageUrl = CancelButtonImageUrl;
2342                     cancelImageButton.AlternateText = CancelButtonText;
2343                     cancelButton = cancelImageButton;
2344                     break;
2345                 case ButtonType.Button:
2346                     cancelPushButton.Text = CancelButtonText;
2347                     cancelButton = cancelPushButton;
2348                     break;
2349             }
2350             switch (ChangePasswordButtonType) {
2351                 case ButtonType.Link:
2352                     linkButton.Text = ChangePasswordButtonText;
2353                     changePasswordButton = linkButton;
2354                     break;
2355                 case ButtonType.Image:
2356                     imageButton.ImageUrl = ChangePasswordButtonImageUrl;
2357                     imageButton.AlternateText = ChangePasswordButtonText;
2358                     changePasswordButton = imageButton;
2359                     break;
2360                 case ButtonType.Button:
2361                     pushButton.Text = ChangePasswordButtonText;
2362                     changePasswordButton = pushButton;
2363                     break;
2364             }
2365
2366             // Set all buttons to nonvisible, then set the selected button to visible
2367             linkButton.Visible = false;
2368             imageButton.Visible = false;
2369             pushButton.Visible = false;
2370             cancelLinkButton.Visible = false;
2371             cancelImageButton.Visible = false;
2372             cancelPushButton.Visible = false;
2373             changePasswordButton.Visible = true;
2374             cancelButton.Visible = true;
2375             cancelButton.TabIndex = TabIndex;
2376             changePasswordButton.TabIndex = TabIndex;
2377
2378             if (CancelButtonStyle != null) cancelButton.ApplyStyle(CancelButtonStyle);
2379             if (ChangePasswordButtonStyle != null) changePasswordButton.ApplyStyle(ChangePasswordButtonStyle);
2380
2381             // Link Setup
2382             Image createUserIcon = container.CreateUserIcon;
2383             HyperLink createUserLink = container.CreateUserLink;
2384             LiteralControl createUserLinkSeparator = container.CreateUserLinkSeparator;
2385             HyperLink passwordRecoveryLink = container.PasswordRecoveryLink;
2386             Image passwordRecoveryIcon = container.PasswordRecoveryIcon;
2387             HyperLink helpPageLink = container.HelpPageLink;
2388             Image helpPageIcon = container.HelpPageIcon;
2389             LiteralControl helpPageLinkSeparator = container.HelpPageLinkSeparator;
2390             LiteralControl editProfileLinkSeparator = container.EditProfileLinkSeparator;
2391             HyperLink editProfileLink = container.EditProfileLink;
2392             Image editProfileIcon = container.EditProfileIcon;
2393             string createUserText = CreateUserText;
2394             string createUserIconUrl = CreateUserIconUrl;
2395             string passwordRecoveryText = PasswordRecoveryText;
2396             string passwordRecoveryIconUrl = PasswordRecoveryIconUrl;
2397             string helpPageText = HelpPageText;
2398             string helpPageIconUrl = HelpPageIconUrl;
2399             string editProfileText = EditProfileText;
2400             string editProfileIconUrl = EditProfileIconUrl;
2401             bool createUserTextVisible = (createUserText.Length > 0);
2402             bool passwordRecoveryTextVisible = (passwordRecoveryText.Length > 0);
2403             bool helpPageTextVisible = (helpPageText.Length > 0);
2404             bool helpPageIconVisible = (helpPageIconUrl.Length > 0);
2405             bool createUserIconVisible = (createUserIconUrl.Length > 0);
2406             bool passwordRecoveryIconVisible = (passwordRecoveryIconUrl.Length > 0);
2407             bool helpPageLineVisible = helpPageTextVisible || helpPageIconVisible;
2408             bool createUserLineVisible = createUserTextVisible || createUserIconVisible;
2409             bool passwordRecoveryLineVisible = passwordRecoveryTextVisible || passwordRecoveryIconVisible;
2410             bool editProfileTextVisible = (editProfileText.Length > 0);
2411             bool editProfileIconVisible = (editProfileIconUrl.Length > 0);
2412             bool editProfileLineVisible = (editProfileTextVisible || editProfileIconVisible);
2413
2414             helpPageLink.Visible = helpPageTextVisible;
2415             helpPageLinkSeparator.Visible = helpPageLineVisible && (passwordRecoveryLineVisible || createUserLineVisible || editProfileLineVisible);
2416             if (helpPageTextVisible) {
2417                 helpPageLink.Text = helpPageText;
2418                 helpPageLink.NavigateUrl = HelpPageUrl;
2419                 helpPageLink.TabIndex = TabIndex;
2420             }
2421             helpPageIcon.Visible = helpPageIconVisible;
2422             if (helpPageIconVisible) {
2423                 helpPageIcon.ImageUrl = helpPageIconUrl;
2424                 helpPageIcon.AlternateText = HelpPageText;
2425             }
2426
2427             createUserLink.Visible = createUserTextVisible;
2428             createUserLinkSeparator.Visible = (createUserLineVisible && (passwordRecoveryLineVisible || editProfileLineVisible));
2429             if (createUserTextVisible) {
2430                 createUserLink.Text = createUserText;
2431                 createUserLink.NavigateUrl = CreateUserUrl;
2432                 createUserLink.TabIndex = TabIndex;
2433             }
2434             createUserIcon.Visible = createUserIconVisible;
2435             if (createUserIconVisible) {
2436                 createUserIcon.ImageUrl = createUserIconUrl;
2437                 createUserIcon.AlternateText = CreateUserText;
2438             }
2439
2440             passwordRecoveryLink.Visible = passwordRecoveryTextVisible;
2441             if (passwordRecoveryTextVisible) {
2442                 passwordRecoveryLink.Text = passwordRecoveryText;
2443                 passwordRecoveryLink.NavigateUrl = PasswordRecoveryUrl;
2444                 passwordRecoveryLink.TabIndex = TabIndex;
2445             }
2446             passwordRecoveryIcon.Visible = passwordRecoveryIconVisible;
2447             if (passwordRecoveryIconVisible) {
2448                 passwordRecoveryIcon.ImageUrl = passwordRecoveryIconUrl;
2449                 passwordRecoveryIcon.AlternateText = PasswordRecoveryText;
2450             }
2451             editProfileLinkSeparator.Visible = (passwordRecoveryLineVisible && editProfileLineVisible);
2452
2453             editProfileLink.Visible = editProfileTextVisible;
2454             editProfileIcon.Visible = editProfileIconVisible;
2455             if (editProfileTextVisible) {
2456                 editProfileLink.Text = editProfileText;
2457                 editProfileLink.NavigateUrl = EditProfileUrl;
2458                 editProfileLink.TabIndex = TabIndex;
2459             }
2460             if (editProfileIconVisible) {
2461                 editProfileIcon.ImageUrl = editProfileIconUrl;
2462                 editProfileIcon.AlternateText = EditProfileText;
2463             }
2464
2465             if (createUserLineVisible || passwordRecoveryLineVisible || helpPageLineVisible || editProfileLineVisible) {
2466                 if (_hyperLinkStyle != null) {
2467                     // Apply style except font to table cell, then apply font and forecolor to HyperLinks
2468                     // VSWhidbey 81289
2469                     TableItemStyle hyperLinkStyleExceptFont = new TableItemStyle();
2470                     hyperLinkStyleExceptFont.CopyFrom(_hyperLinkStyle);
2471                     hyperLinkStyleExceptFont.Font.Reset();
2472                     LoginUtil.SetTableCellStyle(createUserLink, hyperLinkStyleExceptFont);
2473                     createUserLink.Font.CopyFrom(_hyperLinkStyle.Font);
2474                     createUserLink.ForeColor = _hyperLinkStyle.ForeColor;
2475                     passwordRecoveryLink.Font.CopyFrom(_hyperLinkStyle.Font);
2476                     passwordRecoveryLink.ForeColor = _hyperLinkStyle.ForeColor;
2477                     helpPageLink.Font.CopyFrom(_hyperLinkStyle.Font);
2478                     helpPageLink.ForeColor = _hyperLinkStyle.ForeColor;
2479                     editProfileLink.Font.CopyFrom(_hyperLinkStyle.Font);
2480                     editProfileLink.ForeColor = _hyperLinkStyle.ForeColor;
2481                 }
2482                 LoginUtil.SetTableCellVisible(helpPageLink, true);
2483             }
2484             else {
2485                 LoginUtil.SetTableCellVisible(helpPageLink, false);
2486             }
2487
2488             Control failureTextLabel = container.FailureTextLabel;
2489             if (((ITextControl)failureTextLabel).Text.Length > 0) {
2490                 LoginUtil.SetTableCellStyle(failureTextLabel, FailureTextStyle);
2491                 LoginUtil.SetTableCellVisible(failureTextLabel, true);
2492             }
2493             else {
2494                 LoginUtil.SetTableCellVisible(failureTextLabel, false);
2495             }
2496         }
2497
2498         /// <devdoc>
2499         /// Internal because called from ChangePasswordAdapter.
2500         /// </devdoc>
2501         internal void SetDefaultSuccessViewProperties() {
2502             SuccessContainer container = _successContainer;
2503             LinkButton linkButton = container.ContinueLinkButton;
2504             ImageButton imageButton = container.ContinueImageButton;
2505             Button pushButton = container.ContinuePushButton;
2506
2507             container.BorderTable.CellPadding = BorderPadding;
2508             container.BorderTable.CellSpacing = 0;
2509
2510             WebControl button = null;
2511             switch (ContinueButtonType) {
2512                 case ButtonType.Link:
2513                     linkButton.Text = ContinueButtonText;
2514                     button = linkButton;
2515                     break;
2516                 case ButtonType.Image:
2517                     imageButton.ImageUrl = ContinueButtonImageUrl;
2518                     imageButton.AlternateText = ContinueButtonText;
2519                     button = imageButton;
2520                     break;
2521                 case ButtonType.Button:
2522                     pushButton.Text = ContinueButtonText;
2523                     button = pushButton;
2524                     break;
2525             }
2526
2527             linkButton.Visible = false;
2528             imageButton.Visible = false;
2529             pushButton.Visible = false;
2530             button.Visible = true;
2531             button.TabIndex = TabIndex;
2532             button.AccessKey = AccessKey;
2533
2534             if (ContinueButtonStyle != null) button.ApplyStyle(ContinueButtonStyle);
2535
2536             LoginUtil.ApplyStyleToLiteral(container.Title, SuccessTitleText, _titleTextStyle, true);
2537             LoginUtil.ApplyStyleToLiteral(container.SuccessTextLabel, SuccessText, _successTextStyle, true);
2538
2539             string editProfileText = EditProfileText;
2540             string editProfileIconUrl = EditProfileIconUrl;
2541             bool editProfileVisible = (editProfileText.Length > 0);
2542             bool editProfileIconVisible = (editProfileIconUrl.Length > 0);
2543             HyperLink editProfileLink = container.EditProfileLink;
2544             Image editProfileIcon = container.EditProfileIcon;
2545             editProfileIcon.Visible = editProfileIconVisible;
2546             editProfileLink.Visible = editProfileVisible;
2547             if (editProfileVisible) {
2548                 editProfileLink.Text = editProfileText;
2549                 editProfileLink.NavigateUrl = EditProfileUrl;
2550                 editProfileLink.TabIndex = TabIndex;
2551                 if (_hyperLinkStyle != null) {
2552                     // Apply style except font to table cell, then apply font and forecolor to HyperLinks
2553                     // VSWhidbey 81289
2554                     Style hyperLinkStyleExceptFont = new TableItemStyle();
2555                     hyperLinkStyleExceptFont.CopyFrom(_hyperLinkStyle);
2556                     hyperLinkStyleExceptFont.Font.Reset();
2557                     LoginUtil.SetTableCellStyle(editProfileLink, hyperLinkStyleExceptFont);
2558                     editProfileLink.Font.CopyFrom(_hyperLinkStyle.Font);
2559                     editProfileLink.ForeColor = _hyperLinkStyle.ForeColor;
2560                 }
2561             }
2562             if (editProfileIconVisible) {
2563                 editProfileIcon.ImageUrl = editProfileIconUrl;
2564                 editProfileIcon.AlternateText = EditProfileText;
2565             }
2566             LoginUtil.SetTableCellVisible(editProfileLink, editProfileVisible || editProfileIconVisible);
2567         }
2568
2569         /// <devdoc>
2570         ///     Sets the properties of child controls that are editable by the client.
2571         /// </devdoc>
2572         private void SetEditableChildProperties() {
2573             // We need to use UserNameInternal for the DropDownList case where it won't fire a TextChanged for the first item
2574             if (UserNameInternal.Length > 0 && DisplayUserName) {
2575                 ITextControl userNameTextBox = (ITextControl)_changePasswordContainer.UserNameTextBox;
2576                 if (userNameTextBox != null) {
2577                     userNameTextBox.Text = UserNameInternal;
2578                 }
2579             }
2580         }
2581
2582         /// <devdoc>
2583         ///     Marks the starting point to begin tracking and saving changes to the
2584         ///     control as part of the control viewstate.
2585         /// </devdoc>
2586         protected override void TrackViewState() {
2587             base.TrackViewState();
2588
2589             if (_changePasswordButtonStyle != null) {
2590                 ((IStateManager) _changePasswordButtonStyle).TrackViewState();
2591             }
2592             if (_labelStyle != null) {
2593                 ((IStateManager) _labelStyle).TrackViewState();
2594             }
2595             if (_textBoxStyle != null) {
2596                 ((IStateManager) _textBoxStyle).TrackViewState();
2597             }
2598             if (_successTextStyle != null) {
2599                 ((IStateManager) _successTextStyle).TrackViewState();
2600             }
2601             if (_hyperLinkStyle != null) {
2602                 ((IStateManager) _hyperLinkStyle).TrackViewState();
2603             }
2604             if (_instructionTextStyle != null) {
2605                 ((IStateManager) _instructionTextStyle).TrackViewState();
2606             }
2607             if (_titleTextStyle != null) {
2608                 ((IStateManager) _titleTextStyle).TrackViewState();
2609             }
2610             if (_passwordHintStyle != null) {
2611                 ((IStateManager) _passwordHintStyle).TrackViewState();
2612             }
2613             if (_failureTextStyle != null) {
2614                 ((IStateManager) _failureTextStyle).TrackViewState();
2615             }
2616             if (_mailDefinition != null) {
2617                 ((IStateManager) _mailDefinition).TrackViewState();
2618             }
2619             if (_cancelButtonStyle != null) {
2620                 ((IStateManager) _cancelButtonStyle).TrackViewState();
2621             }
2622             if (_continueButtonStyle != null) {
2623                 ((IStateManager) _continueButtonStyle).TrackViewState();
2624             }
2625             if (_validatorTextStyle != null) {
2626                 ((IStateManager) _validatorTextStyle).TrackViewState();
2627             }
2628         }
2629
2630         private void UpdateValidators() {
2631             if (DesignMode) {
2632                 return;
2633             }
2634
2635             ChangePasswordContainer container = _changePasswordContainer;
2636             
2637             if (container != null) {
2638                 bool displayUserName = DisplayUserName;
2639                 RequiredFieldValidator userNameRequired = container.UserNameRequired;
2640                 if (userNameRequired != null) {
2641                     userNameRequired.Enabled = displayUserName;
2642                     userNameRequired.Visible = displayUserName;
2643                 }
2644
2645                 bool regExpEnabled = RegExpEnabled;
2646                 RegularExpressionValidator regExpValidator = container.RegExpValidator;
2647                 if (regExpValidator != null) {
2648                     regExpValidator.Enabled = regExpEnabled;
2649                     regExpValidator.Visible = regExpEnabled;
2650                 }
2651             }
2652         }
2653
2654         private void UserNameTextChanged(object source, EventArgs e) {
2655             string userName = ((ITextControl) source).Text;
2656             if (!String.IsNullOrEmpty(userName)) {
2657                 UserName = userName;
2658             }
2659         }
2660
2661         /// <devdoc>
2662         /// The default success template for the control, used if SuccessTemplate is null.
2663         /// </devdoc>
2664         private sealed class DefaultSuccessTemplate : ITemplate {
2665             private ChangePassword _owner;
2666
2667             public DefaultSuccessTemplate(ChangePassword owner) {
2668                 _owner = owner;
2669             }
2670
2671             private void CreateControls(SuccessContainer successContainer) {
2672                 successContainer.Title = new Literal();
2673                 successContainer.SuccessTextLabel = new Literal();
2674                 successContainer.EditProfileLink = new HyperLink();
2675                 successContainer.EditProfileLink.ID = _editProfileSuccessLinkID;
2676                 successContainer.EditProfileIcon = new Image();
2677
2678                 LinkButton linkButton = new LinkButton();
2679                 linkButton.ID = _continueLinkButtonID;
2680                 linkButton.CommandName = ContinueButtonCommandName;
2681                 linkButton.CausesValidation = false;
2682                 successContainer.ContinueLinkButton = linkButton;
2683
2684                 ImageButton imageButton = new ImageButton();
2685                 imageButton.ID = _continueImageButtonID;
2686                 imageButton.CommandName = ContinueButtonCommandName;
2687                 imageButton.CausesValidation = false;
2688                 successContainer.ContinueImageButton = imageButton;
2689
2690                 Button pushButton = new Button();
2691                 pushButton.ID = _continuePushButtonID;
2692                 pushButton.CommandName = ContinueButtonCommandName;
2693                 pushButton.CausesValidation = false;
2694                 successContainer.ContinuePushButton = pushButton;
2695              }
2696
2697             private void LayoutControls(SuccessContainer successContainer) {
2698                 Table table = new Table();
2699                 table.CellPadding = 0;
2700                 TableRow r;
2701                 TableCell c;
2702
2703                 r = new LoginUtil.DisappearingTableRow();
2704                 c = new TableCell();
2705                 c.ColumnSpan = 2;
2706                 c.HorizontalAlign = HorizontalAlign.Center;
2707                 c.Controls.Add(successContainer.Title);
2708                 r.Cells.Add(c);
2709                 table.Rows.Add(r);
2710
2711                 r = new LoginUtil.DisappearingTableRow();
2712                 c = new TableCell();
2713                 c.Controls.Add(successContainer.SuccessTextLabel);
2714                 r.Cells.Add(c);
2715                 table.Rows.Add(r);
2716
2717                 r = new LoginUtil.DisappearingTableRow();
2718                 c = new TableCell();
2719                 c.ColumnSpan = 2;
2720                 c.HorizontalAlign = HorizontalAlign.Right;
2721                 c.Controls.Add(successContainer.ContinuePushButton);
2722                 c.Controls.Add(successContainer.ContinueLinkButton);
2723                 c.Controls.Add(successContainer.ContinueImageButton);
2724                 r.Cells.Add(c);
2725                 table.Rows.Add(r);
2726
2727                 r = new LoginUtil.DisappearingTableRow();
2728                 c = new TableCell();
2729                 c.ColumnSpan = 2;
2730                 c.Controls.Add(successContainer.EditProfileIcon);
2731                 c.Controls.Add(successContainer.EditProfileLink);
2732                 r.Cells.Add(c);
2733                 table.Rows.Add(r);
2734
2735                 Table table2 = LoginUtil.CreateChildTable(_owner.ConvertingToTemplate);
2736                 r = new TableRow();
2737                 c = new TableCell();
2738                 c.Controls.Add(table);
2739                 r.Cells.Add(c);
2740                 table2.Rows.Add(r);
2741
2742                 successContainer.LayoutTable = table;
2743                 successContainer.BorderTable = table2;
2744                 successContainer.Controls.Add(table2);
2745             }
2746
2747             void ITemplate.InstantiateIn(Control container) {
2748                 SuccessContainer successContainer = (SuccessContainer) container;
2749                 CreateControls(successContainer);
2750                 LayoutControls(successContainer);
2751             }
2752         }
2753
2754         /// <devdoc>
2755         ///     Container for the success template.
2756         ///     Internal instead of private because it must be used by ChangePasswordAdapter.
2757         /// </devdoc>
2758         internal sealed class SuccessContainer : LoginUtil.GenericContainer<ChangePassword>, INonBindingContainer {
2759             private Literal _successTextLabel;
2760             private Button _continuePushButton;
2761             private LinkButton _continueLinkButton;
2762             private ImageButton _continueImageButton;
2763             private Image _editProfileIcon;
2764             private HyperLink _editProfileLink;
2765             private Literal _title;
2766
2767             public SuccessContainer(ChangePassword owner) : base(owner) {
2768             }
2769
2770             internal ImageButton ContinueImageButton {
2771                 get {
2772                     return _continueImageButton;
2773                 }
2774                 set {
2775                     _continueImageButton = value;
2776                 }
2777             }
2778
2779             internal LinkButton ContinueLinkButton {
2780                 get {
2781                     return _continueLinkButton;
2782                 }
2783                 set {
2784                     _continueLinkButton = value;
2785                 }
2786             }
2787
2788             internal Button ContinuePushButton {
2789                 get {
2790                     return _continuePushButton;
2791                 }
2792                 set {
2793                     _continuePushButton = value;
2794                 }
2795             }
2796
2797             protected override bool ConvertingToTemplate {
2798                 get {
2799                     return Owner.ConvertingToTemplate;
2800                 }
2801             }
2802
2803             internal Image EditProfileIcon {
2804                 get {
2805                     return _editProfileIcon;
2806                 }
2807                 set {
2808                     _editProfileIcon = value;
2809                 }
2810             }
2811
2812             internal HyperLink EditProfileLink {
2813                 get {
2814                     return _editProfileLink;
2815                 }
2816                 set {
2817                     _editProfileLink = value;
2818                 }
2819             }
2820
2821             public Literal SuccessTextLabel {
2822                 get {
2823                     return _successTextLabel;
2824                 }
2825                 set {
2826                     _successTextLabel = value;
2827                 }
2828             }
2829
2830             internal Literal Title {
2831                 get {
2832                     return _title;
2833                 }
2834                 set {
2835                     _title = value;
2836                 }
2837             }
2838         }
2839
2840         /// <devdoc>
2841         ///     The default template for the control, used if ChangePasswordTemplate is null.
2842         /// </devdoc>
2843         private sealed class DefaultChangePasswordTemplate : ITemplate {
2844             private ChangePassword _owner;
2845
2846             public DefaultChangePasswordTemplate(ChangePassword owner) {
2847                 _owner = owner;
2848             }
2849
2850             /// <devdoc>
2851             ///     Helper function to create and set properties for a required field validator
2852             /// </devdoc>
2853             private RequiredFieldValidator CreateRequiredFieldValidator(string id, TextBox textBox, string validationGroup, bool enableValidation) {
2854                 RequiredFieldValidator validator = new RequiredFieldValidator();
2855                 validator.ID = id;
2856                 validator.ValidationGroup = validationGroup;
2857                 validator.ControlToValidate = textBox.ID;
2858                 validator.Display = _requiredFieldValidatorDisplay;
2859                 validator.Text = SR.GetString(SR.LoginControls_DefaultRequiredFieldValidatorText);
2860                 validator.Enabled = enableValidation;
2861                 validator.Visible = enableValidation;
2862                 return validator;
2863             }
2864
2865             /// <devdoc>
2866             ///     Creates the child controls, sets certain properties (mostly static properties)
2867             /// </devdoc>
2868             private void CreateControls(ChangePasswordContainer container) {
2869                 string validationGroup = _owner.UniqueID;
2870
2871                 container.Title = new Literal();
2872                 container.Instruction = new Literal();
2873                 container.PasswordHintLabel = new Literal();
2874
2875                 TextBox userNameTextBox = new TextBox();
2876                 // Must explicitly set the ID of controls that raise postback events
2877                 userNameTextBox.ID = _userNameID;
2878                 container.UserNameTextBox = userNameTextBox;
2879                 container.UserNameLabel = new LabelLiteral(userNameTextBox);
2880
2881                 bool enableValidation = (_owner.CurrentView == View.ChangePassword);
2882
2883                 container.UserNameRequired = CreateRequiredFieldValidator(_userNameRequiredID, userNameTextBox, validationGroup, enableValidation);
2884
2885                 TextBox currentPasswordTextBox = new TextBox();
2886                 // Must explicitly set the ID of controls that raise postback events
2887                 currentPasswordTextBox.ID = _currentPasswordID;
2888                 currentPasswordTextBox.TextMode = TextBoxMode.Password;
2889                 container.CurrentPasswordTextBox = currentPasswordTextBox;
2890                 container.CurrentPasswordLabel = new LabelLiteral(currentPasswordTextBox);
2891
2892                 container.PasswordRequired = CreateRequiredFieldValidator(_currentPasswordRequiredID, currentPasswordTextBox, validationGroup, enableValidation);
2893
2894                 TextBox newPasswordTextBox = new TextBox();
2895                 // Must explicitly set the ID of controls that raise postback events
2896                 newPasswordTextBox.ID = _newPasswordID;
2897                 newPasswordTextBox.TextMode = TextBoxMode.Password;
2898                 container.NewPasswordTextBox = newPasswordTextBox;
2899                 container.NewPasswordLabel = new LabelLiteral(newPasswordTextBox);
2900
2901                 container.NewPasswordRequired = CreateRequiredFieldValidator(_newPasswordRequiredID, newPasswordTextBox, validationGroup, enableValidation);
2902
2903                 TextBox confirmNewPasswordTextBox = new TextBox();
2904                 // Must explicitly set the ID of controls that raise postback events
2905                 confirmNewPasswordTextBox.ID = _confirmNewPasswordID;
2906                 confirmNewPasswordTextBox.TextMode = TextBoxMode.Password;
2907                 container.ConfirmNewPasswordTextBox = confirmNewPasswordTextBox;
2908                 container.ConfirmNewPasswordLabel = new LabelLiteral(confirmNewPasswordTextBox);
2909
2910                 container.ConfirmNewPasswordRequired = CreateRequiredFieldValidator(_confirmNewPasswordRequiredID, confirmNewPasswordTextBox, validationGroup, enableValidation);
2911
2912                 // Setup compare validator for new/confirmNewPassword values
2913                 CompareValidator compareValidator = new CompareValidator();
2914                 compareValidator.ID = _newPasswordCompareID;
2915                 compareValidator.ValidationGroup = validationGroup;
2916                 compareValidator.ControlToValidate = _confirmNewPasswordID;
2917                 compareValidator.ControlToCompare = _newPasswordID;
2918                 compareValidator.Operator = ValidationCompareOperator.Equal;
2919                 compareValidator.ErrorMessage = _owner.ConfirmPasswordCompareErrorMessage;
2920                 compareValidator.Display = _compareFieldValidatorDisplay;
2921                 compareValidator.Enabled = enableValidation;
2922                 compareValidator.Visible = enableValidation;
2923                 container.NewPasswordCompareValidator = compareValidator;
2924
2925                 // Reg exp validator
2926                 RegularExpressionValidator regExpValidator = new RegularExpressionValidator();
2927                 regExpValidator.ID = _newPasswordRegExpID;
2928                 regExpValidator.ValidationGroup = validationGroup;
2929                 regExpValidator.ControlToValidate = _newPasswordID;
2930                 regExpValidator.ErrorMessage = _owner.NewPasswordRegularExpressionErrorMessage;
2931                 regExpValidator.ValidationExpression = _owner.NewPasswordRegularExpression;
2932                 regExpValidator.Display = _regexpFieldValidatorDisplay;
2933                 regExpValidator.Enabled = enableValidation;
2934                 regExpValidator.Visible = enableValidation;
2935                 container.RegExpValidator = regExpValidator;
2936
2937                 // Buttons
2938                 LinkButton linkButton = new LinkButton();
2939                 linkButton.ID = _changePasswordLinkButtonID;
2940                 linkButton.ValidationGroup = validationGroup;
2941                 linkButton.CommandName = ChangePasswordButtonCommandName;
2942                 container.ChangePasswordLinkButton = linkButton;
2943
2944                 linkButton = new LinkButton();
2945                 linkButton.ID = _cancelLinkButtonID;
2946                 linkButton.CausesValidation = false;
2947                 linkButton.CommandName = CancelButtonCommandName;
2948                 container.CancelLinkButton = linkButton;
2949
2950                 ImageButton imageButton = new ImageButton();
2951                 imageButton.ID = _changePasswordImageButtonID;
2952                 imageButton.ValidationGroup = validationGroup;
2953                 imageButton.CommandName = ChangePasswordButtonCommandName;
2954                 container.ChangePasswordImageButton = imageButton;
2955
2956                 imageButton = new ImageButton();
2957                 imageButton.ID = _cancelImageButtonID;
2958                 imageButton.CommandName = CancelButtonCommandName;
2959                 imageButton.CausesValidation = false;
2960                 container.CancelImageButton = imageButton;
2961
2962                 Button pushButton = new Button();
2963                 pushButton.ID = _changePasswordPushButtonID;
2964                 pushButton.ValidationGroup = validationGroup;
2965                 pushButton.CommandName = ChangePasswordButtonCommandName;
2966                 container.ChangePasswordPushButton = pushButton;
2967
2968                 pushButton = new Button();
2969                 pushButton.ID = _cancelPushButtonID;
2970                 pushButton.CommandName = CancelButtonCommandName;
2971                 pushButton.CausesValidation = false;
2972                 container.CancelPushButton = pushButton;
2973
2974                 container.PasswordRecoveryIcon = new Image();
2975                 container.PasswordRecoveryLink = new HyperLink();
2976                 container.PasswordRecoveryLink.ID = _passwordRecoveryLinkID;
2977
2978                 container.CreateUserIcon = new Image();
2979                 container.CreateUserLink = new HyperLink();
2980                 container.CreateUserLink.ID = _createUserLinkID;
2981                 container.CreateUserLinkSeparator = new LiteralControl();
2982
2983                 container.HelpPageIcon = new Image();
2984                 container.HelpPageLink = new HyperLink();
2985                 container.HelpPageLink.ID = _helpLinkID;
2986                 container.HelpPageLinkSeparator = new LiteralControl();
2987
2988                 container.EditProfileLink = new HyperLink();
2989                 container.EditProfileLink.ID = _editProfileLinkID;
2990                 container.EditProfileIcon = new Image();
2991                 container.EditProfileLinkSeparator = new LiteralControl();
2992
2993                 Literal failureTextLabel = new Literal();
2994                 failureTextLabel.ID = _failureTextID;
2995                 container.FailureTextLabel = failureTextLabel;
2996             }
2997
2998             /// <devdoc>
2999             ///     Adds the controls to a table for layout.  Layout depends on TextLayout properties.
3000             /// </devdoc>
3001             private void LayoutControls(ChangePasswordContainer container) {
3002                 Table table = new Table();
3003                 table.CellPadding = 0;
3004                 TableRow r;
3005                 TableCell c;
3006
3007                 r = new LoginUtil.DisappearingTableRow();
3008                 c = new TableCell();
3009                 c.ColumnSpan = 2;
3010                 c.HorizontalAlign = HorizontalAlign.Center;
3011                 c.Controls.Add(container.Title);
3012                 r.Cells.Add(c);
3013                 table.Rows.Add(r);
3014
3015                 r = new LoginUtil.DisappearingTableRow();
3016                 c = new TableCell();
3017                 c.ColumnSpan = 2;
3018                 c.HorizontalAlign = HorizontalAlign.Center;
3019                 c.Controls.Add(container.Instruction);
3020                 r.Cells.Add(c);
3021                 table.Rows.Add(r);
3022
3023                 // UserName is only visible if enabled
3024                 r = new LoginUtil.DisappearingTableRow();
3025                 c = new TableCell();
3026                 c.HorizontalAlign = HorizontalAlign.Right;
3027                 if (_owner.ConvertingToTemplate) {
3028                     container.UserNameLabel.RenderAsLabel = true;
3029                 }
3030                 c.Controls.Add(container.UserNameLabel);
3031                 r.Cells.Add(c);
3032
3033                 c = new TableCell();
3034                 c.Controls.Add(container.UserNameTextBox);
3035                 c.Controls.Add(container.UserNameRequired);
3036                 r.Cells.Add(c);
3037                 table.Rows.Add(r);
3038                 _owner._userNameTableRow = r;
3039
3040                 r = new LoginUtil.DisappearingTableRow();
3041                 c = new TableCell();
3042                 c.HorizontalAlign = HorizontalAlign.Right;
3043                 c.Controls.Add(container.CurrentPasswordLabel);
3044                 if (_owner.ConvertingToTemplate) {
3045                     container.CurrentPasswordLabel.RenderAsLabel = true;
3046                 }
3047                 r.Cells.Add(c);
3048
3049                 c = new TableCell();
3050                 c.Controls.Add(container.CurrentPasswordTextBox);
3051                 c.Controls.Add(container.PasswordRequired);
3052                 r.Cells.Add(c);
3053                 table.Rows.Add(r);
3054
3055                 r = new LoginUtil.DisappearingTableRow();
3056                 c = new TableCell();
3057                 c.HorizontalAlign = HorizontalAlign.Right;
3058                 c.Controls.Add(container.NewPasswordLabel);
3059                 if (_owner.ConvertingToTemplate) {
3060                     container.NewPasswordLabel.RenderAsLabel = true;
3061                 }
3062                 r.Cells.Add(c);
3063
3064                 c = new TableCell();
3065                 c.Controls.Add(container.NewPasswordTextBox);
3066                 c.Controls.Add(container.NewPasswordRequired);
3067                 r.Cells.Add(c);
3068                 table.Rows.Add(r);
3069
3070                 r = new LoginUtil.DisappearingTableRow();
3071                 c = new TableCell();
3072                 r.Cells.Add(c);
3073                 c = new TableCell();
3074                 c.Controls.Add(container.PasswordHintLabel);
3075                 r.Cells.Add(c);
3076                 table.Rows.Add(r);
3077                 _owner._passwordHintTableRow = r;
3078
3079                 r = new LoginUtil.DisappearingTableRow();
3080                 c = new TableCell();
3081                 c.HorizontalAlign = HorizontalAlign.Right;
3082                 c.Controls.Add(container.ConfirmNewPasswordLabel);
3083                 if (_owner.ConvertingToTemplate) {
3084                     container.ConfirmNewPasswordLabel.RenderAsLabel = true;
3085                 }
3086                 r.Cells.Add(c);
3087
3088                 c = new TableCell();
3089                 c.Controls.Add(container.ConfirmNewPasswordTextBox);
3090                 c.Controls.Add(container.ConfirmNewPasswordRequired);
3091                 r.Cells.Add(c);
3092                 table.Rows.Add(r);
3093
3094                 r = new LoginUtil.DisappearingTableRow();
3095                 c = new TableCell();
3096                 c.HorizontalAlign = HorizontalAlign.Center;
3097                 c.ColumnSpan = 2;
3098                 c.Controls.Add(container.NewPasswordCompareValidator);
3099                 r.Cells.Add(c);
3100                 table.Rows.Add(r);
3101
3102                 if (_owner.RegExpEnabled) {
3103                     r = new LoginUtil.DisappearingTableRow();
3104                     c = new TableCell();
3105                     c.HorizontalAlign = HorizontalAlign.Center;
3106                     c.ColumnSpan = 2;
3107                     c.Controls.Add(container.RegExpValidator);
3108                     r.Cells.Add(c);
3109                     table.Rows.Add(r);
3110                 }
3111                 _owner.ValidatorRow = r;
3112
3113                 r = new LoginUtil.DisappearingTableRow();
3114                 c = new TableCell();
3115                 c.HorizontalAlign = HorizontalAlign.Center;
3116                 c.ColumnSpan = 2;
3117                 c.Controls.Add(container.FailureTextLabel);
3118                 r.Cells.Add(c);
3119                 table.Rows.Add(r);
3120
3121                 r = new LoginUtil.DisappearingTableRow();
3122                 c = new TableCell();
3123                 c.HorizontalAlign = HorizontalAlign.Right;
3124                 c.Controls.Add(container.ChangePasswordLinkButton);
3125                 c.Controls.Add(container.ChangePasswordImageButton);
3126                 c.Controls.Add(container.ChangePasswordPushButton);
3127                 r.Cells.Add(c);
3128                 c = new TableCell();
3129                 c.Controls.Add(container.CancelLinkButton);
3130                 c.Controls.Add(container.CancelImageButton);
3131                 c.Controls.Add(container.CancelPushButton);
3132                 r.Cells.Add(c);
3133                 table.Rows.Add(r);
3134
3135                 r = new LoginUtil.DisappearingTableRow();
3136                 c = new TableCell();
3137                 c.ColumnSpan = 2;
3138                 c.Controls.Add(container.HelpPageIcon);
3139                 c.Controls.Add(container.HelpPageLink);
3140                 c.Controls.Add(container.HelpPageLinkSeparator);
3141                 c.Controls.Add(container.CreateUserIcon);
3142                 c.Controls.Add(container.CreateUserLink);
3143                 container.HelpPageLinkSeparator.Text = "<br />";
3144                 container.CreateUserLinkSeparator.Text = "<br />";
3145                 container.EditProfileLinkSeparator.Text = "<br />";
3146                 c.Controls.Add(container.CreateUserLinkSeparator);
3147                 c.Controls.Add(container.PasswordRecoveryIcon);
3148                 c.Controls.Add(container.PasswordRecoveryLink);
3149                 c.Controls.Add(container.EditProfileLinkSeparator);
3150                 c.Controls.Add(container.EditProfileIcon);
3151                 c.Controls.Add(container.EditProfileLink);
3152                 r.Cells.Add(c);
3153                 table.Rows.Add(r);
3154
3155                 Table table2 = LoginUtil.CreateChildTable(_owner.ConvertingToTemplate);
3156                 r = new TableRow();
3157                 c = new TableCell();
3158                 c.Controls.Add(table);
3159                 r.Cells.Add(c);
3160                 table2.Rows.Add(r);
3161
3162                 container.LayoutTable = table;
3163                 container.BorderTable = table2;
3164                 container.Controls.Add(table2);
3165             }
3166
3167             #region ITemplate implementation
3168             void ITemplate.InstantiateIn(Control container) {
3169                 ChangePasswordContainer cpContainer = (ChangePasswordContainer) container;
3170                 CreateControls(cpContainer);
3171                 LayoutControls(cpContainer);
3172             }
3173             #endregion
3174         }
3175
3176         /// <devdoc>
3177         ///     Container for the layout template.  Contains properties that reference each child control.
3178         ///     For the default template, the properties are set when the child controls are created.
3179         ///     For the user template, the controls are looked up dynamically by ID.  Some controls are required,
3180         ///     and an exception is thrown if they are missing.  Other controls are optional, and an exception is
3181         ///     thrown if they have the wrong type.
3182         ///     Internal instead of private because it must be used by LoginAdapter.
3183         /// </devdoc>
3184         internal sealed class ChangePasswordContainer : LoginUtil.GenericContainer<ChangePassword>, INonBindingContainer {
3185             private LiteralControl _createUserLinkSeparator;
3186             private LiteralControl _helpPageLinkSeparator;
3187             private LiteralControl _editProfileLinkSeparator;
3188             private Control _failureTextLabel;
3189             private ImageButton _changePasswordImageButton;
3190             private LinkButton _changePasswordLinkButton;
3191             private Button _changePasswordPushButton;
3192             private ImageButton _cancelImageButton;
3193             private LinkButton _cancelLinkButton;
3194             private Button _cancelPushButton;
3195
3196             private Image _createUserIcon;
3197             private Image _helpPageIcon;
3198             private Image _passwordRecoveryIcon;
3199             private Image _editProfileIcon;
3200
3201             private RequiredFieldValidator _passwordRequired;
3202             private RequiredFieldValidator _userNameRequired;
3203             private RequiredFieldValidator _confirmNewPasswordRequired;
3204             private RequiredFieldValidator _newPasswordRequired;
3205             private CompareValidator _newPasswordCompareValidator;
3206             private RegularExpressionValidator _regExpValidator;
3207
3208             private Literal _title;
3209             private Literal _instruction;
3210             private LabelLiteral _userNameLabel;
3211             private LabelLiteral _currentPasswordLabel;
3212             private LabelLiteral _newPasswordLabel;
3213             private LabelLiteral _confirmNewPasswordLabel;
3214             private Literal _passwordHintLabel;
3215             private Control _userNameTextBox;
3216             private Control _currentPasswordTextBox;
3217             private Control _newPasswordTextBox;
3218             private Control _confirmNewPasswordTextBox;
3219             private HyperLink _helpPageLink;
3220             private HyperLink _passwordRecoveryLink;
3221             private HyperLink _createUserLink;
3222             private HyperLink _editProfileLink;
3223
3224             public ChangePasswordContainer(ChangePassword owner) : base(owner) {
3225             }
3226
3227             internal ImageButton CancelImageButton {
3228                 get {
3229                     return _cancelImageButton;
3230                 }
3231                 set {
3232                     _cancelImageButton = value;
3233                 }
3234             }
3235
3236             internal LinkButton CancelLinkButton {
3237                 get {
3238                     return _cancelLinkButton;
3239                 }
3240                 set {
3241                     _cancelLinkButton = value;
3242                 }
3243             }
3244
3245             internal Button CancelPushButton {
3246                 get {
3247                     return _cancelPushButton;
3248                 }
3249                 set {
3250                     _cancelPushButton = value;
3251                 }
3252             }
3253
3254             internal ImageButton ChangePasswordImageButton {
3255                 get {
3256                     return _changePasswordImageButton;
3257                 }
3258                 set {
3259                     _changePasswordImageButton = value;
3260                 }
3261             }
3262
3263             internal LinkButton ChangePasswordLinkButton {
3264                 get {
3265                     return _changePasswordLinkButton;
3266                 }
3267                 set {
3268                     _changePasswordLinkButton = value;
3269                 }
3270             }
3271
3272             internal Button ChangePasswordPushButton {
3273                 get {
3274                     return _changePasswordPushButton;
3275                 }
3276                 set {
3277                     _changePasswordPushButton = value;
3278                 }
3279             }
3280
3281             internal LabelLiteral ConfirmNewPasswordLabel {
3282                 get {
3283                     return _confirmNewPasswordLabel;
3284                 }
3285                 set {
3286                     _confirmNewPasswordLabel = value;
3287                 }
3288             }
3289
3290             internal RequiredFieldValidator ConfirmNewPasswordRequired {
3291                 get {
3292                     return _confirmNewPasswordRequired;
3293                 }
3294
3295                 set {
3296                     _confirmNewPasswordRequired = value;
3297                 }
3298             }
3299
3300             internal Control ConfirmNewPasswordTextBox {
3301                 get {
3302                     if (_confirmNewPasswordTextBox != null) {
3303                         return _confirmNewPasswordTextBox;
3304                     }
3305                     else {
3306                         return FindOptionalControl<IEditableTextControl>(_confirmNewPasswordID);
3307                     }
3308                 }
3309                 set {
3310                     _confirmNewPasswordTextBox = value;
3311                 }
3312             }
3313
3314             protected override bool ConvertingToTemplate {
3315                 get {
3316                     return Owner.ConvertingToTemplate;
3317                 }
3318             }
3319
3320             internal Image CreateUserIcon {
3321                 get {
3322                     return _createUserIcon;
3323                 }
3324                 set {
3325                     _createUserIcon = value;
3326                 }
3327             }
3328
3329             internal HyperLink CreateUserLink {
3330                 get {
3331                     return _createUserLink;
3332                 }
3333                 set {
3334                     _createUserLink = value;
3335                 }
3336             }
3337
3338             internal LiteralControl CreateUserLinkSeparator {
3339                 get {
3340                     return _createUserLinkSeparator;
3341                 }
3342                 set {
3343                     _createUserLinkSeparator = value;
3344                 }
3345             }
3346
3347             internal LabelLiteral CurrentPasswordLabel {
3348                 get {
3349                     return _currentPasswordLabel;
3350                 }
3351                 set {
3352                     _currentPasswordLabel = value;
3353                 }
3354             }
3355
3356             internal Control CurrentPasswordTextBox {
3357                 get {
3358                     if (_currentPasswordTextBox != null) {
3359                         return _currentPasswordTextBox;
3360                     }
3361                     else {
3362                         return FindRequiredControl<IEditableTextControl>(_currentPasswordID,
3363                             SR.ChangePassword_NoCurrentPasswordTextBox);
3364                     }
3365                 }
3366                 set {
3367                     _currentPasswordTextBox = value;
3368                 }
3369             }
3370
3371             internal Image EditProfileIcon {
3372                 get {
3373                     return _editProfileIcon;
3374                 }
3375                 set {
3376                     _editProfileIcon = value;
3377                 }
3378             }
3379
3380             internal HyperLink EditProfileLink {
3381                 get {
3382                     return _editProfileLink;
3383                 }
3384                 set {
3385                     _editProfileLink = value;
3386                 }
3387             }
3388
3389             internal LiteralControl EditProfileLinkSeparator {
3390                 get {
3391                     return _editProfileLinkSeparator;
3392                 }
3393                 set {
3394                     _editProfileLinkSeparator = value;
3395                 }
3396             }
3397
3398             internal Control FailureTextLabel {
3399                 get {
3400                     if (_failureTextLabel != null) {
3401                         return _failureTextLabel;
3402                     }
3403                     else {
3404                         return FindOptionalControl<ITextControl>(_failureTextID);
3405                     }
3406                 }
3407                 set {
3408                     _failureTextLabel = value;
3409                 }
3410             }
3411
3412             internal Image HelpPageIcon {
3413                 get {
3414                     return _helpPageIcon;
3415                 }
3416                 set {
3417                     _helpPageIcon = value;
3418                 }
3419             }
3420
3421             internal HyperLink HelpPageLink {
3422                 get {
3423                     return _helpPageLink;
3424                 }
3425                 set {
3426                     _helpPageLink = value;
3427                 }
3428             }
3429
3430             internal LiteralControl HelpPageLinkSeparator {
3431                 get {
3432                     return _helpPageLinkSeparator;
3433                 }
3434                 set {
3435                     _helpPageLinkSeparator = value;
3436                 }
3437             }
3438
3439             internal Literal Instruction {
3440                 get {
3441                     return _instruction;
3442                 }
3443                 set {
3444                     _instruction = value;
3445                 }
3446             }
3447
3448             internal CompareValidator NewPasswordCompareValidator {
3449                 get {
3450                     return _newPasswordCompareValidator;
3451                 }
3452                 set {
3453                     _newPasswordCompareValidator = value;
3454                 }
3455             }
3456
3457             internal LabelLiteral NewPasswordLabel {
3458                 get {
3459                     return _newPasswordLabel;
3460                 }
3461                 set {
3462                     _newPasswordLabel = value;
3463                 }
3464             }
3465
3466             internal RequiredFieldValidator NewPasswordRequired {
3467                 get {
3468                     return _newPasswordRequired;
3469                 }
3470
3471                 set {
3472                     _newPasswordRequired = value;
3473                 }
3474             }
3475
3476             internal Control NewPasswordTextBox {
3477                 get {
3478                     if (_newPasswordTextBox != null) {
3479                         return _newPasswordTextBox;
3480                     }
3481                     else {
3482                         return FindRequiredControl<IEditableTextControl>(_newPasswordID, SR.ChangePassword_NoNewPasswordTextBox);
3483                     }
3484                 }
3485                 set {
3486                     _newPasswordTextBox = value;
3487                 }
3488             }
3489
3490             internal Literal PasswordHintLabel {
3491                 get {
3492                     return _passwordHintLabel;
3493                 }
3494                 set {
3495                     _passwordHintLabel = value;
3496                 }
3497             }
3498
3499             internal Image PasswordRecoveryIcon {
3500                 get {
3501                     return _passwordRecoveryIcon;
3502                 }
3503                 set {
3504                     _passwordRecoveryIcon = value;
3505                 }
3506             }
3507
3508             internal HyperLink PasswordRecoveryLink {
3509                 get {
3510                     return _passwordRecoveryLink;
3511                 }
3512                 set {
3513                     _passwordRecoveryLink = value;
3514                 }
3515             }
3516
3517             internal RequiredFieldValidator PasswordRequired {
3518                 get {
3519                     return _passwordRequired;
3520                 }
3521                 set {
3522                     _passwordRequired = value;
3523                 }
3524             }
3525
3526             internal RegularExpressionValidator RegExpValidator {
3527                 get {
3528                     return _regExpValidator;
3529                 }
3530                 set {
3531                     _regExpValidator = value;
3532                 }
3533             }
3534
3535             internal Literal Title {
3536                 get {
3537                     return _title;
3538                 }
3539                 set {
3540                     _title = value;
3541                 }
3542             }
3543
3544             internal LabelLiteral UserNameLabel {
3545                 get {
3546                     return _userNameLabel;
3547                 }
3548                 set {
3549                     _userNameLabel = value;
3550                 }
3551             }
3552
3553             internal RequiredFieldValidator UserNameRequired {
3554                 get {
3555                     return _userNameRequired;
3556                 }
3557
3558                 set {
3559                     _userNameRequired = value;
3560                 }
3561             }
3562
3563             internal Control UserNameTextBox {
3564                 get {
3565                     if (_userNameTextBox != null) {
3566                         return _userNameTextBox;
3567                     }
3568                     else {
3569                         // UserNameTextBox is required if DisplayUserName is true, but the control *must not* be
3570                         // present if DisplayUserName is false. (VSWhidbey 393444)
3571                         if (Owner.DisplayUserName) {
3572                             return FindRequiredControl<IEditableTextControl>(_userNameID, SR.ChangePassword_NoUserNameTextBox);
3573                         }
3574                         else {
3575                             VerifyControlNotPresent<IEditableTextControl>(_userNameID, SR.ChangePassword_UserNameTextBoxNotAllowed);
3576                             return null;
3577                         }
3578                     }
3579                 }
3580                 set {
3581                     _userNameTextBox = value;
3582                 }
3583             }
3584         }
3585
3586         /// <devdoc>
3587         /// Internal because used from ChangePasswordAdapter
3588         /// </devdoc>
3589         internal enum View {
3590             ChangePassword,
3591             Success
3592         }
3593     }
3594 }