New tests.
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / TreeView.cs
index 1a2951e5309c5ed4314af1532be342dc5fe5a75e..1716ee8709def23989c4045eda8fd6bcb8e18599 100644 (file)
 using System.Collections;
 using System.Text;
 using System.ComponentModel;
+using System.Globalization;
 using System.Web.Handlers;
 using System.Collections.Specialized;
 using System.IO;
 using System.Security.Permissions;
 using System.Collections.Generic;
+using System.Web.Util;
 
 namespace System.Web.UI.WebControls
 {
@@ -51,6 +53,7 @@ namespace System.Web.UI.WebControls
        [Designer ("System.Web.UI.Design.WebControls.TreeViewDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
        public class TreeView: HierarchicalDataBoundControl, IPostBackEventHandler, IPostBackDataHandler, ICallbackEventHandler
        {
+               string activeSiteMapPath;
                bool stylesPrepared;
                Style hoverNodeStyle;
                TreeNodeStyle leafNodeStyle;
@@ -76,18 +79,86 @@ namespace System.Web.UI.WebControls
                Style selectedNodeLinkStyle;
                Style hoverNodeLinkStyle;
                
-               private static readonly object TreeNodeCheckChangedEvent = new object();
-               private static readonly object SelectedNodeChangedEvent = new object();
-               private static readonly object TreeNodeCollapsedEvent = new object();
-               private static readonly object TreeNodeDataBoundEvent = new object();
-               private static readonly object TreeNodeExpandedEvent = new object();
-               private static readonly object TreeNodePopulateEvent = new object();
+               static readonly object TreeNodeCheckChangedEvent = new object();
+               static readonly object SelectedNodeChangedEvent = new object();
+               static readonly object TreeNodeCollapsedEvent = new object();
+               static readonly object TreeNodeDataBoundEvent = new object();
+               static readonly object TreeNodeExpandedEvent = new object();
+               static readonly object TreeNodePopulateEvent = new object();
                
                static Hashtable imageStyles = new Hashtable ();
+
+               class TreeViewExpandDepthConverter : TypeConverter
+               {
+                       public override bool CanConvertFrom (ITypeDescriptorContext context, Type sourceType)
+                       {
+                               if (sourceType == typeof (string) || sourceType == typeof (int))
+                                       return true;
+
+                               return base.CanConvertFrom (context, sourceType);
+                       }
+
+                       public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
+                       {
+                               if (destinationType == typeof (string) || destinationType == typeof (int))
+                                       return true;
+
+                               return base.CanConvertTo (context, destinationType);
+                       }
+
+                       public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+                       {
+                               if (destinationType != typeof (int) && destinationType != typeof (string))
+                                       return base.ConvertTo (context, culture, value, destinationType);
+                               
+                               if (value is string) {
+                                       if (destinationType == typeof (int)) {
+                                               if (String.Compare ("FullyExpand", (string)value, StringComparison.OrdinalIgnoreCase) == 0)
+                                                       return -1;
+                                               
+                                               try {
+                                                       return Int32.Parse ((string)value);
+                                               } catch (Exception) {
+                                                       return -1;
+                                               }
+                                       } else
+                                               return value;   
+                               }
+
+                               int val = (int)value;
+                               if (destinationType == typeof (string)) {
+                                       if (val == -1)
+                                               return "FullyExpand";
+                                       return val.ToString ();
+                               }
+                                       
+                               return value;
+                       }
+
+                       public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value)
+                       {
+                               if (!(value is string) && !(value is int))
+                                       return base.ConvertFrom (context, culture, value);
+
+                               if (value is string) {
+                                       if (String.Compare ("FullyExpand", (string)value, StringComparison.OrdinalIgnoreCase) == 0)
+                                               return -1;
+
+                                       try {
+                                               return Int32.Parse ((string)value);
+                                       } catch (Exception) {
+                                               return null;
+                                       }
+                               }
+
+                               return value;
+                       }
+               }
                
                class ImageStyle
                {
-                       public ImageStyle (string expand, string collapse, string noExpand, string icon, string iconLeaf, string iconRoot) {
+                       public ImageStyle (string expand, string collapse, string noExpand, string icon, string iconLeaf, string iconRoot)
+                       {
                                Expand = expand;
                                Collapse = collapse;
                                NoExpand = noExpand;
@@ -122,7 +193,7 @@ namespace System.Web.UI.WebControls
                        imageStyles [TreeViewImageSet.News] = new ImageStyle ("TreeView_plus", "TreeView_minus", "TreeView_noexpand", null, null, null);
                        imageStyles [TreeViewImageSet.Faq] = new ImageStyle ("TreeView_plus", "TreeView_minus", "TreeView_noexpand", null, null, null);
                        imageStyles [TreeViewImageSet.WindowsHelp] = new ImageStyle ("TreeView_plus", "TreeView_minus", "TreeView_noexpand", null, null, null);
-                       imageStyles [TreeViewImageSet.XPFileExplorer] = new ImageStyle ("TreeView_plus", "TreeView_minus", "TreeView_noexpand", null, null, null);
+                       imageStyles [TreeViewImageSet.XPFileExplorer] = new ImageStyle ("TreeView_plus", "TreeView_minus", "TreeView_noexpand", "folder", "file", "computer");
                }
                
                public event TreeNodeEventHandler TreeNodeCheckChanged {
@@ -159,7 +230,8 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                TreeNodeEventHandler eh = (TreeNodeEventHandler) Events [TreeNodeCheckChangedEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null)
+                                       eh (this, e);
                        }
                }
 
@@ -167,7 +239,8 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                EventHandler eh = (EventHandler) Events [SelectedNodeChangedEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null)
+                                       eh (this, e);
                        }
                }
 
@@ -175,7 +248,8 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                TreeNodeEventHandler eh = (TreeNodeEventHandler) Events [TreeNodeCollapsedEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null)
+                                       eh (this, e);
                        }
                }
 
@@ -183,7 +257,8 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                TreeNodeEventHandler eh = (TreeNodeEventHandler) Events [TreeNodeDataBoundEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null)
+                                       eh (this, e);
                        }
                }
 
@@ -191,7 +266,8 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                TreeNodeEventHandler eh = (TreeNodeEventHandler) Events [TreeNodeExpandedEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null)
+                                       eh (this, e);
                        }
                }
 
@@ -199,19 +275,16 @@ namespace System.Web.UI.WebControls
                {
                        if (Events != null) {
                                TreeNodeEventHandler eh = (TreeNodeEventHandler) Events [TreeNodePopulateEvent];
-                               if (eh != null) eh (this, e);
+                               if (eh != null)
+                                       eh (this, e);
                        }
                }
 
 
                [Localizable (true)]
                public string CollapseImageToolTip {
-                       get {
-                               return ViewState.GetString ("CollapseImageToolTip", "Collapse {0}");
-                       }
-                       set {
-                               ViewState["CollapseImageToolTip"] = value;
-                       }
+                       get { return ViewState.GetString ("CollapseImageToolTip", "Collapse {0}"); }
+                       set { ViewState["CollapseImageToolTip"] = value; }
                }
 
                [MonoTODO ("Implement support for this")]
@@ -219,12 +292,8 @@ namespace System.Web.UI.WebControls
                [WebSysDescription ("Whether the tree will automatically generate bindings.")]
                [DefaultValue (true)]
                public bool AutoGenerateDataBindings {
-                       get {
-                               return ViewState.GetBool ("AutoGenerateDataBindings", true);
-                       }
-                       set {
-                               ViewState["AutoGenerateDataBindings"] = value;
-                       }
+                       get { return ViewState.GetBool ("AutoGenerateDataBindings", true); }
+                       set { ViewState["AutoGenerateDataBindings"] = value; }
                }
 
                [DefaultValue ("")]
@@ -233,12 +302,8 @@ namespace System.Web.UI.WebControls
                [WebCategory ("Appearance")]
                [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
                public string CollapseImageUrl {
-                       get {
-                               return ViewState.GetString ("CollapseImageUrl", "");
-                       }
-                       set {
-                               ViewState["CollapseImageUrl"] = value;
-                       }
+                       get { return ViewState.GetString ("CollapseImageUrl", String.Empty); }
+                       set { ViewState["CollapseImageUrl"] = value; }
                }
 
                [WebCategory ("Data")]
@@ -263,12 +328,8 @@ namespace System.Web.UI.WebControls
                [Themeable (false)]
                [DefaultValue (true)]
                public bool EnableClientScript {
-                       get {
-                               return ViewState.GetBool ("EnableClientScript", true);
-                       }
-                       set {
-                               ViewState["EnableClientScript"] = value;
-                       }
+                       get { return ViewState.GetBool ("EnableClientScript", true); }
+                       set { ViewState["EnableClientScript"] = value; }
                }
 
                [DefaultValue (-1)]
@@ -276,22 +337,14 @@ namespace System.Web.UI.WebControls
                [WebSysDescription ("The initial expand depth.")]
                [TypeConverter ("System.Web.UI.WebControls.TreeView+TreeViewExpandDepthConverter, " + Consts.AssemblySystem_Web)]
                public int ExpandDepth {
-                       get {
-                               return ViewState.GetInt ("ExpandDepth", -1);
-                       }
-                       set {
-                               ViewState["ExpandDepth"] = value;
-                       }
+                       get { return ViewState.GetInt ("ExpandDepth", -1); }
+                       set { ViewState["ExpandDepth"] = value; }
                }
 
                [Localizable (true)]
                public string ExpandImageToolTip {
-                       get {
-                               return ViewState.GetString ("ExpandImageToolTip", "Expand {0}");
-                       }
-                       set {
-                               ViewState["ExpandImageToolTip"] = value;
-                       }
+                       get { return ViewState.GetString ("ExpandImageToolTip", "Expand {0}"); }
+                       set { ViewState["ExpandImageToolTip"] = value; }
                }
 
                [DefaultValue ("")]
@@ -300,12 +353,8 @@ namespace System.Web.UI.WebControls
                [WebCategory ("Appearance")]
                [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
                public string ExpandImageUrl {
-                       get {
-                               return ViewState.GetString ("ExpandImageUrl", "");
-                       }
-                       set {
-                               ViewState["ExpandImageUrl"] = value;
-                       }
+                       get { return ViewState.GetString ("ExpandImageUrl", String.Empty); }
+                       set { ViewState["ExpandImageUrl"] = value; }
                }
 
                [PersistenceMode (PersistenceMode.InnerProperty)]
@@ -326,9 +375,7 @@ namespace System.Web.UI.WebControls
 
                [DefaultValue (TreeViewImageSet.Custom)]
                public TreeViewImageSet ImageSet {
-                       get {
-                               return (TreeViewImageSet)ViewState.GetInt ("ImageSet", (int)TreeViewImageSet.Custom);
-                       }
+                       get { return (TreeViewImageSet)ViewState.GetInt ("ImageSet", (int)TreeViewImageSet.Custom); }
                        set {
                                if (!Enum.IsDefined (typeof (TreeViewImageSet), value))
                                        throw new ArgumentOutOfRangeException ();
@@ -369,32 +416,20 @@ namespace System.Web.UI.WebControls
 
                [DefaultValue ("")]
                public string LineImagesFolder {
-                       get {
-                               return ViewState.GetString ("LineImagesFolder", "");
-                       }
-                       set {
-                               ViewState["LineImagesFolder"] = value;
-                       }
+                       get { return ViewState.GetString ("LineImagesFolder", String.Empty); }
+                       set { ViewState["LineImagesFolder"] = value; }
                }
 
                [DefaultValue (-1)]
                public int MaxDataBindDepth {
-                       get {
-                               return ViewState.GetInt ("MaxDataBindDepth", -1);
-                       }
-                       set {
-                               ViewState["MaxDataBindDepth"] = value;
-                       }
+                       get { return ViewState.GetInt ("MaxDataBindDepth", -1); }
+                       set { ViewState["MaxDataBindDepth"] = value; }
                }
 
                [DefaultValue (20)]
                public int NodeIndent {
-                       get {
-                               return ViewState.GetInt ("NodeIndent", 20);
-                       }
-                       set {
-                               ViewState["NodeIndent"] = value;
-                       }
+                       get { return ViewState.GetInt ("NodeIndent", 20); }
+                       set { ViewState["NodeIndent"] = value; }
                }
                
                [PersistenceMode (PersistenceMode.InnerProperty)]
@@ -430,12 +465,8 @@ namespace System.Web.UI.WebControls
                
                [DefaultValue (false)]
                public bool NodeWrap {
-                       get {
-                               return ViewState.GetBool ("NodeWrap", false);
-                       }
-                       set {
-                               ViewState ["NodeWrap"] = value;
-                       }
+                       get { return ViewState.GetBool ("NodeWrap", false); }
+                       set { ViewState ["NodeWrap"] = value; }
                }
 
                [UrlProperty]
@@ -444,12 +475,8 @@ namespace System.Web.UI.WebControls
                [WebCategory ("Appearance")]
                [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
                public string NoExpandImageUrl {
-                       get {
-                               return ViewState.GetString ("NoExpandImageUrl", "");
-                       }
-                       set {
-                               ViewState ["NoExpandImageUrl"] = value;
-                       }
+                       get { return ViewState.GetString ("NoExpandImageUrl", String.Empty); }
+                       set { ViewState ["NoExpandImageUrl"] = value; }
                }
 
                [PersistenceMode (PersistenceMode.InnerProperty)]
@@ -470,22 +497,14 @@ namespace System.Web.UI.WebControls
                
                [DefaultValue ('/')]
                public char PathSeparator {
-                       get {
-                               return ViewState.GetChar ("PathSeparator", '/');
-                       }
-                       set {
-                               ViewState ["PathSeparator"] = value;
-                       }
+                       get { return ViewState.GetChar ("PathSeparator", '/'); }
+                       set { ViewState ["PathSeparator"] = value; }
                }
 
                [DefaultValue (true)]
                public bool PopulateNodesFromClient {
-                       get {
-                               return ViewState.GetBool ("PopulateNodesFromClient", true);
-                       }
-                       set {
-                               ViewState ["PopulateNodesFromClient"] = value;
-                       }
+                       get { return ViewState.GetBool ("PopulateNodesFromClient", true); }
+                       set { ViewState ["PopulateNodesFromClient"] = value; }
                }
 
                [PersistenceMode (PersistenceMode.InnerProperty)]
@@ -520,7 +539,7 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-               private Style ControlLinkStyle {
+               Style ControlLinkStyle {
                        get {
                                if (controlLinkStyle == null) {
                                        controlLinkStyle = new Style ();
@@ -530,7 +549,7 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-               private Style NodeLinkStyle {
+               Style NodeLinkStyle {
                        get {
                                if (nodeLinkStyle == null) {
                                        nodeLinkStyle = new Style ();
@@ -539,56 +558,49 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-               private Style RootNodeLinkStyle {
+               Style RootNodeLinkStyle {
                        get {
-                               if (rootNodeLinkStyle == null) {
+                               if (rootNodeLinkStyle == null)
                                        rootNodeLinkStyle = new Style ();
-                               }
                                return rootNodeLinkStyle;
                        }
                }
 
-               private Style ParentNodeLinkStyle {
+               Style ParentNodeLinkStyle {
                        get {
-                               if (parentNodeLinkStyle == null) {
+                               if (parentNodeLinkStyle == null)
                                        parentNodeLinkStyle = new Style ();
-                               }
                                return parentNodeLinkStyle;
                        }
                }
 
-               private Style SelectedNodeLinkStyle {
+               Style SelectedNodeLinkStyle {
                        get {
-                               if (selectedNodeLinkStyle == null) {
+                               if (selectedNodeLinkStyle == null)
                                        selectedNodeLinkStyle = new Style ();
-                               }
                                return selectedNodeLinkStyle;
                        }
                }
 
-               private Style LeafNodeLinkStyle {
+               Style LeafNodeLinkStyle {
                        get {
-                               if (leafNodeLinkStyle == null) {
+                               if (leafNodeLinkStyle == null)
                                        leafNodeLinkStyle = new Style ();
-                               }
                                return leafNodeLinkStyle;
                        }
                }
 
-               private Style HoverNodeLinkStyle {
+               Style HoverNodeLinkStyle {
                        get {
-                               if (hoverNodeLinkStyle == null) {
+                               if (hoverNodeLinkStyle == null)
                                        hoverNodeLinkStyle = new Style ();
-                               }
                                return hoverNodeLinkStyle;
                        }
                }
                
                [DefaultValue (TreeNodeTypes.None)]
                public TreeNodeTypes ShowCheckBoxes {
-                       get {
-                               return (TreeNodeTypes)ViewState.GetInt ("ShowCheckBoxes", (int)TreeNodeTypes.None);
-                       }
+                       get { return (TreeNodeTypes)ViewState.GetInt ("ShowCheckBoxes", (int)TreeNodeTypes.None); }
                        set {
                                if ((int) value > 7)
                                        throw new ArgumentOutOfRangeException ();
@@ -598,33 +610,21 @@ namespace System.Web.UI.WebControls
 
                [DefaultValue (true)]
                public bool ShowExpandCollapse {
-                       get {
-                               return ViewState.GetBool ("ShowExpandCollapse", true);
-                       }
-                       set {
-                               ViewState ["ShowExpandCollapse"] = value;
-                       }
+                       get { return ViewState.GetBool ("ShowExpandCollapse", true); }
+                       set { ViewState ["ShowExpandCollapse"] = value; }
                }
 
                [DefaultValue (false)]
                public bool ShowLines {
-                       get {
-                               return ViewState.GetBool ("ShowLines", false);
-                       }
-                       set {
-                               ViewState ["ShowLines"] = value;
-                       }
+                       get { return ViewState.GetBool ("ShowLines", false); }
+                       set { ViewState ["ShowLines"] = value; }
                }
 
                [Localizable (true)]
                public string SkipLinkText
                {
-                       get {
-                               return ViewState.GetString ("SkipLinkText", "Skip Navigation Links.");
-                       }
-                       set {
-                               ViewState ["SkipLinkText"] = value;
-                       }
+                       get { return ViewState.GetString ("SkipLinkText", "Skip Navigation Links."); }
+                       set { ViewState ["SkipLinkText"] = value; }
                }
                
                
@@ -638,28 +638,20 @@ namespace System.Web.UI.WebControls
                [DefaultValue ("")]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public string SelectedValue {
-                       get { return selectedNode != null ? selectedNode.Value : ""; }
+                       get { return selectedNode != null ? selectedNode.Value : String.Empty; }
                }
 
                [DefaultValue ("")]
                public string Target {
-                       get {
-                               return ViewState.GetString ("Target", "");
-                       }
-                       set {
-                               ViewState ["Target"] = value;
-                       }
+                       get { return ViewState.GetString ("Target", String.Empty); }
+                       set { ViewState ["Target"] = value; }
                }
 
                [MonoTODO ("why override?")]
                public override bool Visible 
                {
-                       get {
-                               return base.Visible;
-                       }
-                       set {
-                               base.Visible = value;
-                       }
+                       get { return base.Visible; }
+                       set { base.Visible = value; }
                }
                                
                [Browsable (false)]
@@ -675,7 +667,8 @@ namespace System.Web.UI.WebControls
                void FindCheckedNodes (TreeNodeCollection nodeList, TreeNodeCollection result)
                {
                        foreach (TreeNode node in nodeList) {
-                               if (node.Checked) result.Add (node, false);
+                               if (node.Checked)
+                                       result.Add (node, false);
                                FindCheckedNodes (node.ChildNodes, result);
                        }
                }
@@ -694,7 +687,8 @@ namespace System.Web.UI.WebControls
                
                public TreeNode FindNode (string valuePath)
                {
-                       if (valuePath == null) throw new ArgumentNullException ("valuePath");
+                       if (valuePath == null)
+                               throw new ArgumentNullException ("valuePath");
                        string[] path = valuePath.Split (PathSeparator);
                        int n = 0;
                        TreeNodeCollection col = Nodes;
@@ -703,7 +697,8 @@ namespace System.Web.UI.WebControls
                                foundBranch = false;
                                foreach (TreeNode node in col) {
                                        if (node.Value == path [n]) {
-                                               if (++n == path.Length) return node;
+                                               if (++n == path.Length)
+                                                       return node;
                                                col = node.ChildNodes;
                                                foundBranch = true;
                                                break;
@@ -757,7 +752,8 @@ namespace System.Web.UI.WebControls
                
                internal void SetSelectedNode (TreeNode node, bool loading)
                {
-                       if (selectedNode == node) return;
+                       if (selectedNode == node)
+                               return;
                        if (selectedNode != null)
                                selectedNode.SelectedFlag = false;
                        selectedNode = node;
@@ -788,33 +784,24 @@ namespace System.Web.UI.WebControls
                        EnsureDataBound ();
                        
                        base.TrackViewState();
-                       if (hoverNodeStyle != null) {
+                       if (hoverNodeStyle != null)
                                hoverNodeStyle.TrackViewState();
-                       }
-                       if (leafNodeStyle != null) {
+                       if (leafNodeStyle != null)
                                leafNodeStyle.TrackViewState();
-                       }
-                       if (levelStyles != null && levelStyles.Count > 0) {
+                       if (levelStyles != null && levelStyles.Count > 0)
                                ((IStateManager)levelStyles).TrackViewState();
-                       }
-                       if (nodeStyle != null) {
+                       if (nodeStyle != null)
                                nodeStyle.TrackViewState();
-                       }
-                       if (parentNodeStyle != null) {
+                       if (parentNodeStyle != null)
                                parentNodeStyle.TrackViewState();
-                       }
-                       if (rootNodeStyle != null) {
+                       if (rootNodeStyle != null)
                                rootNodeStyle.TrackViewState();
-                       }
-                       if (selectedNodeStyle != null) {
+                       if (selectedNodeStyle != null)
                                selectedNodeStyle.TrackViewState();
-                       }
-                       if (dataBindings != null) {
+                       if (dataBindings != null)
                                ((IStateManager)dataBindings).TrackViewState ();
-                       }
-                       if (nodes != null) {
+                       if (nodes != null)
                                ((IStateManager)nodes).TrackViewState();;
-                       }
                }
 
                protected override object SaveViewState()
@@ -869,9 +856,11 @@ namespace System.Web.UI.WebControls
 
                protected virtual void RaisePostBackEvent (string eventArgument)
                {
+                       ValidateEvent (UniqueID, eventArgument);
                        string[] args = eventArgument.Split ('|');
                        TreeNode node = FindNodeByPos (args[1]);
-                       if (node == null) return;
+                       if (node == null)
+                               return;
                        
                        if (args [0] == "sel")
                                HandleSelectEvent (node);
@@ -903,14 +892,41 @@ namespace System.Web.UI.WebControls
                protected virtual void RaisePostDataChangedEvent ()
                {
                }
+
+               TreeNode MakeNodeTree (string[] args)
+               {
+                       string[] segments = args [0].Split ('_');
+                       TreeNode ret = null, node;
+
+                       foreach (string seg in segments) {
+                               int idx = Int32.Parse (seg);
+                               node = new TreeNode (seg);
+                               if (ret != null) {
+                                       ret.ChildNodes.Add (node);
+                                       node.Index = idx;
+                               }
+                               ret = node;
+                       }
+
+                       ret.Value = args [1].Replace ("U+007C", "|");
+                       ret.ImageUrl = args [2].Replace ("U+007C", "|");
+                       ret.NavigateUrl = args [3].Replace ("U+007C", "|");
+                       ret.Target = args [4].Replace ("U+007C", "|");
+                       ret.Tree = this;
+                       
+                       NotifyPopulateRequired (ret);
+                       
+                       return ret;
+               }
                
                string callbackResult;
                protected virtual void RaiseCallbackEvent (string eventArgs)
                {
+                       string[] args = eventArgs.Split ('|');
                        RequiresDataBinding = true;
                        EnsureDataBound ();
                        
-                       TreeNode node = FindNodeByPos (eventArgs);
+                       TreeNode node = MakeNodeTree (args);
                        ArrayList levelLines = new ArrayList ();
                        TreeNode nd = node;
                        while (nd != null) {
@@ -922,14 +938,14 @@ namespace System.Web.UI.WebControls
                        StringWriter sw = new StringWriter ();
                        HtmlTextWriter writer = new HtmlTextWriter (sw);
                        EnsureStylesPrepared ();
-                       
+
                        node.Expanded = true;
                        int num = node.ChildNodes.Count;
                        for (int n=0; n<num; n++)
                                RenderNode (writer, node.ChildNodes [n], node.Depth + 1, levelLines, true, n<num-1);
                        
                        string res = sw.ToString ();
-                       callbackResult = res != "" ? res : "*";
+                       callbackResult = res.Length > 0 ? res : "*";
                }
                
                protected virtual string GetCallbackResult ()
@@ -971,7 +987,7 @@ namespace System.Web.UI.WebControls
                {
                        base.PerformDataBinding ();
                        InitializeDataBindings ();
-                       HierarchicalDataSourceView data = GetData ("");
+                       HierarchicalDataSourceView data = GetData (String.Empty);
                        if (data == null)
                                return;
                        Nodes.Clear ();
@@ -979,10 +995,11 @@ namespace System.Web.UI.WebControls
                        FillBoundChildrenRecursive (e, Nodes);
                }
                
-               private void FillBoundChildrenRecursive (IHierarchicalEnumerable hEnumerable, TreeNodeCollection nodeCollection)
+               void FillBoundChildrenRecursive (IHierarchicalEnumerable hEnumerable, TreeNodeCollection nodeCollection)
                {
                        if (hEnumerable == null)
-                               return;
+                               return;                 
+                       
                        foreach (object obj in hEnumerable) {
                                IHierarchyData hdata = hEnumerable.GetHierarchyData (obj);
                                TreeNode child = new TreeNode ();
@@ -1013,7 +1030,7 @@ namespace System.Web.UI.WebControls
                                                        continue;
                                                TreeNode node = FindNodeByPos (id);
                                                if (node != null && node.PopulateOnDemand && !node.Populated)
-                                                       node.Populate();
+                                                       node.Populated = true;
                                        }
                                }
                                res = true;
@@ -1028,16 +1045,42 @@ namespace System.Web.UI.WebControls
                                        string[] ids = states.Split ('|');
                                        UnsetExpandStates (Nodes, ids);
                                        SetExpandStates (ids);
-                               }
-                               else
+                               } else
                                        UnsetExpandStates (Nodes, new string[0]);
                                res = true;
                        }
                        return res;
                }
 
-               const string onPreRenderScript_1 = @"var {0} = new Object ();\n{0}.treeId = {1};\n{0}.uid = {2};\n{0}.showImage = {3};\n";
-               const string onPreRenderScript_2 = @"{0}.form = {1};\n{0}.PopulateNode = function(nodeId) {{ {2}; }};\n{0}.populateFromClient = {3};\n{0}.expandAlt = {4};\n{0}.collapseAlt = {5};\n";
+               const string _OnPreRender_Script_Preamble =
+                       "var {0} = new Object ();\n" +
+                       "{0}.treeId = {1};\n" +
+                       "{0}.uid = {2};\n" +
+                       "{0}.showImage = {3};\n";
+
+               const string _OnPreRender_Script_ShowExpandCollapse =
+                       "{0}.expandImage = {1};\n" +
+                       "{0}.collapseImage = {2};\n";
+
+               const string _OnPreRender_Script_ShowExpandCollapse_Populate =
+                       "{0}.noExpandImage = {1};\n";
+
+               const string _OnPreRender_Script_PopulateCallback =
+                       "{0}.form = {1};\n" +
+                       "{0}.PopulateNode = function (nodeId, nodeValue, nodeImageUrl, nodeNavigateUrl, nodeTarget) {{\n" +
+                       "\t{2}.__theFormPostData = \"\";\n" +
+                       "\t{2}.__theFormPostCollection = new Array ();\n" +
+                       "\t{2}.WebForm_InitCallback ();\n" +
+                       "\tTreeView_PopulateNode (this.uid, this.treeId, nodeId, nodeValue, nodeImageUrl, nodeNavigateUrl, nodeTarget)\n}};\n";
+
+               const string _OnPreRender_Script_CallbackOptions =
+                       "{0}.populateFromClient = {1};\n" +
+                       "{0}.expandAlt = {2};\n" +
+                       "{0}.collapseAlt = {3};\n";
+
+               const string _OnPreRender_Script_HoverStyle =
+                       "{0}.hoverClass = {1};\n" +
+                       "{0}.hoverLinkClass = {2};\n";
                
                protected internal override void OnPreRender (EventArgs e)
                {
@@ -1054,47 +1097,45 @@ namespace System.Web.UI.WebControls
                        }
                        
                        string ctree = ClientID + "_data";
-                       string script = String.Format (onPreRenderScript_1,
-                                                      ctree,
-                                                      ClientScriptManager.GetScriptLiteral (ClientID),
-                                                      ClientScriptManager.GetScriptLiteral (UniqueID),
-                                                      ClientScriptManager.GetScriptLiteral (ShowExpandCollapse));                      
+                       StringBuilder script = new StringBuilder ();
+                       script.AppendFormat (_OnPreRender_Script_Preamble,
+                                            ctree,
+                                            ClientScriptManager.GetScriptLiteral (ClientID),
+                                            ClientScriptManager.GetScriptLiteral (UniqueID),
+                                            ClientScriptManager.GetScriptLiteral (ShowExpandCollapse));                        
                        
                        if (ShowExpandCollapse) {
-                               bool defaultImages = ShowLines || ImageSet != TreeViewImageSet.Custom || (ExpandImageUrl == "" && CollapseImageUrl == "");
-                               script += String.Concat (ctree, ".defaultImages = ", ClientScriptManager.GetScriptLiteral (defaultImages), ";\n");
                                ImageStyle imageStyle = GetImageStyle ();
-                               if (!defaultImages) {
-                                       script += String.Concat (ctree,
-                                                                ".expandImage = ",
-                                                                ClientScriptManager.GetScriptLiteral (GetNodeImageUrl ("plus", imageStyle)),
-                                                                ";\n");
-                                       script += String.Concat (ctree,
-                                                                ".collapseImage = ",
-                                                                ClientScriptManager.GetScriptLiteral (GetNodeImageUrl ("minus", imageStyle)),
-                                                                ";\n");
-                               }
+                               script.AppendFormat (_OnPreRender_Script_ShowExpandCollapse,
+                                                    ctree,
+                                                    ClientScriptManager.GetScriptLiteral (GetNodeImageUrl ("plus", imageStyle)),
+                                                    ClientScriptManager.GetScriptLiteral (GetNodeImageUrl ("minus", imageStyle)));
+                                                    
                                if (PopulateNodesFromClient)
-                                       script += String.Concat (ctree,
-                                                                ".noExpandImage = ",
-                                                                ClientScriptManager.GetScriptLiteral (GetNodeImageUrl ("noexpand", imageStyle)),
-                                                                ";\n");
+                                       script.AppendFormat (_OnPreRender_Script_ShowExpandCollapse_Populate,
+                                                            ctree,
+                                                            ClientScriptManager.GetScriptLiteral (GetNodeImageUrl ("noexpand", imageStyle)));
                        }
 
                        if (Page != null) {
-                               script += String.Format (onPreRenderScript_2,
-                                                        ctree,
-                                                        Page.theForm,
-                                                        Page.ClientScript.GetCallbackEventReference ("this.uid", "nodeId", "TreeView_PopulateCallback",
-                                                                                                     "this.treeId + \" \" + nodeId",
-                                                                                                     "TreeView_PopulateCallback", false),
-                                                        ClientScriptManager.GetScriptLiteral (PopulateNodesFromClient),
-                                                        ClientScriptManager.GetScriptLiteral (GetNodeImageToolTip (true, null)),
-                                                        ClientScriptManager.GetScriptLiteral (GetNodeImageToolTip (false, null)));
-
-                               if (!Page.IsPostBack) {
+                               script.AppendFormat (_OnPreRender_Script_PopulateCallback,
+                                                    ctree,
+                                                    Page.theForm,
+                                                    Page.WebFormScriptReference);
+                               
+                                                    // Page.ClientScript.GetCallbackEventReference (
+                                                    //              "this.uid", "nodeId",
+                                                    //              "TreeView_PopulateCallback",
+                                                    //              "this.treeId + \" \" + nodeId", "TreeView_PopulateCallback", false));
+                               
+                               script.AppendFormat (_OnPreRender_Script_CallbackOptions,
+                                                    ctree,
+                                                    ClientScriptManager.GetScriptLiteral (PopulateNodesFromClient),
+                                                    ClientScriptManager.GetScriptLiteral (GetNodeImageToolTip (true, null)),
+                                                    ClientScriptManager.GetScriptLiteral (GetNodeImageToolTip (false, null)));
+                               
+                               if (!Page.IsPostBack)
                                        SetNodesExpandedToDepthRecursive (Nodes);
-                               }
 
                                if (EnableClientScript) {
                                        Page.ClientScript.RegisterHiddenField (ClientID + "_ExpandStates", GetExpandStates ());
@@ -1103,9 +1144,8 @@ namespace System.Web.UI.WebControls
                                        Page.ClientScript.RegisterWebFormClientScript ();
                                }
 
-                               if (EnableClientScript && PopulateNodesFromClient) {
+                               if (EnableClientScript && PopulateNodesFromClient)
                                        Page.ClientScript.RegisterHiddenField (ClientID + "_PopulatedStates", "|");
-                               }
 
                                EnsureStylesPrepared ();
 
@@ -1113,26 +1153,27 @@ namespace System.Web.UI.WebControls
                                        if (Page.Header == null)
                                                throw new InvalidOperationException ("Using TreeView.HoverNodeStyle requires Page.Header to be non-null (e.g. <head runat=\"server\" />).");
                                        RegisterStyle (HoverNodeStyle, HoverNodeLinkStyle);
-                                       script += String.Concat (ctree, ".hoverClass = ",
-                                                                ClientScriptManager.GetScriptLiteral (HoverNodeStyle.RegisteredCssClass),
-                                                                ";\n");
-                                       script += String.Concat (ctree, ".hoverLinkClass = ",
-                                                                ClientScriptManager.GetScriptLiteral (HoverNodeLinkStyle.RegisteredCssClass),
-                                                                ";\n");
+                                       script.AppendFormat (_OnPreRender_Script_HoverStyle,
+                                                            ctree,
+                                                            ClientScriptManager.GetScriptLiteral (HoverNodeStyle.RegisteredCssClass),
+                                                            ClientScriptManager.GetScriptLiteral (HoverNodeLinkStyle.RegisteredCssClass));                                     
                                }
                                
-                               Page.ClientScript.RegisterStartupScript (typeof(TreeView), this.UniqueID, script, true);
+                               Page.ClientScript.RegisterStartupScript (typeof(TreeView), this.UniqueID, script.ToString (), true);
+                               script = null;
                        }
                }
 
-               void EnsureStylesPrepared () {
+               void EnsureStylesPrepared ()
+               {
                        if (stylesPrepared)
                                return;
                        stylesPrepared = true;
                        PrepareStyles ();
                }
 
-               private void PrepareStyles () {
+               void PrepareStyles ()
+               {
                        // The order in which styles are defined matters when more than one class
                        // is assigned to an element
                        ControlLinkStyle.CopyTextStylesFrom (ControlStyle);
@@ -1164,7 +1205,8 @@ namespace System.Web.UI.WebControls
                                RegisterStyle (SelectedNodeStyle, SelectedNodeLinkStyle);
                }
 
-               void SetNodesExpandedToDepthRecursive (TreeNodeCollection nodes) {
+               void SetNodesExpandedToDepthRecursive (TreeNodeCollection nodes)
+               {
                        foreach (TreeNode node in nodes) {
                                if (!node.Expanded.HasValue) {
                                        if (ExpandDepth < 0 || node.Depth < ExpandDepth)
@@ -1174,20 +1216,24 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-               string IncrementStyleClassName () {
+               string IncrementStyleClassName ()
+               {
                        registeredStylesCounter++;
                        return ClientID + "_" + registeredStylesCounter;
                }
 
-               void RegisterStyle (Style baseStyle, Style linkStyle) {
+               void RegisterStyle (Style baseStyle, Style linkStyle)
+               {
                        linkStyle.CopyTextStylesFrom (baseStyle);
                        linkStyle.BorderStyle = BorderStyle.None;
+                       linkStyle.AddCssClass (baseStyle.CssClass);
                        baseStyle.Font.Reset ();
                        RegisterStyle (linkStyle);
                        RegisterStyle (baseStyle);
                }
 
-               void RegisterStyle (Style baseStyle) {
+               void RegisterStyle (Style baseStyle)
+               {
                        if (Page.Header == null)
                                return;
                        string className = IncrementStyleClassName ().Trim ('_');
@@ -1200,15 +1246,16 @@ namespace System.Web.UI.WebControls
                        return dataMember + " " + depth;
                }
                
-               void InitializeDataBindings () {
+               void InitializeDataBindings ()
+               {
                        if (dataBindings != null && dataBindings.Count > 0) {
                                bindings = new Hashtable ();
                                foreach (TreeNodeBinding bin in dataBindings) {
                                        string key = GetBindingKey (bin.DataMember, bin.Depth);
-                                       bindings [key] = bin;
+                                       if (!bindings.ContainsKey(key))
+                                               bindings [key] = bin;
                                }
-                       }
-                       else
+                       } else
                                bindings = null;
                }
                
@@ -1218,15 +1265,18 @@ namespace System.Web.UI.WebControls
                                return null;
                                
                        TreeNodeBinding bin = (TreeNodeBinding) bindings [GetBindingKey (type, depth)];
-                       if (bin != null) return bin;
+                       if (bin != null)
+                               return bin;
                        
                        bin = (TreeNodeBinding) bindings [GetBindingKey (type, -1)];
-                       if (bin != null) return bin;
+                       if (bin != null)
+                               return bin;
                        
-                       bin = (TreeNodeBinding) bindings [GetBindingKey ("", depth)];
-                       if (bin != null) return bin;
+                       bin = (TreeNodeBinding) bindings [GetBindingKey (String.Empty, depth)];
+                       if (bin != null)
+                               return bin;
                        
-                       return (TreeNodeBinding) bindings [GetBindingKey ("", -1)];
+                       return (TreeNodeBinding) bindings [GetBindingKey (String.Empty, -1)];
                }
                
                internal void DecorateNode(TreeNode node)
@@ -1251,6 +1301,15 @@ namespace System.Web.UI.WebControls
                
                protected internal override void RenderContents (HtmlTextWriter writer)
                {
+                       SiteMapDataSource siteMap = GetDataSource () as SiteMapDataSource;
+                       bool checkSitePath = IsBoundUsingDataSourceID && siteMap != null;
+
+                       if (checkSitePath) {
+                               IHierarchyData data = siteMap.Provider.CurrentNode;
+                               if (data != null)
+                                       activeSiteMapPath = data.Path;
+                       }
+                       
                        ArrayList levelLines = new ArrayList ();
                        int num = Nodes.Count;
                        for (int n=0; n<num; n++)
@@ -1264,7 +1323,9 @@ namespace System.Web.UI.WebControls
                
                public override void RenderBeginTag (HtmlTextWriter writer)
                {
-                       if (SkipLinkText != "") {
+                       string skipLinkText = SkipLinkText;
+                       
+                       if (!String.IsNullOrEmpty (skipLinkText)) {
                                writer.AddAttribute (HtmlTextWriterAttribute.Href, "#" + ClientID + "_SkipLink");
                                writer.RenderBeginTag (HtmlTextWriterTag.A);
 
@@ -1273,7 +1334,7 @@ namespace System.Web.UI.WebControls
                                img.ImageUrl = csm.GetWebResourceUrl (typeof (SiteMapPath), "transparent.gif");
                                img.Attributes.Add ("height", "0");
                                img.Attributes.Add ("width", "0");
-                               img.AlternateText = SkipLinkText;
+                               img.AlternateText = skipLinkText;
                                img.Render (writer);
 
                                writer.RenderEndTag ();
@@ -1285,7 +1346,7 @@ namespace System.Web.UI.WebControls
                {
                        base.RenderEndTag (writer);
 
-                       if (SkipLinkText != "") {
+                       if (!String.IsNullOrEmpty (SkipLinkText)) {
                                writer.AddAttribute (HtmlTextWriterAttribute.Id, ClientID + "_SkipLink");
                                writer.RenderBeginTag (HtmlTextWriterTag.A);
                                writer.RenderEndTag ();
@@ -1294,6 +1355,9 @@ namespace System.Web.UI.WebControls
                
                void RenderNode (HtmlTextWriter writer, TreeNode node, int level, ArrayList levelLines, bool hasPrevious, bool hasNext)
                {
+                       if (node.PopulateOnDemand && node.HadChildrenBeforePopulating)
+                               throw new InvalidOperationException ("PopulateOnDemand cannot be set to true on a node that already has children.");
+                       
                        DecorateNode(node);
                        
                        string nodeImage;
@@ -1311,9 +1375,9 @@ namespace System.Web.UI.WebControls
                        else
                                hasChildNodes = (node.PopulateOnDemand && !node.Populated) || node.ChildNodes.Count > 0;
                                
-                       writer.AddAttribute ("cellpadding", "0", false);
-                       writer.AddAttribute ("cellspacing", "0", false);
-                       writer.AddStyleAttribute ("border-width", "0");
+                       writer.AddAttribute (HtmlTextWriterAttribute.Cellpadding, "0", false);
+                       writer.AddAttribute (HtmlTextWriterAttribute.Cellspacing, "0", false);
+                       writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
                        writer.RenderBeginTag (HtmlTextWriterTag.Table);
 
                        Unit nodeSpacing = GetNodeSpacing (node);
@@ -1328,12 +1392,12 @@ namespace System.Web.UI.WebControls
                        nodeImage = GetNodeImageUrl ("i", imageStyle);
                        for (int n=0; n<level; n++) {
                                writer.RenderBeginTag (HtmlTextWriterTag.Td);
-                               writer.AddStyleAttribute ("width", NodeIndent + "px");
-                               writer.AddStyleAttribute ("height", "1px");
+                               writer.AddStyleAttribute (HtmlTextWriterStyle.Width, NodeIndent + "px");
+                               writer.AddStyleAttribute (HtmlTextWriterStyle.Height, "1px");
                                writer.RenderBeginTag (HtmlTextWriterTag.Div);
                                if (ShowLines && levelLines [n] != null) {
-                                       writer.AddAttribute ("src", nodeImage);
-                                       writer.AddAttribute (HtmlTextWriterAttribute.Alt, "", false);
+                                       writer.AddAttribute (HtmlTextWriterAttribute.Src, nodeImage);
+                                       writer.AddAttribute (HtmlTextWriterAttribute.Alt, String.Empty, false);
                                        writer.RenderBeginTag (HtmlTextWriterTag.Img);
                                        writer.RenderEndTag ();
                                }
@@ -1342,46 +1406,54 @@ namespace System.Web.UI.WebControls
                        }
                        
                        // Node image + line
-                       
-                       if (ShowExpandCollapse || ShowLines) {
+                       bool showExpandCollapse = ShowExpandCollapse;
+                       bool showLines = ShowLines;
+                       if (showExpandCollapse || showLines) {
                                bool buttonImage = false;
-                               string tooltip = "";
-                               string shape = "";
+                               string tooltip = String.Empty;
+                               string shape = String.Empty;
                                
-                               if (ShowLines) {
-                                       if (hasPrevious && hasNext) shape = "t";
-                                       else if (hasPrevious && !hasNext) shape = "l";
-                                       else if (!hasPrevious && hasNext) shape = "r";
-                                       else shape = "dash";
+                               if (showLines) {
+                                       if (hasPrevious && hasNext)
+                                               shape = "t";
+                                       else if (hasPrevious && !hasNext)
+                                               shape = "l";
+                                       else if (!hasPrevious && hasNext)
+                                               shape = "r";
+                                       else
+                                               shape = "dash";
                                }
                                
-                               if (ShowExpandCollapse) {
+                               if (showExpandCollapse) {
                                        if (hasChildNodes) {
                                                buttonImage = true;
-                                               if (node.Expanded.HasValue && node.Expanded.Value) shape += "minus";
-                                               else shape += "plus";
+                                               if (node.Expanded.HasValue && node.Expanded.Value)
+                                                       shape += "minus";
+                                               else
+                                                       shape += "plus";
                                                tooltip = GetNodeImageToolTip (!(node.Expanded.HasValue && node.Expanded.Value), node.Text);
-                                       } else if (!ShowLines)
+                                       } else if (!showLines)
                                                shape = "noexpand";
                                }
 
-                               if (shape != "") {
+                               if (!String.IsNullOrEmpty (shape)) {
                                        nodeImage = GetNodeImageUrl (shape, imageStyle);
                                        writer.RenderBeginTag (HtmlTextWriterTag.Td);   // TD
                                        
                                        if (buttonImage) {
                                                if (!clientExpand || (!PopulateNodesFromClient && node.PopulateOnDemand && !node.Populated))
-                                                       writer.AddAttribute ("href", GetClientEvent (node, "ec"));
+                                                       writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientEvent (node, "ec"));
                                                else
-                                                       writer.AddAttribute ("href", GetClientExpandEvent(node));
+                                                       writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientExpandEvent(node));
                                                writer.RenderBeginTag (HtmlTextWriterTag.A);    // Anchor
                                        }
 
-                                       writer.AddAttribute ("alt", tooltip);
+                                       // tooltip is 'HtmlAttributeEncoded'
+                                       writer.AddAttribute (HtmlTextWriterAttribute.Alt, tooltip);
 
                                        if (buttonImage && clientExpand)
-                                               writer.AddAttribute ("id", GetNodeClientId (node, "img"));
-                                       writer.AddAttribute ("src", nodeImage);
+                                               writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "img"));
+                                       writer.AddAttribute (HtmlTextWriterAttribute.Src, nodeImage);
                                        if (buttonImage)
                                                writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
                                        writer.RenderBeginTag (HtmlTextWriterTag.Img);
@@ -1412,9 +1484,9 @@ namespace System.Web.UI.WebControls
                        if (!String.IsNullOrEmpty (imageUrl)) {
                                writer.RenderBeginTag (HtmlTextWriterTag.Td);   // TD
                                BeginNodeTag (writer, node, clientExpand);
-                               writer.AddAttribute ("src", imageUrl);
+                               writer.AddAttribute (HtmlTextWriterAttribute.Src, imageUrl);
                                writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0");
-                               writer.AddAttribute ("alt", node.ImageToolTip);
+                               writer.AddAttribute (HtmlTextWriterAttribute.Alt, node.ImageToolTip);
                                writer.RenderBeginTag (HtmlTextWriterTag.Img);
                                writer.RenderEndTag (); // IMG
                                writer.RenderEndTag (); // style tag
@@ -1422,8 +1494,15 @@ namespace System.Web.UI.WebControls
                        }
 
                        if (!NodeWrap)
-                               writer.AddStyleAttribute ("white-space", "nowrap");
-                       AddNodeStyle (writer, node, level);
+                               writer.AddStyleAttribute (HtmlTextWriterStyle.WhiteSpace, "nowrap");
+
+                       bool nodeIsSelected = node == SelectedNode && selectedNodeStyle != null;
+                       if (!nodeIsSelected && selectedNodeStyle != null) {
+                               if (!String.IsNullOrEmpty (activeSiteMapPath))
+                                       nodeIsSelected = String.Compare (activeSiteMapPath, node.NavigateUrl, RuntimeHelpers.StringComparison) == 0;
+                       }
+                       
+                       AddNodeStyle (writer, node, level, nodeIsSelected);
                        if (EnableClientScript) {
                                writer.AddAttribute ("onmouseout", "TreeView_UnhoverNode(this)", false);
                                writer.AddAttribute ("onmouseover", "TreeView_HoverNode('" + ClientID + "', this)");
@@ -1433,10 +1512,10 @@ namespace System.Web.UI.WebControls
                        // Checkbox
                        
                        if (node.ShowCheckBoxInternal) {
-                               writer.AddAttribute ("name", ClientID + "_cs_" + node.Path);
-                               writer.AddAttribute ("type", "checkbox", false);
-                               writer.AddAttribute ("title", node.Text);
-                               if (node.Checked) writer.AddAttribute ("checked", "checked", false);
+                               writer.AddAttribute (HtmlTextWriterAttribute.Name, ClientID + "_cs_" + node.Path);
+                               writer.AddAttribute (HtmlTextWriterAttribute.Type, "checkbox", false);
+                               writer.AddAttribute (HtmlTextWriterAttribute.Title, node.Text);
+                               if (node.Checked) writer.AddAttribute (HtmlTextWriterAttribute.Checked, "checked", false);
                                writer.RenderBeginTag (HtmlTextWriterTag.Input);        // INPUT
                                writer.RenderEndTag (); // INPUT
                        }
@@ -1446,8 +1525,8 @@ namespace System.Web.UI.WebControls
                        node.BeginRenderText (writer);
                        
                        if (clientExpand)
-                               writer.AddAttribute ("id", GetNodeClientId (node, "txt"));
-                       AddNodeLinkStyle (writer, node, level);
+                               writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, "txt"));
+                       AddNodeLinkStyle (writer, node, level, nodeIsSelected);
                        BeginNodeTag (writer, node, clientExpand);
                        writer.Write (node.Text);
                        writer.RenderEndTag (); // style tag
@@ -1480,10 +1559,10 @@ namespace System.Web.UI.WebControls
                                
                                if (clientExpand) {
                                        if (!(node.Expanded.HasValue && node.Expanded.Value))
-                                               writer.AddStyleAttribute ("display", "none");
+                                               writer.AddStyleAttribute (HtmlTextWriterStyle.Display, "none");
                                        else
-                                               writer.AddStyleAttribute ("display", "block");
-                                       writer.AddAttribute ("id", GetNodeClientId (node, null));
+                                               writer.AddStyleAttribute (HtmlTextWriterStyle.Display, "block");
+                                       writer.AddAttribute (HtmlTextWriterAttribute.Id, GetNodeClientId (node, null));
                                        writer.RenderBeginTag (HtmlTextWriterTag.Span);
                                        
                                        if (renderChildNodes) {
@@ -1506,7 +1585,7 @@ namespace System.Web.UI.WebControls
                        }
                }
 
-               private void AddChildrenPadding (HtmlTextWriter writer, TreeNode node)
+               void AddChildrenPadding (HtmlTextWriter writer, TreeNode node)
                {
                        int level = node.Depth;
                        Unit cnp = Unit.Empty;
@@ -1521,7 +1600,7 @@ namespace System.Web.UI.WebControls
                                return;
 
                        writer.RenderBeginTag (HtmlTextWriterTag.Table);
-                       writer.AddAttribute ("height", ((int) value).ToString (), false);
+                       writer.AddAttribute (HtmlTextWriterAttribute.Height, ((int) value).ToString (), false);
                        writer.RenderBeginTag (HtmlTextWriterTag.Tr);
                        writer.RenderBeginTag (HtmlTextWriterTag.Td);
                        writer.RenderEndTag (); // td
@@ -1529,32 +1608,30 @@ namespace System.Web.UI.WebControls
                        writer.RenderEndTag (); // table
                }
                
-               private void RenderMenuItemSpacing (HtmlTextWriter writer, Unit itemSpacing) {
-                       writer.AddStyleAttribute ("height", itemSpacing.ToString ());
+               void RenderMenuItemSpacing (HtmlTextWriter writer, Unit itemSpacing)
+               {
+                       writer.AddStyleAttribute (HtmlTextWriterStyle.Height, itemSpacing.ToString ());
                        writer.RenderBeginTag (HtmlTextWriterTag.Tr);
                        writer.RenderBeginTag (HtmlTextWriterTag.Td);
                        writer.RenderEndTag ();
                        writer.RenderEndTag ();
                }
 
-               private Unit GetNodeSpacing (TreeNode node) {
-                       if (node.Selected && selectedNodeStyle != null && selectedNodeStyle.NodeSpacing != Unit.Empty) {
+               Unit GetNodeSpacing (TreeNode node)
+               {
+                       if (node.Selected && selectedNodeStyle != null && selectedNodeStyle.NodeSpacing != Unit.Empty)
                                return selectedNodeStyle.NodeSpacing;
-                       }
 
-                       if (levelStyles != null && node.Depth < levelStyles.Count && levelStyles [node.Depth].NodeSpacing != Unit.Empty) {
+                       if (levelStyles != null && node.Depth < levelStyles.Count && levelStyles [node.Depth].NodeSpacing != Unit.Empty)
                                return levelStyles [node.Depth].NodeSpacing;
-                       }
 
                        if (node.IsLeafNode) {
                                if (leafNodeStyle != null && leafNodeStyle.NodeSpacing != Unit.Empty)
                                        return leafNodeStyle.NodeSpacing;
-                       }
-                       else if (node.IsRootNode) {
+                       } else if (node.IsRootNode) {
                                if (rootNodeStyle != null && rootNodeStyle.NodeSpacing != Unit.Empty)
                                        return rootNodeStyle.NodeSpacing;
-                       }
-                       else if (node.IsParentNode) {
+                       } else if (node.IsParentNode) {
                                if (parentNodeStyle != null && parentNodeStyle.NodeSpacing != Unit.Empty)
                                        return parentNodeStyle.NodeSpacing;
                        }
@@ -1564,8 +1641,8 @@ namespace System.Web.UI.WebControls
                        else
                                return Unit.Empty;
                }
-               
-               void AddNodeStyle (HtmlTextWriter writer, TreeNode node, int level)
+
+               void AddNodeStyle (HtmlTextWriter writer, TreeNode node, int level, bool nodeIsSelected)
                {
                        TreeNodeStyle style = new TreeNodeStyle ();
                        if (Page.Header != null) {
@@ -1579,14 +1656,12 @@ namespace System.Web.UI.WebControls
                                                style.AddCssClass (leafNodeStyle.CssClass);
                                                style.AddCssClass (leafNodeStyle.RegisteredCssClass);
                                        }
-                               }
-                               else if (node.IsRootNode) {
+                               } else if (node.IsRootNode) {
                                        if (rootNodeStyle != null) {
                                                style.AddCssClass (rootNodeStyle.CssClass);
                                                style.AddCssClass (rootNodeStyle.RegisteredCssClass);
                                        }
-                               }
-                               else if (node.IsParentNode) {
+                               } else if (node.IsParentNode) {
                                        if (parentNodeStyle != null) {
                                                style.AddCssClass (parentNodeStyle.CssClass);
                                                style.AddCssClass (parentNodeStyle.RegisteredCssClass);
@@ -1596,12 +1671,12 @@ namespace System.Web.UI.WebControls
                                        style.AddCssClass (levelStyles [level].CssClass);
                                        style.AddCssClass (levelStyles [level].RegisteredCssClass);
                                }
-                               if (node == SelectedNode && selectedNodeStyle != null) {
+                               
+                               if (nodeIsSelected) {
                                        style.AddCssClass (selectedNodeStyle.CssClass);
                                        style.AddCssClass (selectedNodeStyle.RegisteredCssClass);
                                }
-                       }
-                       else {
+                       } else {
                                // styles are not registered
                                if (nodeStyle != null) {
                                        style.CopyFrom (nodeStyle);
@@ -1610,28 +1685,26 @@ namespace System.Web.UI.WebControls
                                        if (leafNodeStyle != null) {
                                                style.CopyFrom (leafNodeStyle);
                                        }
-                               }
-                               else if (node.IsRootNode) {
+                               } else if (node.IsRootNode) {
                                        if (rootNodeStyle != null) {
                                                style.CopyFrom (rootNodeStyle);
                                        }
-                               }
-                               else if (node.IsParentNode) {
+                               } else if (node.IsParentNode) {
                                        if (parentNodeStyle != null) {
                                                style.CopyFrom (parentNodeStyle);
                                        }
                                }
-                               if (levelStyles != null && levelStyles.Count > level) {
+                               if (levelStyles != null && levelStyles.Count > level)
                                        style.CopyFrom (levelStyles [level]);
-                               }
-                               if (node == SelectedNode && selectedNodeStyle != null) {
+                               
+                               if (nodeIsSelected)
                                        style.CopyFrom (selectedNodeStyle);
-                               }
                        }
                        style.AddAttributesToRender (writer);
                }
 
-               void AddNodeLinkStyle (HtmlTextWriter writer, TreeNode node, int level) {
+               void AddNodeLinkStyle (HtmlTextWriter writer, TreeNode node, int level, bool nodeIsSelected)
+               {
                        Style style = new Style ();
                        if (Page.Header != null) {
                                // styles are registered
@@ -1641,60 +1714,58 @@ namespace System.Web.UI.WebControls
                                        style.AddCssClass (nodeLinkStyle.CssClass);
                                        style.AddCssClass (nodeLinkStyle.RegisteredCssClass);
                                }
+
+                               if (levelLinkStyles != null && levelLinkStyles.Count > level) {
+                                       style.AddCssClass (levelLinkStyles [level].CssClass);
+                                       style.AddCssClass (levelLinkStyles [level].RegisteredCssClass);
+                               }
+                               
                                if (node.IsLeafNode) {
                                        if (leafNodeStyle != null) {
                                                style.AddCssClass (leafNodeLinkStyle.CssClass);
                                                style.AddCssClass (leafNodeLinkStyle.RegisteredCssClass);
                                        }
-                               }
-                               else if (node.IsRootNode) {
+                               } else if (node.IsRootNode) {
                                        if (rootNodeStyle != null) {
                                                style.AddCssClass (rootNodeLinkStyle.CssClass);
                                                style.AddCssClass (rootNodeLinkStyle.RegisteredCssClass);
                                        }
-                               }
-                               else if (node.IsParentNode) {
+                               } else if (node.IsParentNode) {
                                        if (parentNodeStyle != null) {
                                                style.AddCssClass (parentNodeLinkStyle.CssClass);
                                                style.AddCssClass (parentNodeLinkStyle.RegisteredCssClass);
                                        }
                                }
-                               if (levelStyles != null && levelStyles.Count > level) {
-                                       style.AddCssClass (levelLinkStyles [level].CssClass);
-                                       style.AddCssClass (levelLinkStyles [level].RegisteredCssClass);
-                               }
-                               if (node == SelectedNode && selectedNodeStyle != null) {
+                               
+                               if (nodeIsSelected) {
                                        style.AddCssClass (selectedNodeLinkStyle.CssClass);
                                        style.AddCssClass (selectedNodeLinkStyle.RegisteredCssClass);
                                }
-                       }
-                       else {
+                       } else {
                                // styles are not registered
                                style.CopyFrom (ControlLinkStyle);
-                               if (nodeStyle != null) {
+                               if (nodeStyle != null)
                                        style.CopyFrom (nodeLinkStyle);
-                               }
+
+                               if (levelLinkStyles != null && levelLinkStyles.Count > level)
+                                       style.CopyFrom (levelLinkStyles [level]);
+                               
                                if (node.IsLeafNode) {
                                        if (node.IsLeafNode && leafNodeStyle != null) {
                                                style.CopyFrom (leafNodeLinkStyle);
                                        }
-                               }
-                               else if (node.IsRootNode) {
+                               } else if (node.IsRootNode) {
                                        if (node.IsRootNode && rootNodeStyle != null) {
                                                style.CopyFrom (rootNodeLinkStyle);
                                        }
-                               }
-                               else if (node.IsParentNode) {
+                               } else if (node.IsParentNode) {
                                        if (node.IsParentNode && parentNodeStyle != null) {
                                                style.CopyFrom (parentNodeLinkStyle);
                                        }
                                }
-                               if (levelStyles != null && levelStyles.Count > level) {
-                                       style.CopyFrom (levelLinkStyles [level]);
-                               }
-                               if (node == SelectedNode && selectedNodeStyle != null) {
+                               
+                               if (nodeIsSelected)
                                        style.CopyFrom (selectedNodeLinkStyle);
-                               }
                                style.AlwaysRenderTextDecoration = true;
                        }
                        style.AddAttributesToRender (writer);
@@ -1703,44 +1774,46 @@ namespace System.Web.UI.WebControls
                void BeginNodeTag (HtmlTextWriter writer, TreeNode node, bool clientExpand)
                {
                        if(node.ToolTip.Length>0)
-                               writer.AddAttribute ("title", node.ToolTip);
+                               writer.AddAttribute (HtmlTextWriterAttribute.Title, node.ToolTip);
 
-                       if (node.NavigateUrl != "") {
+                       string navigateUrl = node.NavigateUrl;
+                       if (!String.IsNullOrEmpty (navigateUrl)) {
                                string target = node.Target.Length > 0 ? node.Target : Target;
 #if TARGET_J2EE
-                               string navUrl = ResolveClientUrl (node.NavigateUrl, String.Compare (target, "_blank", StringComparison.InvariantCultureIgnoreCase) != 0);
+                               string navUrl = ResolveClientUrl (navigateUrl, String.Compare (target, "_blank", StringComparison.InvariantCultureIgnoreCase) != 0);
 #else
-                               string navUrl = ResolveClientUrl (node.NavigateUrl);
+                               string navUrl = ResolveClientUrl (navigateUrl);
 #endif
-                               writer.AddAttribute ("href", navUrl);
+                               writer.AddAttribute (HtmlTextWriterAttribute.Href, navUrl);
                                if (target.Length > 0)
-                                       writer.AddAttribute ("target", target);
+                                       writer.AddAttribute (HtmlTextWriterAttribute.Target, target);
                                writer.RenderBeginTag (HtmlTextWriterTag.A);
-                       }
-                       else if (node.SelectAction != TreeNodeSelectAction.None) {
+                       } else if (node.SelectAction != TreeNodeSelectAction.None) {
                                if (node.SelectAction == TreeNodeSelectAction.Expand && clientExpand)
-                                       writer.AddAttribute ("href", GetClientExpandEvent (node));
+                                       writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientExpandEvent (node));
                                else
-                                       writer.AddAttribute ("href", GetClientEvent (node, "sel"));
+                                       writer.AddAttribute (HtmlTextWriterAttribute.Href, GetClientEvent (node, "sel"));
                                writer.RenderBeginTag (HtmlTextWriterTag.A);
-                       }
-                       else
+                       } else
                                writer.RenderBeginTag (HtmlTextWriterTag.Span);
                }
                
-               string GetNodeImageToolTip (bool expand, string txt) {
-                       if (expand)  {
-                               if (ExpandImageToolTip != "")
-                                       return String.Format (ExpandImageToolTip, txt);
+               string GetNodeImageToolTip (bool expand, string txt)
+               {
+                       if (expand) {
+                               string expandImageToolTip = ExpandImageToolTip;
+                               if (!String.IsNullOrEmpty (expandImageToolTip))
+                                       return String.Format (expandImageToolTip, HttpUtility.HtmlAttributeEncode (txt));
                                else if (txt != null)
-                                       return "Expand " + txt;
+                                       return "Expand " + HttpUtility.HtmlAttributeEncode (txt);
                                else
                                        return "Expand {0}";
                        } else {
-                               if (CollapseImageToolTip != "")
-                                       return String.Format (CollapseImageToolTip, txt);
+                               string collapseImageToolTip = CollapseImageToolTip;
+                               if (!String.IsNullOrEmpty (collapseImageToolTip))
+                                       return String.Format (collapseImageToolTip, HttpUtility.HtmlAttributeEncode (txt));
                                else if (txt != null)
-                                       return "Collapse " + txt;
+                                       return "Collapse " + HttpUtility.HtmlAttributeEncode (txt);
                                else
                                        return "Collapse {0}";
                        }
@@ -1748,7 +1821,7 @@ namespace System.Web.UI.WebControls
                
                string GetNodeClientId (TreeNode node, string sufix)
                {
-                       return ClientID + "_" + node.Path + (sufix != null ? "_" + sufix : "");
+                       return ClientID + "_" + node.Path + (sufix != null ? "_" + sufix : String.Empty);
                }
                                                        
                string GetNodeImageUrl (string shape, ImageStyle imageStyle)
@@ -1761,26 +1834,21 @@ namespace System.Web.UI.WebControls
                                        if (shape == "plus") {
                                                if (!String.IsNullOrEmpty (imageStyle.Expand))
                                                        return GetNodeIconUrl (imageStyle.Expand);
-                                       }
-                                       else if (shape == "minus") {
+                                       } else if (shape == "minus") {
                                                if (!String.IsNullOrEmpty (imageStyle.Collapse))
                                                        return GetNodeIconUrl (imageStyle.Collapse);
-                                       }
-                                       else if (shape == "noexpand") {
+                                       } else if (shape == "noexpand") {
                                                if (!String.IsNullOrEmpty (imageStyle.NoExpand))
                                                        return GetNodeIconUrl (imageStyle.NoExpand);
                                        }
-                               }
-                               else {
+                               } else {
                                        if (shape == "plus") {
                                                if (!String.IsNullOrEmpty (ExpandImageUrl))
                                                        return ResolveClientUrl (ExpandImageUrl);
-                                       }
-                                       else if (shape == "minus") {
+                                       } else if (shape == "minus") {
                                                if (!String.IsNullOrEmpty (CollapseImageUrl))
                                                        return ResolveClientUrl (CollapseImageUrl);
-                                       }
-                                       else if (shape == "noexpand") {
+                                       } else if (shape == "noexpand") {
                                                if (!String.IsNullOrEmpty (NoExpandImageUrl))
                                                        return ResolveClientUrl (NoExpandImageUrl);
                                        }
@@ -1803,9 +1871,15 @@ namespace System.Web.UI.WebControls
                
                string GetClientExpandEvent (TreeNode node)
                {
-                       return "javascript:TreeView_ToggleExpand ('" + ClientID + "', '" + node.Path + "')";
+                       return String.Format ("javascript:TreeView_ToggleExpand ('{0}','{1}','{2}','{3}','{4}','{5}')",
+                                             ClientID,
+                                             node.Path,
+                                             HttpUtility.HtmlAttributeEncode (node.Value).Replace ("'", "\\'").Replace ("|","U+007C"),
+                                             HttpUtility.HtmlAttributeEncode (node.ImageUrl).Replace ("'", "\\'").Replace ("|","U+007c"),
+                                             HttpUtility.HtmlAttributeEncode (node.NavigateUrl).Replace ("'", "\\'").Replace ("|","U+007C"),
+                                             HttpUtility.HtmlAttributeEncode (node.Target).Replace ("'", "\\'").Replace ("|","U+007C"));
                }
-               
+
                TreeNode FindNodeByPos (string path)
                {
                        string[] indexes = path.Split ('_');
@@ -1867,7 +1941,8 @@ namespace System.Web.UI.WebControls
                void SetExpandStates (string[] states)
                {
                        foreach (string id in states) {
-                               if (id == null || id == "") continue;
+                               if (String.IsNullOrEmpty (id))
+                                       continue;
                                TreeNode node = FindNodeByPos (id);
                                if (node != null)
                                        node.Expanded = true;
@@ -1897,5 +1972,4 @@ namespace System.Web.UI.WebControls
                }
        }
 }
-
 #endif