Page.Validate() is called when CausesValidation=true
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / Menu.cs
index b4a70bdc2dd9799f4c770ce3798c1f9df83ac3f6..bea86e6af4ec91f0ba037f8e24e6e81e2bb3ef77 100644 (file)
@@ -3,6 +3,7 @@
 //
 // Authors:
 //     Lluis Sanchez Gual (lluis@novell.com)
+//     Igor Zelmanovich (igorz@mainsoft.com)
 //
 // (C) 2004 Novell, Inc (http://www.novell.com)
 //
@@ -38,11 +39,14 @@ using System.Web.UI;
 using System.Web.Handlers;
 using System.Collections.Specialized;
 using System.IO;
+using System.Drawing;
+using System.Collections.Generic;
 
 namespace System.Web.UI.WebControls
 {
        [DefaultEvent ("MenuItemClick")]
        [ControlValueProperty ("SelectedValue")]
+       [Designer ("System.Web.UI.Design.WebControls.MenuDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
        public class Menu : HierarchicalDataBoundControl, IPostBackEventHandler, INamingContainer
        {
                MenuItemStyle dynamicMenuItemStyle;
@@ -56,22 +60,46 @@ namespace System.Web.UI.WebControls
 
                MenuItemStyleCollection levelMenuItemStyles;
                MenuItemStyleCollection levelSelectedStyles;
+               SubMenuStyleCollection levelSubMenuStyles;
                ITemplate staticItemTemplate;
                ITemplate dynamicItemTemplate;
                
                MenuItemCollection items;
                MenuItemBindingCollection dataBindings;
                MenuItem selectedItem;
+               string selectedItemPath;
                Hashtable bindings;
-               ArrayList dynamicMenus;
-               
+
+               Hashtable _menuItemControls;
+               bool _requiresChildControlsDataBinding;
+
+               int registeredStylesCounter = -1;
+               List<Style> levelSelectedLinkStyles;
+               List<Style> levelMenuItemLinkStyles;
+               Style popOutBoxStyle;
+               Style controlLinkStyle;
+               Style dynamicMenuItemLinkStyle;
+               Style staticMenuItemLinkStyle;
+               Style dynamicSelectedLinkStyle;
+               Style staticSelectedLinkStyle;
+               Style dynamicHoverLinkStyle;
+               Style staticHoverLinkStyle;
+
                private static readonly object MenuItemClickEvent = new object();
+               private static readonly object MenuItemDataBoundEvent = new object();
+               
+               public static readonly string MenuItemClickCommandName = "Click";
                
                public event MenuEventHandler MenuItemClick {
                        add { Events.AddHandler (MenuItemClickEvent, value); }
                        remove { Events.RemoveHandler (MenuItemClickEvent, value); }
                }
                
+               public event MenuEventHandler MenuItemDataBound {
+                       add { Events.AddHandler (MenuItemDataBoundEvent, value); }
+                       remove { Events.RemoveHandler (MenuItemDataBoundEvent, value); }
+               }
+               
                protected virtual void OnMenuItemClick (MenuEventArgs e)
                {
                        if (Events != null) {
@@ -79,11 +107,20 @@ namespace System.Web.UI.WebControls
                                if (eh != null) eh (this, e);
                        }
                }
+               
+               protected virtual void OnMenuItemDataBound (MenuEventArgs e)
+               {
+                       if (Events != null) {
+                               MenuEventHandler eh = (MenuEventHandler) Events [MenuItemDataBoundEvent];
+                               if (eh != null) eh (this, e);
+                       }
+               }
 
+           [DefaultValueAttribute (null)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               [Editor ("System.Web.UI.Design.MenuItemBindingsEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-               public virtual MenuItemBindingCollection DataBindings {
+           [EditorAttribute ("System.Web.UI.Design.WebControls.MenuBindingsEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+           [MergablePropertyAttribute (false)]
+               public MenuItemBindingCollection DataBindings {
                        get {
                                if (dataBindings == null) {
                                        dataBindings = new MenuItemBindingCollection ();
@@ -96,7 +133,7 @@ namespace System.Web.UI.WebControls
 
                [DefaultValue (500)]
                [ThemeableAttribute (false)]
-               public virtual int DisappearAfter {
+               public int DisappearAfter {
                        get {
                                object o = ViewState ["DisappearAfter"];
                                if (o != null) return (int)o;
@@ -107,11 +144,11 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-               [ThemeableAttribute (false)]
+               [ThemeableAttribute (true)]
                [DefaultValue ("")]
                [UrlProperty]
-               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-               public virtual string DynamicBottomSeparatorImageUrl {
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public string DynamicBottomSeparatorImageUrl {
                        get {
                                object o = ViewState ["dbsiu"];
                                if (o != null) return (string)o;
@@ -122,11 +159,23 @@ namespace System.Web.UI.WebControls
                        }
                }
 
+           [DefaultValueAttribute ("")]
+               public string DynamicItemFormatString {
+                       get {
+                               object o = ViewState ["DynamicItemFormatString"];
+                               if (o != null) return (string)o;
+                               return "";
+                       }
+                       set {
+                               ViewState["DynamicItemFormatString"] = value;
+                       }
+               }
+
                [DefaultValue ("")]
                [UrlProperty]
                [WebCategory ("Appearance")]
-               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-               public virtual string DynamicTopSeparatorImageUrl {
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public string DynamicTopSeparatorImageUrl {
                        get {
                                object o = ViewState ["dtsiu"];
                                if (o != null) return (string)o;
@@ -140,8 +189,8 @@ namespace System.Web.UI.WebControls
                [DefaultValue ("")]
                [UrlProperty]
                [WebCategory ("Appearance")]
-               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-               public virtual string StaticBottomSeparatorImageUrl {
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public string StaticBottomSeparatorImageUrl {
                        get {
                                object o = ViewState ["sbsiu"];
                                if (o != null) return (string)o;
@@ -155,8 +204,8 @@ namespace System.Web.UI.WebControls
                [DefaultValue ("")]
                [UrlProperty]
                [WebCategory ("Appearance")]
-               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-               public virtual string StaticTopSeparatorImageUrl {
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public string StaticTopSeparatorImageUrl {
                        get {
                                object o = ViewState ["stsiu"];
                                if (o != null) return (string)o;
@@ -168,7 +217,7 @@ namespace System.Web.UI.WebControls
                }
 
                [DefaultValue (Orientation.Vertical)]
-               public virtual Orientation Orientation {
+               public Orientation Orientation {
                        get {
                                object o = ViewState ["Orientation"];
                                if (o != null) return (Orientation) o;
@@ -180,8 +229,8 @@ namespace System.Web.UI.WebControls
                }
 
                [DefaultValue (1)]
-               [ThemeableAttribute (false)]
-               public virtual int StaticDisplayLevels {
+               [ThemeableAttribute (true)]
+               public int StaticDisplayLevels {
                        get {
                                object o = ViewState ["StaticDisplayLevels"];
                                if (o != null) return (int)o;
@@ -193,8 +242,20 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-               [DefaultValue ("16px")]
-               [ThemeableAttribute (false)]
+           [DefaultValueAttribute ("")]
+               public string StaticItemFormatString {
+                       get {
+                               object o = ViewState ["StaticItemFormatString"];
+                               if (o != null) return (string)o;
+                               return "";
+                       }
+                       set {
+                               ViewState["StaticItemFormatString"] = value;
+                       }
+               }
+
+               [DefaultValue (typeof (Unit), "16px")]
+               [ThemeableAttribute (true)]
                public Unit StaticSubMenuIndent {
                        get {
                                object o = ViewState ["StaticSubMenuIndent"];
@@ -206,9 +267,9 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-               [ThemeableAttribute (false)]
+               [ThemeableAttribute (true)]
                [DefaultValue (3)]
-               public virtual int MaximumDynamicDisplayLevels {
+               public int MaximumDynamicDisplayLevels {
                        get {
                                object o = ViewState ["MaximumDynamicDisplayLevels"];
                                if (o != null) return (int)o;
@@ -221,7 +282,7 @@ namespace System.Web.UI.WebControls
                }
 
                [DefaultValue (0)]
-               public virtual int DynamicVerticalOffset {
+               public int DynamicVerticalOffset {
                        get {
                                object o = ViewState ["DynamicVerticalOffset"];
                                if (o != null) return (int)o;
@@ -233,7 +294,7 @@ namespace System.Web.UI.WebControls
                }
 
                [DefaultValue (0)]
-               public virtual int DynamicHorizontalOffset {
+               public int DynamicHorizontalOffset {
                        get {
                                object o = ViewState ["DynamicHorizontalOffset"];
                                if (o != null) return (int)o;
@@ -245,7 +306,7 @@ namespace System.Web.UI.WebControls
                }
 
                [DefaultValue (true)]
-               public virtual bool DynamicEnableDefaultPopOutImage {
+               public bool DynamicEnableDefaultPopOutImage {
                        get {
                                object o = ViewState ["dedpoi"];
                                if (o != null) return (bool)o;
@@ -257,7 +318,7 @@ namespace System.Web.UI.WebControls
                }
 
                [DefaultValue (true)]
-               public virtual bool StaticEnableDefaultPopOutImage {
+               public bool StaticEnableDefaultPopOutImage {
                        get {
                                object o = ViewState ["sedpoi"];
                                if (o != null) return (bool)o;
@@ -268,10 +329,11 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
+               [DefaultValueAttribute (null)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [Editor ("System.Web.UI.Design.MenuItemCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-               public virtual MenuItemCollection Items {
+               [Editor ("System.Web.UI.Design.MenuItemCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               [MergablePropertyAttribute (false)]
+               public MenuItemCollection Items {
                        get {
                                if (items == null) {
                                        items = new MenuItemCollection (this);
@@ -283,7 +345,7 @@ namespace System.Web.UI.WebControls
                }
 
                [DefaultValue ('/')]
-               public virtual char PathSeparator {
+               public char PathSeparator {
                        get {
                                object o = ViewState ["PathSeparator"];
                                if(o != null) return (char)o;
@@ -295,7 +357,7 @@ namespace System.Web.UI.WebControls
                }
 
                [DefaultValue (false)]
-               public virtual bool ItemWrap {
+               public bool ItemWrap {
                        get {
                                object o = ViewState ["ItemWrap"];
                                if(o != null) return (bool)o;
@@ -306,11 +368,85 @@ namespace System.Web.UI.WebControls
                        }
                }
 
+               private Style PopOutBoxStyle {
+                       get {
+                               if (popOutBoxStyle == null) {
+                                       popOutBoxStyle = new Style ();
+                                       popOutBoxStyle.BackColor = Color.White;
+                               }
+                               return popOutBoxStyle;
+                       }
+               }
+
+               private Style ControlLinkStyle {
+                       get {
+                               if (controlLinkStyle == null) {
+                                       controlLinkStyle = new Style ();
+                                       controlLinkStyle.AlwaysRenderTextDecoration = true;
+                               }
+                               return controlLinkStyle;
+                       }
+               }
+
+               private Style DynamicMenuItemLinkStyle {
+                       get {
+                               if (dynamicMenuItemLinkStyle == null) {
+                                       dynamicMenuItemLinkStyle = new Style ();
+                               }
+                               return dynamicMenuItemLinkStyle;
+                       }
+               }
+
+               private Style StaticMenuItemLinkStyle {
+                       get {
+                               if (staticMenuItemLinkStyle == null) {
+                                       staticMenuItemLinkStyle = new Style ();
+                               }
+                               return staticMenuItemLinkStyle;
+                       }
+               }
+
+               private Style DynamicSelectedLinkStyle {
+                       get {
+                               if (dynamicSelectedLinkStyle == null) {
+                                       dynamicSelectedLinkStyle = new Style ();
+                               }
+                               return dynamicSelectedLinkStyle;
+                       }
+               }
+
+               private Style StaticSelectedLinkStyle {
+                       get {
+                               if (staticSelectedLinkStyle == null) {
+                                       staticSelectedLinkStyle = new Style ();
+                               }
+                               return staticSelectedLinkStyle;
+                       }
+               }
+
+               private Style DynamicHoverLinkStyle {
+                       get {
+                               if (dynamicHoverLinkStyle == null) {
+                                       dynamicHoverLinkStyle = new Style ();
+                               }
+                               return dynamicHoverLinkStyle;
+                       }
+               }
+
+               private Style StaticHoverLinkStyle {
+                       get {
+                               if (staticHoverLinkStyle == null) {
+                                       staticHoverLinkStyle = new Style ();
+                               }
+                               return staticHoverLinkStyle;
+                       }
+               }
+
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual MenuItemStyle DynamicMenuItemStyle {
+               public MenuItemStyle DynamicMenuItemStyle {
                        get {
                                if (dynamicMenuItemStyle == null) {
                                        dynamicMenuItemStyle = new MenuItemStyle ();
@@ -325,7 +461,7 @@ namespace System.Web.UI.WebControls
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual MenuItemStyle DynamicSelectedStyle {
+               public MenuItemStyle DynamicSelectedStyle {
                        get {
                                if (dynamicSelectedStyle == null) {
                                        dynamicSelectedStyle = new MenuItemStyle ();
@@ -340,7 +476,7 @@ namespace System.Web.UI.WebControls
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual SubMenuStyle DynamicMenuStyle {
+               public SubMenuStyle DynamicMenuStyle {
                        get {
                                if (dynamicMenuStyle == null) {
                                        dynamicMenuStyle = new SubMenuStyle ();
@@ -355,7 +491,7 @@ namespace System.Web.UI.WebControls
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual MenuItemStyle StaticMenuItemStyle {
+               public MenuItemStyle StaticMenuItemStyle {
                        get {
                                if (staticMenuItemStyle == null) {
                                        staticMenuItemStyle = new MenuItemStyle ();
@@ -370,7 +506,7 @@ namespace System.Web.UI.WebControls
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual MenuItemStyle StaticSelectedStyle {
+               public MenuItemStyle StaticSelectedStyle {
                        get {
                                if (staticSelectedStyle == null) {
                                        staticSelectedStyle = new MenuItemStyle ();
@@ -385,7 +521,7 @@ namespace System.Web.UI.WebControls
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual SubMenuStyle StaticMenuStyle {
+               public SubMenuStyle StaticMenuStyle {
                        get {
                                if (staticMenuStyle == null) {
                                        staticMenuStyle = new SubMenuStyle ();
@@ -396,9 +532,10 @@ namespace System.Web.UI.WebControls
                        }
                }
 
+               [DefaultValue (null)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual MenuItemStyleCollection LevelMenuItemStyles {
+           [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public MenuItemStyleCollection LevelMenuItemStyles {
                        get {
                                if (levelMenuItemStyles == null) {
                                        levelMenuItemStyles = new MenuItemStyleCollection ();
@@ -409,9 +546,10 @@ namespace System.Web.UI.WebControls
                        }
                }
 
+               [DefaultValue (null)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
-               [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual MenuItemStyleCollection LevelSelectedStyles {
+           [Editor ("System.Web.UI.Design.WebControls.MenuItemStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public MenuItemStyleCollection LevelSelectedStyles {
                        get {
                                if (levelSelectedStyles == null) {
                                        levelSelectedStyles = new MenuItemStyleCollection ();
@@ -422,11 +560,25 @@ namespace System.Web.UI.WebControls
                        }
                }
 
+               [DefaultValue (null)]
+               [PersistenceMode (PersistenceMode.InnerProperty)]
+           [Editor ("System.Web.UI.Design.WebControls.SubMenuStyleCollectionEditor," + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public SubMenuStyleCollection LevelSubMenuStyles {
+                       get {
+                               if (levelSubMenuStyles == null) {
+                                       levelSubMenuStyles = new SubMenuStyleCollection ();
+                                       if (IsTrackingViewState)
+                                               ((IStateManager)levelSubMenuStyles).TrackViewState();
+                               }
+                               return levelSubMenuStyles;
+                       }
+               }
+
                [PersistenceMode (PersistenceMode.InnerProperty)]
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual Style DynamicHoverStyle {
+               public Style DynamicHoverStyle {
                        get {
                                if (dynamicHoverStyle == null) {
                                        dynamicHoverStyle = new Style ();
@@ -441,7 +593,7 @@ namespace System.Web.UI.WebControls
                [NotifyParentProperty (true)]
                [DefaultValue (null)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
-               public virtual Style StaticHoverStyle {
+               public Style StaticHoverStyle {
                        get {
                                if (staticHoverStyle == null) {
                                        staticHoverStyle = new Style ();
@@ -454,8 +606,8 @@ namespace System.Web.UI.WebControls
                
                [DefaultValue ("")]
                [UrlProperty]
-               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-               public virtual string ScrollDownImageUrl {
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public string ScrollDownImageUrl {
                        get {
                                object o = ViewState ["sdiu"];
                                if (o != null) return (string)o;
@@ -468,8 +620,8 @@ namespace System.Web.UI.WebControls
 
                [DefaultValue ("")]
                [UrlProperty]
-               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-               public virtual string ScrollUpImageUrl {
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public string ScrollUpImageUrl {
                        get {
                                object o = ViewState ["suiu"];
                                if (o != null) return (string)o;
@@ -481,11 +633,11 @@ namespace System.Web.UI.WebControls
                }
 
                [Localizable (true)]
-               public virtual string ScrollDownText {
+               public string ScrollDownText {
                        get {
                                object o = ViewState ["ScrollDownText"];
                                if (o != null) return (string) o;
-                               return "";
+                               return Locale.GetText ("Scroll down");
                        }
                        set {
                                ViewState["ScrollDownText"] = value;
@@ -493,21 +645,37 @@ namespace System.Web.UI.WebControls
                }
 
                [Localizable (true)]
-               public virtual string ScrollUpText {
+               public string ScrollUpText {
                        get {
                                object o = ViewState ["ScrollUpText"];
                                if (o != null) return (string) o;
-                               return "";
+                               return Locale.GetText ("Scroll up");
                        }
                        set {
                                ViewState["ScrollUpText"] = value;
                        }
                }
 
+               [MonoTODO]
+               public string DynamicPopOutImageTextFormatString 
+               {
+                       get
+                       {
+                               object o = ViewState ["dpoitf"];
+                               if (o != null) return (string) o;
+                               return Locale.GetText ("Expand {0}");
+                       }
+                       set
+                       {
+                               ViewState ["dpoitf"] = value;
+                       }
+               }
+               
+
                [DefaultValue ("")]
                [UrlProperty]
-               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-               public virtual string DynamicPopOutImageUrl {
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public string DynamicPopOutImageUrl {
                        get {
                                object o = ViewState ["dpoiu"];
                                if (o != null) return (string)o;
@@ -518,10 +686,26 @@ namespace System.Web.UI.WebControls
                        }
                }
 
+               [MonoTODO]
+               public string StaticPopOutImageTextFormatString
+               {
+                       get
+                       {
+                               object o = ViewState ["spoitf"];
+                               if (o != null) return (string) o;
+                               return Locale.GetText ("Expand {0}");
+                       }
+                       set
+                       {
+                               ViewState ["spoitf"] = value;
+                       }
+               }
+               
+
                [DefaultValue ("")]
                [UrlProperty]
-               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
-               public virtual string StaticPopOutImageUrl {
+               [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
+               public string StaticPopOutImageUrl {
                        get {
                                object o = ViewState ["spoiu"];
                                if (o != null) return (string)o;
@@ -533,7 +717,7 @@ namespace System.Web.UI.WebControls
                }
 
                [DefaultValue ("")]
-               public virtual string Target {
+               public string Target {
                        get {
                                object o = ViewState ["Target"];
                                if (o != null) return (string) o;
@@ -547,6 +731,7 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
+           [Browsable (false)]
                public ITemplate StaticItemTemplate {
                        get { return staticItemTemplate; }
                        set { staticItemTemplate = value; }
@@ -555,6 +740,7 @@ namespace System.Web.UI.WebControls
                [DefaultValue (null)]
                [TemplateContainer (typeof(MenuItemTemplateContainer), BindingDirection.OneWay)]
                [PersistenceMode (PersistenceMode.InnerProperty)]
+           [Browsable (false)]
                public ITemplate DynamicItemTemplate {
                        get { return dynamicItemTemplate; }
                        set { dynamicItemTemplate = value; }
@@ -563,22 +749,43 @@ namespace System.Web.UI.WebControls
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public MenuItem SelectedItem {
-                       get { return selectedItem; }
+                       get {
+                               if (selectedItem == null && selectedItemPath != null) {
+                                       selectedItem = FindItemByPos (selectedItemPath);
+                               }
+                               
+                               return selectedItem;
+                       }
                }
 
                [Browsable (false)]
+               [DefaultValue ("")]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public string SelectedValue {
-                       get { return selectedItem != null ? selectedItem.Value : null; }
+                       get { return selectedItem != null ? selectedItem.Value : ""; }
+               }
+
+               [MonoTODO]
+               [Localizable (true)]
+               public string SkipLinkText 
+               {
+                       get {
+                               object o = ViewState ["SkipLinkText"];
+                               if (o != null)
+                                       return (string) o;
+                               return "Skip Navigation Links";
+                       }
+                       set {
+                               ViewState ["SkipLinkText"] = value;
+                       }
                }
+               
 
                internal void SetSelectedItem (MenuItem item)
                {
                        if (selectedItem == item) return;
-                       if (selectedItem != null)
-                               selectedItem.SelectedFlag = false;
                        selectedItem = item;
-                       selectedItem.SelectedFlag = true;
+                       selectedItemPath = item.Path;
                }
                
                public MenuItem FindItem (string valuePath)
@@ -627,23 +834,78 @@ namespace System.Web.UI.WebControls
                protected internal override void PerformDataBinding ()
                {
                        base.PerformDataBinding ();
+
+                       // Do not attempt to bind data if there is no
+                       // data source set.
+                       if (!IsBoundUsingDataSourceID && (DataSource == null)) {
+                               EnsureChildControlsDataBound ();
+                               return;
+                       }
+
+                       InitializeDataBindings ();
+
                        HierarchicalDataSourceView data = GetData ("");
+
+                       if (data == null) {
+                               throw new InvalidOperationException ("No view returned by data source control.");
+                       }
+                       Items.Clear ();
                        IHierarchicalEnumerable e = data.Select ();
-                       foreach (object obj in e) {
-                               IHierarchyData hdata = e.GetHierarchyData (obj);
+                       FillBoundChildrenRecursive (e, Items);
+
+                       CreateChildControlsForItems ();
+                       ChildControlsCreated = true;
+
+                       EnsureChildControlsDataBound ();
+               }
+
+               private void FillBoundChildrenRecursive (IHierarchicalEnumerable hEnumerable, MenuItemCollection itemCollection) {
+                       foreach (object obj in hEnumerable) {
+                               IHierarchyData hdata = hEnumerable.GetHierarchyData (obj);
                                MenuItem item = new MenuItem ();
+                               itemCollection.Add (item);
                                item.Bind (hdata);
-                               Items.Add (item);
+                               OnMenuItemDataBound (new MenuEventArgs (item));
+
+                               if (hdata == null || !hdata.HasChildren)
+                                       continue;
+
+                               IHierarchicalEnumerable e = hdata.GetChildren ();
+                               FillBoundChildrenRecursive (e, item.ChildItems);
                        }
                }
                
-               void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
+               protected void SetItemDataBound (MenuItem node, bool dataBound)
+               {
+                       node.SetDataBound (dataBound);
+               }
+               
+               protected void SetItemDataPath (MenuItem node, string dataPath)
+               {
+                       node.SetDataPath (dataPath);
+               }
+               
+               protected void SetItemDataItem (MenuItem node, object dataItem)
+               {
+                       node.SetDataItem (dataItem);
+               }
+               
+               protected internal virtual void RaisePostBackEvent (string eventArgument)
                {
+                       if (!Enabled)
+                               return;
+
+                       EnsureChildControls();
                        MenuItem item = FindItemByPos (eventArgument);
                        if (item == null) return;
                        item.Selected = true;
                        OnMenuItemClick (new MenuEventArgs (item));
                }
+
+               void IPostBackEventHandler.RaisePostBackEvent (string eventArgument)
+               {
+                       RaisePostBackEvent (eventArgument);
+               }
                
                MenuItem FindItemByPos (string path)
                {
@@ -686,6 +948,8 @@ namespace System.Web.UI.WebControls
                                ((IStateManager)levelMenuItemStyles).TrackViewState();
                        if (levelSelectedStyles != null)
                                ((IStateManager)levelSelectedStyles).TrackViewState();
+                       if (levelSubMenuStyles != null)
+                               ((IStateManager)levelSubMenuStyles).TrackViewState();
                        if (dynamicSelectedStyle != null)
                                dynamicSelectedStyle.TrackViewState();
                        if (staticMenuItemStyle != null)
@@ -702,7 +966,7 @@ namespace System.Web.UI.WebControls
 
                protected override object SaveViewState()
                {
-                       object[] states = new object [13];
+                       object[] states = new object [14];
                        states[0] = base.SaveViewState ();
                        states[1] = dataBindings == null ? null : ((IStateManager)dataBindings).SaveViewState();
                        states[2] = items == null ? null : ((IStateManager)items).SaveViewState();
@@ -716,6 +980,7 @@ namespace System.Web.UI.WebControls
                        states[10] = staticSelectedStyle == null ? null : staticSelectedStyle.SaveViewState();
                        states[11] = staticHoverStyle == null ? null : staticHoverStyle.SaveViewState();
                        states[12] = dynamicHoverStyle == null ? null : dynamicHoverStyle.SaveViewState();
+                       states[13] = levelSubMenuStyles == null ? null : ((IStateManager)levelSubMenuStyles).SaveViewState();
 
                        for (int i = states.Length - 1; i >= 0; i--) {
                                if (states [i] != null)
@@ -734,37 +999,156 @@ namespace System.Web.UI.WebControls
                        base.LoadViewState (states[0]);
                        
                        if (states[1] != null)
-                               ((IStateManager)dataBindings).LoadViewState(states[1]);
+                               ((IStateManager)DataBindings).LoadViewState(states[1]);
                        if (states[2] != null)
                                ((IStateManager)Items).LoadViewState(states[2]);
                        if (states[3] != null)
-                               dynamicMenuItemStyle.LoadViewState (states[3]);
+                               DynamicMenuItemStyle.LoadViewState (states[3]);
                        if (states[4] != null)
-                               dynamicMenuStyle.LoadViewState (states[4]);
+                               DynamicMenuStyle.LoadViewState (states[4]);
                        if (states[5] != null)
-                               ((IStateManager)levelMenuItemStyles).LoadViewState(states[5]);
+                               ((IStateManager)LevelMenuItemStyles).LoadViewState(states[5]);
                        if (states[6] != null)
-                               ((IStateManager)levelSelectedStyles).LoadViewState(states[6]);
+                               ((IStateManager)LevelSelectedStyles).LoadViewState(states[6]);
                        if (states[7] != null)
-                               dynamicSelectedStyle.LoadViewState (states[7]);
+                               DynamicSelectedStyle.LoadViewState (states[7]);
                        if (states[8] != null)
-                               staticMenuItemStyle.LoadViewState (states[8]);
+                               StaticMenuItemStyle.LoadViewState (states[8]);
                        if (states[9] != null)
-                               staticMenuStyle.LoadViewState (states[9]);
+                               StaticMenuStyle.LoadViewState (states[9]);
                        if (states[10] != null)
-                               staticSelectedStyle.LoadViewState (states[10]);
+                               StaticSelectedStyle.LoadViewState (states[10]);
                        if (states[11] != null)
-                               staticHoverStyle.LoadViewState (states[11]);
+                               StaticHoverStyle.LoadViewState (states[11]);
                        if (states[12] != null)
-                               dynamicHoverStyle.LoadViewState (states[12]);
+                               DynamicHoverStyle.LoadViewState (states[12]);
+                       if (states[13] != null)
+                               ((IStateManager)LevelSubMenuStyles).LoadViewState(states[13]);
+               }
+               
+               protected internal override void OnInit (EventArgs e)
+               {
+                       Page.RegisterRequiresControlState (this);
+                       base.OnInit (e);
+               }
+               
+               protected internal override void LoadControlState (object ob)
+               {
+                       if (ob == null) return;
+                       object[] state = (object[]) ob;
+                       base.LoadControlState (state[0]);
+                       selectedItemPath = state[1] as string;
+               }
+               
+               protected internal override object SaveControlState ()
+               {
+                       object bstate = base.SaveControlState ();
+                       object mstate = selectedItemPath;
+                       
+                       if (bstate != null || mstate != null)
+                               return new object[] { bstate, mstate };
+                       else
+                               return null;
                }
                
-               protected override void OnPreRender (EventArgs e)
+               protected internal override void CreateChildControls ()
+               {
+                       if (!IsBoundUsingDataSourceID && (DataSource == null)) {
+                               CreateChildControlsForItems ();
+                       }
+                       else {
+                               EnsureDataBound ();
+                       }
+               }
+
+               private void CreateChildControlsForItems () {
+                       Controls.Clear ();
+                       // Check for HasChildViewState to avoid unnecessary calls to ClearChildViewState.
+                       if (HasChildViewState)
+                               ClearChildViewState ();
+                       _menuItemControls = new Hashtable ();
+                       CreateChildControlsForItems (Items);
+                       _requiresChildControlsDataBinding = true;
+               }
+
+               private void CreateChildControlsForItems (MenuItemCollection items ) {
+                       foreach (MenuItem item in items) {
+                               bool isDynamicItem = IsDynamicItem (item);
+                               if (isDynamicItem && dynamicItemTemplate != null) {
+                                       MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
+                                       dynamicItemTemplate.InstantiateIn (cter);
+                                       _menuItemControls [item] = cter;
+                                       Controls.Add (cter);
+                               }
+                               else if (!isDynamicItem && staticItemTemplate != null) {
+                                       MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
+                                       staticItemTemplate.InstantiateIn (cter);
+                                       _menuItemControls [item] = cter;
+                                       Controls.Add (cter);
+                               }
+                               if (item.HasChildData)
+                                       CreateChildControlsForItems (item.ChildItems);
+                       }
+               }
+
+               protected override void EnsureDataBound ()
+               {
+                       base.EnsureDataBound ();
+                       
+                       EnsureChildControlsDataBound ();
+               }
+
+               private void EnsureChildControlsDataBound () {
+                       if (!_requiresChildControlsDataBinding)
+                               return;
+                       DataBindChildren ();
+                       _requiresChildControlsDataBinding = false;
+               }
+
+               [MonoTODO]
+               protected override IDictionary GetDesignModeState ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               [MonoTODO]
+               protected override void SetDesignModeState (IDictionary data)
+               {
+                       throw new NotImplementedException ();
+               }
+                               
+               public override ControlCollection Controls {
+                       get { return base.Controls; }
+               }
+               
+               public sealed override void DataBind ()
+               {
+                       base.DataBind ();
+               }
+               
+               protected override bool OnBubbleEvent (object source, EventArgs args)
+               {
+                       if (!(args is CommandEventArgs))
+                               return false;
+
+                       MenuEventArgs menuArgs = args as MenuEventArgs;
+                       if (menuArgs != null && string.Equals (menuArgs.CommandName, MenuItemClickCommandName))
+                               OnMenuItemClick (menuArgs);
+                       return true;
+               }
+
+               protected override void OnDataBinding (EventArgs e)
+               {
+                       EnsureChildControls ();
+                       base.OnDataBinding (e);
+               }
+               
+               protected internal override void OnPreRender (EventArgs e)
                {
                        base.OnPreRender (e);
                        
                        if (!Page.ClientScript.IsClientScriptIncludeRegistered (typeof(Menu), "Menu.js")) {
-                               string url = Page.GetWebResourceUrl (typeof(Menu), "Menu.js");
+                               string url = Page.ClientScript.GetWebResourceUrl (typeof(Menu), "Menu.js");
                                Page.ClientScript.RegisterClientScriptInclude (typeof(Menu), "Menu.js", url);
                        }
                        
@@ -776,48 +1160,76 @@ namespace System.Web.UI.WebControls
                                script += string.Format ("{0}.dho = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (DynamicHorizontalOffset));
                        if (DynamicVerticalOffset != 0)
                                script += string.Format ("{0}.dvo = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (DynamicVerticalOffset));
-                               
+                       
                        // The order in which styles are defined matters when more than one class
                        // is assigned to an element
+                       RegisterStyle (PopOutBoxStyle);
+                       RegisterStyle (ControlStyle, ControlLinkStyle);
                        
-                       if (dynamicMenuStyle != null)
-                               RegisterItemStyle (dynamicMenuStyle);
-                       if (staticMenuStyle != null)
-                               RegisterItemStyle (staticMenuStyle);
-               
                        if (staticMenuItemStyle != null)
-                               RegisterItemStyle (staticMenuItemStyle);
-                       if (staticSelectedStyle != null)
-                               RegisterItemStyle (staticSelectedStyle);
+                               RegisterStyle (StaticMenuItemStyle, StaticMenuItemLinkStyle);
 
+                       if (staticMenuStyle != null)
+                               RegisterStyle (StaticMenuStyle);
+                       
                        if (dynamicMenuItemStyle != null)
-                               RegisterItemStyle (dynamicMenuItemStyle);
-                       if (dynamicSelectedStyle != null)
-                               RegisterItemStyle (dynamicSelectedStyle);
+                               RegisterStyle (DynamicMenuItemStyle, DynamicMenuItemLinkStyle);
 
-                       if (levelMenuItemStyles != null)
-                               foreach (Style style in levelMenuItemStyles)
-                                       RegisterItemStyle (style);
+                       if (dynamicMenuStyle != null)
+                               RegisterStyle (DynamicMenuStyle);
 
-                       if (levelSelectedStyles != null)
-                               foreach (Style style in levelSelectedStyles)
-                                       RegisterItemStyle (style);
+                       if (levelMenuItemStyles != null) {
+                               levelMenuItemLinkStyles = new List<Style> ();
+                               foreach (Style style in levelMenuItemStyles) {
+                                       Style linkStyle = new Style ();
+                                       levelMenuItemLinkStyles.Add (linkStyle);
+                                       RegisterStyle (style, linkStyle);
+                               }
+                       }
+               
+                       if (levelSubMenuStyles != null)
+                               foreach (Style style in levelSubMenuStyles)
+                                       RegisterStyle (style);
+
+                       if (staticSelectedStyle != null)
+                               RegisterStyle (staticSelectedStyle, StaticSelectedLinkStyle);
                        
-                       if (dynamicHoverStyle != null)
-                               RegisterItemStyle (dynamicHoverStyle);
-                       if (staticHoverStyle != null)
-                               RegisterItemStyle (staticHoverStyle);
+                       if (dynamicSelectedStyle != null)
+                               RegisterStyle (dynamicSelectedStyle, DynamicSelectedLinkStyle);
 
-                       if (staticHoverStyle != null)
+                       if (levelSelectedStyles != null) {
+                               levelSelectedLinkStyles = new List<Style> ();
+                               foreach (Style style in levelSelectedStyles) {
+                                       Style linkStyle = new Style ();
+                                       levelSelectedLinkStyles.Add (linkStyle);
+                                       RegisterStyle (style, linkStyle);
+                               }
+                       }
+                       
+                       if (staticHoverStyle != null) {
+                               if (Page.Header == null)
+                                       throw new InvalidOperationException ("Using Menu.StaticHoverStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
+                               RegisterStyle (staticHoverStyle, StaticHoverLinkStyle);
                                script += string.Format ("{0}.staticHover = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (staticHoverStyle.RegisteredCssClass));
-                       if (dynamicHoverStyle != null)
+                               script += string.Format ("{0}.staticLinkHover = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (StaticHoverLinkStyle.RegisteredCssClass));
+                       }
+                       
+                       if (dynamicHoverStyle != null) {
+                               if (Page.Header == null)
+                                       throw new InvalidOperationException ("Using Menu.DynamicHoverStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
+                               RegisterStyle (dynamicHoverStyle, DynamicHoverLinkStyle);
                                script += string.Format ("{0}.dynamicHover = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (dynamicHoverStyle.RegisteredCssClass));
+                               script += string.Format ("{0}.dynamicLinkHover = {1};\n", cmenu, ClientScriptManager.GetScriptLiteral (DynamicHoverLinkStyle.RegisteredCssClass));
+                       }
                        
                        Page.ClientScript.RegisterStartupScript (typeof(Menu), ClientID, script, true);
 
+               }
+
+               void InitializeDataBindings () {
                        if (dataBindings != null && dataBindings.Count > 0) {
                                bindings = new Hashtable ();
-                               foreach (TreeNodeBinding bin in dataBindings) {
+                               foreach (MenuItemBinding bin in dataBindings) {
                                        string key = GetBindingKey (bin.DataMember, bin.Depth);
                                        bindings [key] = bin;
                                }
@@ -825,44 +1237,122 @@ namespace System.Web.UI.WebControls
                        else
                                bindings = null;
                }
+
+               string IncrementStyleClassName () {
+                       registeredStylesCounter++;
+                       return ClientID + "_" + registeredStylesCounter;
+               }
+
+               void RegisterStyle (Style baseStyle, Style linkStyle) {
+                       linkStyle.CopyTextStylesFrom (baseStyle);
+                       linkStyle.BorderStyle = BorderStyle.None;
+                       RegisterStyle (linkStyle);
+                       RegisterStyle (baseStyle);
+               }
+
+               void RegisterStyle (Style baseStyle)
+               {
+                       if (Page.Header == null)
+                               return;
+                       string className = IncrementStyleClassName ();
+                       baseStyle.SetRegisteredCssClass (className);
+                       Page.Header.StyleSheet.CreateStyleRule (baseStyle, this, "." + className);
+               }
+               
+               protected internal override void Render (HtmlTextWriter writer)
+               {
+                       if (Items.Count > 0)
+                               base.Render (writer);
+               }
                
-               void RegisterItemStyle (Style baseStyle)
+               protected override void AddAttributesToRender (HtmlTextWriter writer)
                {
-                       Page.Header.StyleSheet.RegisterStyle (baseStyle, this);
-                       Style ts = new Style ();
-                       ts.CopyTextStylesFrom (baseStyle);
-                       Page.Header.StyleSheet.CreateStyleRule (ts, "." + baseStyle.RegisteredCssClass + " A", this);
+                       writer.AddAttribute ("cellpadding", "0");
+                       writer.AddAttribute ("cellspacing", "0");
+                       writer.AddAttribute ("border", "0");
+                       if (Page.Header != null) {
+                               // styles are registered
+                               if (staticMenuStyle != null) {
+                                       AddCssClass (ControlStyle, staticMenuStyle.CssClass);
+                                       AddCssClass (ControlStyle, staticMenuStyle.RegisteredCssClass);
+                               }
+                               if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0) {
+                                       AddCssClass (ControlStyle, levelSubMenuStyles [0].CssClass);
+                                       AddCssClass (ControlStyle, levelSubMenuStyles [0].RegisteredCssClass);
+                               }
+                       }
+                       else {
+                               // styles are not registered
+                               if (staticMenuStyle != null){
+                                       ControlStyle.CopyFrom (staticMenuStyle);
+                               }
+                               if (levelSubMenuStyles != null && levelSubMenuStyles.Count > 0) {
+                                       ControlStyle.CopyFrom (levelSubMenuStyles [0]);
+                               }
+                       }
+                       base.AddAttributesToRender (writer);
+               }
+
+               void AddCssClass (Style style, string cssClass) {
+                       style.AddCssClass (cssClass);
                }
                
                public override void RenderBeginTag (HtmlTextWriter writer)
                {
-                       RenderMenuBeginTagAttributes (writer, false);
+                       if (SkipLinkText != "") {
+                               System.Web.UI.HtmlControls.HtmlAnchor anchor = new System.Web.UI.HtmlControls.HtmlAnchor ();
+                               anchor.HRef = "#" + ClientID + "_SkipLink";
+
+                               Image img = new Image ();
+                               ClientScriptManager csm = new ClientScriptManager (null);
+                               img.ImageUrl = csm.GetWebResourceUrl (typeof (SiteMapPath), "transparent.gif");
+                               img.Attributes.Add ("height", "0");
+                               img.Attributes.Add ("width", "0");
+                               img.AlternateText = SkipLinkText;
+
+                               anchor.Controls.Add (img);
+                               anchor.Render (writer);
+                       }
                        base.RenderBeginTag (writer);
                }
                
                public override void RenderEndTag (HtmlTextWriter writer)
                {
                        base.RenderEndTag (writer);
-                       
-                       // Render dynamic menus outside the main control tag
-                       for (int n=0; n<dynamicMenus.Count; n++) {
-                               MenuItem item = (MenuItem) dynamicMenus [n];
-                               RenderDynamicMenu (writer, item);
+
+                       if (SkipLinkText != "") {
+                               System.Web.UI.HtmlControls.HtmlAnchor anchor = new System.Web.UI.HtmlControls.HtmlAnchor ();
+                               anchor.ID = "SkipLink";
+                               anchor.Render (writer);
                        }
-                       dynamicMenus = null;
                }
                
-               protected override void RenderContents (HtmlTextWriter writer)
+               protected internal override void RenderContents (HtmlTextWriter writer)
                {
-                       dynamicMenus = new ArrayList ();
-                       RenderMenuBody (writer, Items, Orientation == Orientation.Vertical, false);
+                       RenderMenuBody (writer, Items, Orientation == Orientation.Vertical, false, false);
+               }
+
+               void RenderDynamicMenu (HtmlTextWriter writer, MenuItemCollection items) {
+                       for (int n = 0; n < items.Count; n++) {
+                               if (DisplayChildren (items [n])) {
+                                       RenderDynamicMenu (writer, items [n]);
+                                       RenderDynamicMenu (writer, items [n].ChildItems);
+                               }
+                       }
                }
                
                void RenderDynamicMenu (HtmlTextWriter writer, MenuItem item)
                {
-                       if (dynamicMenuStyle != null)
-                               writer.AddAttribute ("class", dynamicMenuStyle.RegisteredCssClass);
-                       
+                       SubMenuStyle style = new SubMenuStyle ();
+                       if (Page.Header != null) {
+                               AddCssClass (style, PopOutBoxStyle.RegisteredCssClass);
+                       }
+                       else {
+                               style.CopyFrom (PopOutBoxStyle);
+                       }
+                       FillMenuStyle (true, item.Depth + 1, style);
+                       style.AddAttributesToRender (writer);
+
                        writer.AddStyleAttribute ("visibility", "hidden");
                        writer.AddStyleAttribute ("position", "absolute");
                        writer.AddStyleAttribute ("left", "0px");
@@ -878,7 +1368,7 @@ namespace System.Web.UI.WebControls
                        writer.AddAttribute ("onmouseout", string.Format ("javascript:Menu_OutScrollBtn ('{0}','{1}','{2}')", ClientID, item.Path, "u"));
                        writer.RenderBeginTag (HtmlTextWriterTag.Div);
                        
-                       string src = ScrollUpImageUrl != "" ? ScrollUpImageUrl : Page.GetWebResourceUrl (typeof(Menu), "arrow_up.gif");
+                       string src = ScrollUpImageUrl != "" ? ScrollUpImageUrl : Page.ClientScript.GetWebResourceUrl (typeof(Menu), "arrow_up.gif");
                        writer.AddAttribute ("src", src);
                        writer.AddAttribute ("alt", ScrollUpText);
                        writer.RenderBeginTag (HtmlTextWriterTag.Img);
@@ -891,7 +1381,7 @@ namespace System.Web.UI.WebControls
                        writer.AddAttribute ("id", GetItemClientId (item, "cc"));       // Content
                        writer.RenderBeginTag (HtmlTextWriterTag.Div);
                        
-                       RenderMenu (writer, item.ChildItems, true, true);
+                       RenderMenu (writer, item.ChildItems, true, true, item.Depth + 1, false);
                        
                        writer.RenderEndTag (); // DIV Content
                        writer.RenderEndTag (); // DIV Scroll container
@@ -904,7 +1394,7 @@ namespace System.Web.UI.WebControls
                        writer.AddAttribute ("onmouseout", string.Format ("javascript:Menu_OutScrollBtn ('{0}','{1}','{2}')", ClientID, item.Path, "d"));
                        writer.RenderBeginTag (HtmlTextWriterTag.Div);
                        
-                       src = ScrollDownImageUrl != "" ? ScrollDownImageUrl : Page.GetWebResourceUrl (typeof(Menu), "arrow_down.gif");
+                       src = ScrollDownImageUrl != "" ? ScrollDownImageUrl : Page.ClientScript.GetWebResourceUrl (typeof(Menu), "arrow_down.gif");
                        writer.AddAttribute ("src", src);
                        writer.AddAttribute ("alt", ScrollDownText);
                        writer.RenderBeginTag (HtmlTextWriterTag.Img);
@@ -914,26 +1404,59 @@ namespace System.Web.UI.WebControls
                        
                        writer.RenderEndTag (); // DIV menu
                }
-               
-               void RenderMenuBeginTagAttributes (HtmlTextWriter writer, bool dynamic)
-               {
+
+               void RenderMenuBeginTagAttributes (HtmlTextWriter writer, bool dynamic, int menuLevel) {
                        writer.AddAttribute ("cellpadding", "0");
                        writer.AddAttribute ("cellspacing", "0");
+                       writer.AddAttribute ("border", "0");
 
-                       if (!dynamic && staticMenuStyle != null)
-                               writer.AddAttribute ("class", staticMenuStyle.RegisteredCssClass);
+                       if (!dynamic) {
+                               SubMenuStyle style = new SubMenuStyle ();
+                               FillMenuStyle (dynamic, menuLevel, style);
+                               style.AddAttributesToRender (writer);
+                       }
                }
-               
-               void RenderMenu (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic)
+
+               private void FillMenuStyle (bool dynamic, int menuLevel, SubMenuStyle style) {
+                       if (Page.Header != null) {
+                               // styles are registered
+                               if (!dynamic && staticMenuStyle != null) {
+                                       AddCssClass (style, staticMenuStyle.CssClass);
+                                       AddCssClass (style, staticMenuStyle.RegisteredCssClass);
+                               }
+                               if (dynamic && dynamicMenuStyle != null) {
+                                       AddCssClass (style, dynamicMenuStyle.CssClass);
+                                       AddCssClass (style, dynamicMenuStyle.RegisteredCssClass);
+                               }
+                               if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
+                                       AddCssClass (style, levelSubMenuStyles [menuLevel].CssClass);
+                                       AddCssClass (style, levelSubMenuStyles [menuLevel].RegisteredCssClass);
+                               }
+                       }
+                       else {
+                               // styles are not registered
+                               if (!dynamic && staticMenuStyle != null) {
+                                       style.CopyFrom (staticMenuStyle);
+                               }
+                               if (dynamic && dynamicMenuStyle != null) {
+                                       style.CopyFrom (dynamicMenuStyle);
+                               }
+                               if (levelSubMenuStyles != null && levelSubMenuStyles.Count > menuLevel) {
+                                       style.CopyFrom (levelSubMenuStyles [menuLevel]);
+                               }
+                       }
+               }
+
+               void RenderMenu (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic, int menuLevel, bool notLast)
                {
-                       RenderMenuBeginTag (writer, dynamic);
-                       RenderMenuBody (writer, items, vertical, dynamic);
+                       RenderMenuBeginTag (writer, dynamic, menuLevel);
+                       RenderMenuBody (writer, items, vertical, dynamic, notLast);
                        RenderMenuEndTag (writer);
                }
                
-               void RenderMenuBeginTag (HtmlTextWriter writer, bool dynamic)
+               void RenderMenuBeginTag (HtmlTextWriter writer, bool dynamic, int menuLevel)
                {
-                       RenderMenuBeginTagAttributes (writer, dynamic);
+                       RenderMenuBeginTagAttributes (writer, dynamic, menuLevel);
                        writer.RenderBeginTag (HtmlTextWriterTag.Table);
                }
                
@@ -941,87 +1464,72 @@ namespace System.Web.UI.WebControls
                {
                        writer.RenderEndTag ();
                }
-               
-               void RenderMenuBody (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic)
-               {
-                       if (!vertical) writer.RenderBeginTag (HtmlTextWriterTag.Tr);
-                       
-                       for (int n=0; n<items.Count; n++) {
+
+               void RenderMenuBody (HtmlTextWriter writer, MenuItemCollection items, bool vertical, bool dynamic, bool notLast) {
+                       if (!vertical)
+                               writer.RenderBeginTag (HtmlTextWriterTag.Tr);
+
+                       int count = items.Count;
+                       for (int n = 0; n < count; n++) {
                                MenuItem item = items [n];
-                               if (n > 0) {
-                                       int itemSpacing = GetItemSpacing (item, dynamic);
-                                       if (itemSpacing != 0) {
-                                               if (vertical) {
-                                                       writer.AddAttribute ("height", itemSpacing + "px");
-                                                       writer.RenderBeginTag (HtmlTextWriterTag.Tr);
-                                                       writer.RenderEndTag ();
-                                               } else {
-                                                       writer.AddAttribute ("width", itemSpacing + "px");
-                                                       writer.RenderBeginTag (HtmlTextWriterTag.Td);
-                                                       writer.RenderEndTag ();
-                                               }
-                                       }
-                               }
-                               RenderMenuItem (writer, item);
+                               RenderMenuItem (writer, item, (n + 1 == count) ? notLast : true, n == 0);
                        }
-                       
-                       if (!vertical) writer.RenderEndTag ();  // TR
+
+                       if (!vertical)
+                               writer.RenderEndTag (); // TR
                }
-               
-               void RenderMenuItem (HtmlTextWriter writer, MenuItem item)
-               {
-                       bool displayChildren = (item.Depth + 1 < StaticDisplayLevels + MaximumDynamicDisplayLevels);
-                       bool dynamicChildren = displayChildren && (item.Depth + 1 >= StaticDisplayLevels) && item.ChildItems.Count > 0;
-                       bool isDynamicItem = item.Depth + 1 > StaticDisplayLevels;
-                       bool vertical = (Orientation == Orientation.Vertical) || isDynamicItem;
 
-                       if (vertical)
+               void RenderMenuItemSpacing (HtmlTextWriter writer, Unit itemSpacing, bool vertical) {
+                       if (vertical) {
+                               writer.AddStyleAttribute ("height", itemSpacing.ToString ());
                                writer.RenderBeginTag (HtmlTextWriterTag.Tr);
-                       
-                       Style itemStyle = null;
-                       if (levelMenuItemStyles != null && item.Depth < levelMenuItemStyles.Count)
-                               itemStyle = levelMenuItemStyles [item.Depth];
-                       else if (isDynamicItem) {
-                               if (dynamicMenuItemStyle != null)
-                                       itemStyle = dynamicMenuItemStyle;
-                       } else {
-                               if (staticMenuItemStyle != null)
-                                       itemStyle = staticMenuItemStyle;
+                               writer.RenderBeginTag (HtmlTextWriterTag.Td);
+                               writer.RenderEndTag ();
+                               writer.RenderEndTag ();
                        }
-                       
-                       Style selectedStyle = null;
-                       if (item == SelectedItem) {
-                               if (levelSelectedStyles != null && item.Depth < levelSelectedStyles.Count)
-                                       selectedStyle = levelSelectedStyles [item.Depth];
-                               else if (isDynamicItem) {
-                                       if (dynamicSelectedStyle != null)
-                                               selectedStyle = dynamicSelectedStyle;
-                               } else {
-                                       if (staticSelectedStyle != null)
-                                               selectedStyle = staticSelectedStyle;
-                               }
+                       else {
+                               writer.AddStyleAttribute ("width", itemSpacing.ToString ());
+                               writer.RenderBeginTag (HtmlTextWriterTag.Td);
+                               writer.RenderEndTag ();
                        }
+               }
+               
+               private bool IsDynamicItem (MenuItem item) {
+                       return item.Depth + 1 > StaticDisplayLevels;
+               }
+
+               private bool DisplayChildren (MenuItem item) {
+                       return (item.Depth + 1 < StaticDisplayLevels + MaximumDynamicDisplayLevels) && item.ChildItems.Count > 0;
+               }
+
+               void RenderMenuItem (HtmlTextWriter writer, MenuItem item, bool notLast, bool isFirst) {
+                       bool displayChildren = DisplayChildren (item);
+                       bool dynamicChildren = displayChildren && (item.Depth + 1 >= StaticDisplayLevels);
+                       bool isDynamicItem = IsDynamicItem (item);
+                       bool vertical = (Orientation == Orientation.Vertical) || isDynamicItem;
                        
-                       string cls = "";
-                       if (itemStyle != null) cls += itemStyle.RegisteredCssClass + " ";
-                       if (selectedStyle != null) cls += selectedStyle.RegisteredCssClass + " ";
-                       if (cls != "")
-                               writer.AddAttribute ("class", cls);
-                       
+                       Unit itemSpacing = GetItemSpacing (item, isDynamicItem);
+
+                       if (itemSpacing != Unit.Empty && (item.Depth > 0 || !isFirst))
+                               RenderMenuItemSpacing (writer, itemSpacing, vertical);
+
+                       if (vertical)
+                               writer.RenderBeginTag (HtmlTextWriterTag.Tr);
+
                        string parentId = isDynamicItem ? "'" + item.Parent.Path + "'" : "null";
                        if (dynamicChildren) {
                                writer.AddAttribute ("onmouseover", string.Format ("javascript:Menu_OverItem ('{0}','{1}',{2})", ClientID, item.Path, parentId));
                                writer.AddAttribute ("onmouseout", string.Format ("javascript:Menu_OutItem ('{0}','{1}')", ClientID, item.Path));
-                       } else if (isDynamicItem) {
+                       }
+                       else if (isDynamicItem) {
                                writer.AddAttribute ("onmouseover", string.Format ("javascript:Menu_OverDynamicLeafItem ('{0}','{1}',{2})", ClientID, item.Path, parentId));
                                writer.AddAttribute ("onmouseout", string.Format ("javascript:Menu_OutItem ('{0}','{1}',{2})", ClientID, item.Path, parentId));
-                       } else {
+                       }
+                       else {
                                writer.AddAttribute ("onmouseover", string.Format ("javascript:Menu_OverStaticLeafItem ('{0}','{1}')", ClientID, item.Path));
                                writer.AddAttribute ("onmouseout", string.Format ("javascript:Menu_OutItem ('{0}','{1}')", ClientID, item.Path));
                        }
-                       
-                       writer.AddAttribute ("id", GetItemClientId (item, "i"));
-                       
+
                        writer.RenderBeginTag (HtmlTextWriterTag.Td);
 
                        // Top separator image
@@ -1030,28 +1538,79 @@ namespace System.Web.UI.WebControls
                                writer.AddAttribute ("src", DynamicTopSeparatorImageUrl);
                                writer.RenderBeginTag (HtmlTextWriterTag.Img);
                                writer.RenderEndTag (); // IMG
-                       } else  if (!isDynamicItem && StaticTopSeparatorImageUrl != "") {
+                       }
+                       else if (!isDynamicItem && StaticTopSeparatorImageUrl != "") {
                                writer.AddAttribute ("src", StaticTopSeparatorImageUrl);
                                writer.RenderBeginTag (HtmlTextWriterTag.Img);
                                writer.RenderEndTag (); // IMG
                        }
-                       
+
                        // Menu item box
                        
+                       MenuItemStyle style = new MenuItemStyle ();
+                       if (Page.Header != null) {
+                               // styles are registered
+                               if (!isDynamicItem && staticMenuItemStyle != null) {
+                                       AddCssClass (style, staticMenuItemStyle.CssClass);
+                                       AddCssClass (style, staticMenuItemStyle.RegisteredCssClass);
+                               }
+                               if (isDynamicItem && dynamicMenuItemStyle != null) {
+                                       AddCssClass (style, dynamicMenuItemStyle.CssClass);
+                                       AddCssClass (style, dynamicMenuItemStyle.RegisteredCssClass);
+                               }
+                               if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
+                                       AddCssClass (style, levelMenuItemStyles [item.Depth].CssClass);
+                                       AddCssClass (style, levelMenuItemStyles [item.Depth].RegisteredCssClass);
+                               }
+                               if (item == SelectedItem) {
+                                       if (!isDynamicItem && staticSelectedStyle != null) {
+                                               AddCssClass (style, staticSelectedStyle.CssClass);
+                                               AddCssClass (style, staticSelectedStyle.RegisteredCssClass);
+                                       }
+                                       if (isDynamicItem && dynamicSelectedStyle != null) {
+                                               AddCssClass (style, dynamicSelectedStyle.CssClass);
+                                               AddCssClass (style, dynamicSelectedStyle.RegisteredCssClass);
+                                       }
+                                       if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
+                                               AddCssClass (style, levelSelectedStyles [item.Depth].CssClass);
+                                               AddCssClass (style, levelSelectedStyles [item.Depth].RegisteredCssClass);
+                                       }
+                               }
+                       }
+                       else {
+                               // styles are not registered
+                               if (!isDynamicItem && staticMenuItemStyle != null) {
+                                       style.CopyFrom (staticMenuItemStyle);
+                               }
+                               if (isDynamicItem && dynamicMenuItemStyle != null) {
+                                       style.CopyFrom (dynamicMenuItemStyle);
+                               }
+                               if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
+                                       style.CopyFrom (levelMenuItemStyles [item.Depth]);
+                               }
+                               if (item == SelectedItem) {
+                                       if (!isDynamicItem && staticSelectedStyle != null) {
+                                               style.CopyFrom (staticSelectedStyle);
+                                       }
+                                       if (isDynamicItem && dynamicSelectedStyle != null) {
+                                               style.CopyFrom (dynamicSelectedStyle);
+                                       }
+                                       if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
+                                               style.CopyFrom (levelSelectedStyles [item.Depth]);
+                                       }
+                               }
+                       }
+                       style.AddAttributesToRender (writer);
+
+                       writer.AddAttribute ("id", GetItemClientId (item, "i"));
+
                        writer.AddAttribute ("cellpadding", "0");
                        writer.AddAttribute ("cellspacing", "0");
+                       writer.AddAttribute ("border", "0");
                        writer.AddAttribute ("width", "100%");
                        writer.RenderBeginTag (HtmlTextWriterTag.Table);
                        writer.RenderBeginTag (HtmlTextWriterTag.Tr);
-                       
-                       if (item.Depth > 0 && !isDynamicItem) {
-                               writer.RenderBeginTag (HtmlTextWriterTag.Td);
-                               writer.AddStyleAttribute ("width", StaticSubMenuIndent.ToString ());
-                               writer.RenderBeginTag (HtmlTextWriterTag.Div);
-                               writer.RenderEndTag (); // DIV
-                               writer.RenderEndTag (); // TD
-                       }
-                       
+
                        if (item.ImageUrl != "") {
                                writer.RenderBeginTag (HtmlTextWriterTag.Td);
                                RenderItemHref (writer, item);
@@ -1063,28 +1622,95 @@ namespace System.Web.UI.WebControls
                                writer.RenderEndTag (); // A
                                writer.RenderEndTag (); // TD
                        }
-                       
+
                        // Menu item text
-                       
-                       writer.AddAttribute ("width", "100%");
+
+                       if (vertical)
+                               writer.AddStyleAttribute (HtmlTextWriterStyle.Width, "100%");
                        if (!ItemWrap)
-                               writer.AddAttribute ("nowrap", "nowrap");
+                               writer.AddStyleAttribute ("white-space", "nowrap");
                        writer.RenderBeginTag (HtmlTextWriterTag.Td);
-                       
+
                        RenderItemHref (writer, item);
-                       writer.AddStyleAttribute ("text-decoration", "none");
+                       
+                       Style linkStyle = new Style ();
+                       if (Page.Header != null) {
+                               // styles are registered
+                               AddCssClass (linkStyle, ControlLinkStyle.RegisteredCssClass);
+
+                               if (!isDynamicItem && staticMenuItemStyle != null) {
+                                       AddCssClass (linkStyle, staticMenuItemStyle.CssClass);
+                                       AddCssClass (linkStyle, staticMenuItemLinkStyle.RegisteredCssClass);
+                               }
+                               if (isDynamicItem && dynamicMenuItemStyle != null) {
+                                       AddCssClass (linkStyle, dynamicMenuItemStyle.CssClass);
+                                       AddCssClass (linkStyle, dynamicMenuItemLinkStyle.RegisteredCssClass);
+                               }
+                               if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
+                                       AddCssClass (linkStyle, levelMenuItemStyles [item.Depth].CssClass);
+                                       AddCssClass (linkStyle, levelMenuItemLinkStyles [item.Depth].RegisteredCssClass);
+                               }
+                               if (item == SelectedItem) {
+                                       if (!isDynamicItem && staticSelectedStyle != null) {
+                                               AddCssClass (linkStyle, staticSelectedStyle.CssClass);
+                                               AddCssClass (linkStyle, staticSelectedLinkStyle.RegisteredCssClass);
+                                       }
+                                       if (isDynamicItem && dynamicSelectedStyle != null) {
+                                               AddCssClass (linkStyle, dynamicSelectedStyle.CssClass);
+                                               AddCssClass (linkStyle, dynamicSelectedLinkStyle.RegisteredCssClass);
+                                       }
+                                       if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
+                                               AddCssClass (linkStyle, levelSelectedStyles [item.Depth].CssClass);
+                                               AddCssClass (linkStyle, levelSelectedLinkStyles [item.Depth].RegisteredCssClass);
+                                       }
+                               }
+                       }
+                       else {
+                               // styles are not registered
+                               linkStyle.CopyFrom (ControlLinkStyle);
+
+                               if (!isDynamicItem && staticMenuItemStyle != null) {
+                                       linkStyle.CopyFrom (staticMenuItemLinkStyle);
+                               }
+                               if (isDynamicItem && dynamicMenuItemStyle != null) {
+                                       linkStyle.CopyFrom (dynamicMenuItemLinkStyle);
+                               }
+                               if (levelMenuItemStyles != null && levelMenuItemStyles.Count > item.Depth) {
+                                       linkStyle.CopyFrom (levelMenuItemLinkStyles [item.Depth]);
+                               }
+                               if (item == SelectedItem) {
+                                       if (!isDynamicItem && staticSelectedStyle != null) {
+                                               linkStyle.CopyFrom (staticSelectedLinkStyle);
+                                       }
+                                       if (isDynamicItem && dynamicSelectedStyle != null) {
+                                               linkStyle.CopyFrom (dynamicSelectedLinkStyle);
+                                       }
+                                       if (levelSelectedStyles != null && levelSelectedStyles.Count > item.Depth) {
+                                               linkStyle.CopyFrom (levelSelectedLinkStyles [item.Depth]);
+                                       }
+                               }
+
+                               linkStyle.AlwaysRenderTextDecoration = true;
+                       }
+                       linkStyle.AddAttributesToRender (writer);
+
+                       writer.AddAttribute ("id", GetItemClientId (item, "l"));
+                       
+                       if (item.Depth > 0 && !isDynamicItem) {
+                               Unit indent = new Unit (StaticSubMenuIndent.Value * item.Depth, StaticSubMenuIndent.Type);
+                               writer.AddStyleAttribute ("margin-left", indent.ToString ());
+                       }
                        writer.RenderBeginTag (HtmlTextWriterTag.A);
                        RenderItemContent (writer, item, isDynamicItem);
                        writer.RenderEndTag (); // A
-                       
+
                        writer.RenderEndTag (); // TD
-                       
+
                        // Popup image
-                       
+
                        if (dynamicChildren) {
                                string popOutImage = GetPopOutImage (item, isDynamicItem);
-                               if (popOutImage != null)
-                               {
+                               if (popOutImage != null) {
                                        writer.RenderBeginTag (HtmlTextWriterTag.Td);
                                        writer.AddAttribute ("src", popOutImage);
                                        writer.AddAttribute ("border", "0");
@@ -1093,98 +1719,99 @@ namespace System.Web.UI.WebControls
                                        writer.RenderEndTag (); // TD
                                }
                        }
-                       
+
                        writer.RenderEndTag (); // TR
                        writer.RenderEndTag (); // TABLE
-                       
+
                        // Bottom separator image
-                               
+
                        string separatorImg = item.SeparatorImageUrl;
-                       if (separatorImg.Length == 0) { 
-                               if (isDynamicItem) separatorImg = DynamicBottomSeparatorImageUrl;
-                               else separatorImg = StaticBottomSeparatorImageUrl;
+                       if (separatorImg.Length == 0) {
+                               if (isDynamicItem)
+                                       separatorImg = DynamicBottomSeparatorImageUrl;
+                               else
+                                       separatorImg = StaticBottomSeparatorImageUrl;
                        }
                        if (separatorImg.Length > 0) {
                                writer.AddAttribute ("src", separatorImg);
                                writer.RenderBeginTag (HtmlTextWriterTag.Img);
                                writer.RenderEndTag (); // IMG
                        }
-                               
-                       // Submenu
-                               
-                       if (vertical) {
-                               if (displayChildren) {
-                                       if (dynamicChildren) dynamicMenus.Add (item);
-                                       else {
-                                               writer.AddAttribute ("width", "100%");
-                                               RenderMenu (writer, item.ChildItems, true, false);
-                                       }
-                               }
-                               
-                               writer.RenderEndTag (); // TD
+
+                       writer.RenderEndTag (); // TD
+                       if (vertical)
                                writer.RenderEndTag (); // TR
-                       } else {
-                               writer.RenderEndTag (); // TD
-                               
-                               writer.RenderBeginTag (HtmlTextWriterTag.Td);
-                               if (displayChildren) {
-                                       if (dynamicChildren) dynamicMenus.Add (item);
-                                       else RenderMenu (writer, item.ChildItems, false, false);
+
+                       if (itemSpacing != Unit.Empty)
+                               RenderMenuItemSpacing (writer, itemSpacing, vertical);
+                       else if (!vertical && (notLast || displayChildren)) {
+                               if (!displayChildren || !dynamicChildren) {
+                                       writer.AddStyleAttribute ("width", "3px");
+                                       writer.RenderBeginTag (HtmlTextWriterTag.Td);
+                                       writer.RenderEndTag ();
                                }
+                       }
+
+                       // Submenu
+
+                       if (displayChildren && !dynamicChildren) {
+                               if (vertical)
+                                       writer.RenderBeginTag (HtmlTextWriterTag.Tr);
+                               writer.RenderBeginTag (HtmlTextWriterTag.Td);
+                               writer.AddAttribute ("width", "100%");
+                               RenderMenu (writer, item.ChildItems, true, false, item.Depth + 1, notLast);
+                               if (item.Depth + 2 == StaticDisplayLevels)
+                                       RenderDynamicMenu (writer, item.ChildItems);
                                writer.RenderEndTag (); // TD
+                               if (vertical)
+                                       writer.RenderEndTag (); // TR
                        }
+
                }
-               
-               void RenderItemContent (HtmlTextWriter writer, MenuItem item, bool isDynamicItem)
-               {
-                       if (isDynamicItem && dynamicItemTemplate != null) {
-                               MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
-                               dynamicItemTemplate.InstantiateIn (cter);
-                               cter.Render (writer);
-                       } else if (!isDynamicItem && staticItemTemplate != null) {
-                               MenuItemTemplateContainer cter = new MenuItemTemplateContainer (item.Index, item);
-                               staticItemTemplate.InstantiateIn (cter);
-                               cter.Render (writer);
-                       else {
+
+               void RenderItemContent (HtmlTextWriter writer, MenuItem item, bool isDynamicItem) {
+                       if (_menuItemControls!=null && _menuItemControls [item] != null) {
+                               ((Control) _menuItemControls [item]).Render (writer);
+                       }
+                       else if (isDynamicItem && DynamicItemFormatString.Length > 0) {
+                               writer.Write (string.Format (DynamicItemFormatString, item.Text));
+                       }
+                       else if (!isDynamicItem && StaticItemFormatString.Length > 0) {
+                               writer.Write (string.Format (StaticItemFormatString, item.Text));
+                       }
+                       else {
                                writer.Write (item.Text);
                        }
                }
                        
-               int GetItemSpacing (MenuItem item, bool dynamic)
+               Unit GetItemSpacing (MenuItem item, bool dynamic)
                {
-                       int itemSpacing;
+                       Unit itemSpacing;
                        
                        if (item.Selected) {
                                if (levelSelectedStyles != null && item.Depth < levelSelectedStyles.Count) {
                                        itemSpacing = levelSelectedStyles [item.Depth].ItemSpacing;
-                                       if (itemSpacing != 0) return itemSpacing;
+                                       if (itemSpacing != Unit.Empty) return itemSpacing;
                                }
                                
                                if (dynamic) itemSpacing = DynamicSelectedStyle.ItemSpacing;
                                else itemSpacing = StaticSelectedStyle.ItemSpacing;
-                               if (itemSpacing != 0) return itemSpacing;
+                               if (itemSpacing != Unit.Empty) return itemSpacing;
                        }
                        
                        if (levelMenuItemStyles != null && item.Depth < levelMenuItemStyles.Count) {
                                itemSpacing = levelMenuItemStyles [item.Depth].ItemSpacing;
-                               if (itemSpacing != 0) return itemSpacing;
+                               if (itemSpacing != Unit.Empty) return itemSpacing;
                        }
-                       
-                       if (dynamic) return DynamicMenuItemStyle.ItemSpacing;
-                       else return StaticMenuItemStyle.ItemSpacing;
+
+                       if (dynamic && dynamicMenuItemStyle != null)
+                               return dynamicMenuItemStyle.ItemSpacing;
+                       else if (!dynamic && staticMenuItemStyle != null)
+                               return staticMenuItemStyle.ItemSpacing;
+                       else
+                               return Unit.Empty;
                }
                
-               
-               string GetItemSeparatorImage (MenuItem item, bool isDynamicItem)
-               {
-                       if (item.SeparatorImageUrl != "") return item.SeparatorImageUrl;
-                       if (isDynamicItem && DynamicTopSeparatorImageUrl != "")
-                               return DynamicTopSeparatorImageUrl;
-                       else  if (!isDynamicItem && StaticTopSeparatorImageUrl != "")
-                               return StaticTopSeparatorImageUrl;
-                       return null;
-               }
-                       
                string GetPopOutImage (MenuItem item, bool isDynamicItem)
                {
                        if (item.PopOutImageUrl != "")
@@ -1206,7 +1833,14 @@ namespace System.Web.UI.WebControls
                        
                void RenderItemHref (HtmlTextWriter writer, MenuItem item)
                {
-                       if (item.NavigateUrl != "") {
+                       if (!item.BranchEnabled) {
+                               writer.AddAttribute ("disabled", "true");
+                       }
+                       else if (!item.Selectable) {
+                               writer.AddAttribute ("href", "#");
+                               writer.AddStyleAttribute ("cursor", "text");
+                       }
+                       else if (item.NavigateUrl != "") {
                                writer.AddAttribute ("href", item.NavigateUrl);
                                if (item.Target != "")
                                        writer.AddAttribute ("target", item.Target);
@@ -1216,6 +1850,7 @@ namespace System.Web.UI.WebControls
                        else {
                                writer.AddAttribute ("href", GetClientEvent (item));
                        }
+
                }
                
                string GetItemClientId (MenuItem item, string sufix)
@@ -1225,7 +1860,7 @@ namespace System.Web.UI.WebControls
                                                        
                string GetClientEvent (MenuItem item)
                {
-                       return Page.GetPostBackClientHyperlink (this, item.Path);
+                       return Page.ClientScript.GetPostBackClientHyperlink (this, item.Path);
                }
        }
 }