context: using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Drawing;
  using System.Windows.Forms;
  using System.Xml;
  using System.IO;
  using System.Text.RegularExpressions;
  
  namespace ScintillaNet.Configuration
  {
  	public class Configuration
  	{
  		private string _language;
  		public string Language
  		{
  			get
  			{
  				return _language;
  			}
  			set
  			{
  				_language = value;
  			}
  		}
  
  		#region Constructor
  		public Configuration(string language)
  		{
  			_language = language;
  		}
  
  
  
  		public Configuration(XmlDocument configDocument, string language)
  		{
  			_language = language;
  			Load(configDocument);
  		}
  
  		public Configuration(string fileName, string language, bool useXmlReader)
  		{
  			_language = language;
  			Load(fileName, useXmlReader);
  		}
  
  
  		public Configuration(Stream inStream, string language, bool useXmlReader)
  		{
  			_language = language;
  			Load(inStream, useXmlReader);
  		}
  
  		public Configuration(TextReader txtReader, string language)
  		{
  			_language = language;
  			Load(txtReader);
  		}
  
  		public Configuration(XmlReader reader, string language)
  		{
  			_language = language;
  			Load(reader);
  		}
  
  		#endregion
  
  		#region Load
  		public void Load(string fileName, bool useXmlReader)
  		{
  			if (useXmlReader)
  			{
  				XmlReaderSettings s = new XmlReaderSettings();
  				s.IgnoreComments = true;
  				s.IgnoreWhitespace = true;
  
  				Load(XmlReader.Create(fileName, s));
  			}
  			else
  			{
  				XmlDocument doc = new XmlDocument();
  				doc.PreserveWhitespace = true;
  				doc.Load(fileName);
  
  				Load(doc);
  			}
  		}
  
  		public void Load(Stream inStream, bool useXmlReader)
  		{
  			if (useXmlReader)
  			{
  				XmlReaderSettings s = new XmlReaderSettings();
  				s.IgnoreComments = true;
  				s.IgnoreWhitespace = true;
  
  				Load(XmlReader.Create(inStream, s));
  			}
  			else
  			{
  				XmlDocument doc = new XmlDocument();
  				doc.PreserveWhitespace = true;
  				doc.Load(inStream);
  				Load(doc);
  			}
  		}
  
  		public void Load(TextReader txtReader)
  		{
  			XmlDocument configDocument = new XmlDocument();
  			configDocument.PreserveWhitespace = true;
  			configDocument.Load(txtReader);
  			Load(configDocument);
  		}
  
  		public void Load(XmlReader reader)
  		{
  			reader.ReadStartElement();
  			
  
  			while (!reader.EOF)
  			{
  				if (reader.Name.Equals("language", StringComparison.OrdinalIgnoreCase) && reader.HasAttributes)
  				{
  					while (reader.MoveToNextAttribute())
  					{
  						if (reader.Name.Equals("name", StringComparison.OrdinalIgnoreCase) && reader.Value.Equals(_language, StringComparison.OrdinalIgnoreCase))
  						{
  							readLanguage(reader);
  							_hasData = true;
  						}
  					}
  
  					if (_hasData)
  						reader.Skip();
  				}
  				else
  				{
  					reader.Skip();
  					continue;
  				}
  
  				
  				reader.Read();
  			}
  
  			reader.Close();
  		}
  
  		private void readLanguage(XmlReader reader)
  		{
  			_commands_KeyBindingList = new CommandBindingConfigList();
  			_lexing_Properties = new LexerPropertiesConfig();
  			_lexing_Keywords = new KeyWordConfigList();
  			_margin_List = new MarginConfigList();
  			_markers_List = new MarkersConfigList();
  			_snippetsConfigList = new SnippetsConfigList();
  			_styles = new StyleConfigList();
  
  			reader.Read();
  			while (reader.NodeType == XmlNodeType.Element)
  			{
  				string elName = reader.Name.ToLower();
  				switch (elName)
  				{
  					case "autocomplete":
  						readAutoComplete(reader);
  						break;
  					case "calltip":
  						readCallTip(reader);
  						break;
  					case "caret":
  						readCaret(reader);
  						break;
  					case "clipboard":
  						readClipboard(reader);
  						break;
  					case "commands":
  						readCommands(reader);
  						break;
  					case "endofline":
  						readEndOfLine(reader);
  						break;
  					case "folding":
  						readFolding(reader);
  						break;
  					case "hotspot":
  						readHotSpot(reader);
  						break;
  					case "indentation":
  						readIndentation(reader);
  						break;
  					case "indicators":
  						readIndicators(reader);
  						break;
  					case "lexer":
  						readLexer(reader);
  						break;
  					case "linewrap":
  						readLineWrap(reader);
  						break;
  					case "longlines":
  						readLongLines(reader);
  						break;
  					case "margins":
  						readMargins(reader);
  						break;
  					case "markers":
  						readMarkers(reader);
  						break;
  					case "scrolling":
  						readScrolling(reader);
  						break;
  					case "selection":
  						readSelection(reader);
  						break;
  					case "snippets":
  						readSnippets(reader);
  						break;
  					case "styles":
  						readStyles(reader);
  						break;
  					case "undoredo":
  						readUndoRedo(reader);
  						break;
  					case "whitespace":
  						readWhitespace(reader);
  						break;
  					default:
  						reader.Skip();
  						break;
  				}
  				
  			}
  		}
  
  		private void readWhitespace(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "backcolor":
  							_whitespace_BackColor = getColor(reader.Value);
  							break;
  						case "forecolor":
  							_whitespace_ForeColor = getColor(reader.Value);
  							break;
  						case "mode":
  							_whitespace_Mode = (WhitespaceMode)Enum.Parse(typeof(WhitespaceMode), reader.Value, true);
  							break;
  					}
  				}
  			}
  			reader.Skip();
  		}
  
  		private void readSnippets(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "activesnippetcolor":
  							_snippetsConfigList.ActiveSnippetColor = getColor(reader.Value);
  							break;
  						case "activesnippetindicator":
  							_snippetsConfigList.ActiveSnippetIndicator = getInt(reader.Value);
  							break;
  						case "inactivesnippetcolor":
  							_snippetsConfigList.InactiveSnippetColor = getColor(reader.Value);
  							break;
  						case "inactivesnippetindicator":
  							_snippetsConfigList.InactiveSnippetIndicator = getInt(reader.Value);
  							break;
  						case "activesnippetindicatorstyle":
  							_snippetsConfigList.ActiveSnippetIndicatorStyle = (IndicatorStyle)Enum.Parse(typeof(IndicatorStyle), reader.Value, true);
  							break;
  						case "inactivesnippetindicatorstyle":
  							_snippetsConfigList.InactiveSnippetIndicatorStyle = (IndicatorStyle)Enum.Parse(typeof(IndicatorStyle), reader.Value, true);
  							break;
  						case "defaultdelimeter":
  							_snippetsConfigList.DefaultDelimeter = getChar(reader.Value);
  							break;
  						case "isenabled":
  							_snippetsConfigList.IsEnabled = getBool(reader.Value);
  							break;
  						case "isonekeyselectionembedenabled":
  							_snippetsConfigList.IsOneKeySelectionEmbedEnabled = getBool(reader.Value);
  							break;
  					}
  				}
  
  				reader.MoveToElement();
  			}
  
  			if (!reader.IsEmptyElement)
  			{
  				while (!(reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("snippets", StringComparison.OrdinalIgnoreCase)))
  				{
  					reader.Read();
  					if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals("snippet", StringComparison.OrdinalIgnoreCase))
  					{
  						if (reader.HasAttributes)
  						{
  							SnippetsConfig sc = new SnippetsConfig();
  							if (reader.HasAttributes)
  							{
  								while (reader.MoveToNextAttribute())
  								{
  									string attrName = reader.Name.ToLower();
  									switch (attrName)
  									{
  
  										case "shortcut":
  											sc.Shortcut = reader.Value;
  											break;
  										case "delimeter":
  											sc.Delimeter = getChar(reader.Value);
  											break;
  										case "issurroundswith":
  											sc.IsSurroundsWith = getBool(reader.Value);
  											break;
  									}
  								}
  							}
  							reader.MoveToElement();
  							sc.Code = reader.ReadString();
  							_snippetsConfigList.Add(sc);
  						}
  					}
  				}
  			}
  
  			reader.Read();
  		}
  
  		private StyleConfig getStyleConfigFromElement(XmlReader reader)
  		{
  			StyleConfig sc = new StyleConfig();
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "name":
  							sc.Name = reader.Value;
  							break;
  						case "number":
  							sc.Number = getInt(reader.Value);
  							break;
  						case "backcolor":
  							sc.BackColor = getColor(reader.Value);
  							break;
  						case "bold":
  							sc.Bold = getBool(reader.Value);
  							break;
  						case "case":
  							sc.Case = (StyleCase)Enum.Parse(typeof(StyleCase), reader.Value, true);
  							break;
  						case "characterset":
  							sc.CharacterSet = (CharacterSet)Enum.Parse(typeof(CharacterSet), reader.Value, true);
  							break;
  						case "fontname":
  							sc.FontName = reader.Value;
  							break;
  						case "forecolor":
  							sc.ForeColor = getColor(reader.Value);
  							break;
  						case "ischangeable":
  							sc.IsChangeable = getBool(reader.Value);
  							break;
  						case "ishotspot":
  							sc.IsHotspot = getBool(reader.Value);
  							break;
  						case "isselectioneolfilled":
  							sc.IsSelectionEolFilled = getBool(reader.Value);
  							break;
  						case "isvisible":
  							sc.IsVisible = getBool(reader.Value);
  							break;
  						case "italic":
  							sc.Italic = getBool(reader.Value);
  							break;
  						case "size":
  							sc.Size = getInt(reader.Value);
  							break;
  						case "underline":
  							sc.Underline = getBool(reader.Value);
  							break;
  						case "inherit":
  							sc.Inherit = getBool(reader.Value);
  							break;
  					}
  				}
  				reader.MoveToElement();
  			}
  
  			return sc;
          }
  
  		private void readStyles(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  					if (reader.Name.ToLower() == "bits")
  						_undoRedoIsUndoEnabled = getBool(reader.Value);
  
  				reader.MoveToElement();
  			}
  
  			if (!reader.IsEmptyElement)
  			{
  				while (!(reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("styles", StringComparison.OrdinalIgnoreCase)))
  				{
  					reader.Read();
  					if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals("style", StringComparison.OrdinalIgnoreCase))
  					{
  						_styles.Add(getStyleConfigFromElement(reader));
  					}
  					else if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals("sublanguage", StringComparison.OrdinalIgnoreCase))
  					{
  						readSubLanguage(reader);
  					}
  				}
  			}
  
  			reader.Read();
  		}
  
  		private void readSubLanguage(XmlReader reader)
  		{
  			//	This is a nifty added on hack made specifically for HTML.
  			//	Normally the style config elements are quite managable as there
  			//	are typically less than 10 when you don't count common styles.
  			//	
  			//	However HTML uses 9 different Sub languages that combined make 
  			//	use of all 128 styles (well there are some small gaps). In order
  			//	to make this more managable I did added a SubLanguage element that
  			//	basically just prepends the Language's name and "." to the Style 
  			//	Name definition.
  			//
  			//	So for example if you had the following
  			//	<Styles>
  			//		<SubLanguage Name="ASP JavaScript">
  			//			<Style Name="Keyword" Bold="True" />
  			//		</SubLanguage>
  			//	</Styles>
  			//	That style's name will get interpreted as "ASP JavaScript.Keyword".
  			//	which if you look at the html.txt in LexerStyleNames you'll see it
  			//	maps to Style # 62
  			string subLanguageName = string.Empty;
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  					if (reader.Name.ToLower() == "name")
  						subLanguageName = reader.Value;
  
  				reader.MoveToElement();
  			}
  
  			if (!reader.IsEmptyElement)
  			{
  				while (!(reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("sublanguage", StringComparison.OrdinalIgnoreCase)))
  				{
  					reader.Read();
  					if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals("style", StringComparison.OrdinalIgnoreCase))
  					{
  						StyleConfig sc = getStyleConfigFromElement(reader);
  						sc.Name = subLanguageName + "." + sc.Name;
  						_styles.Add(sc);
  					}
  				}
  			}
  
  			reader.Read();
  		}
  		
  
  		private void readUndoRedo(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  					if (reader.Name.ToLower() == "isundoenabled")
  						_undoRedoIsUndoEnabled = getBool(reader.Value);
  
  				reader.MoveToElement();
  			}
  			reader.Skip();
  		}
  
  		private void readSelection(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "backcolor":
  							_selection_BackColor = getColor(reader.Value);
  							break;
  						case "backcolorunfocused":
  							_selection_BackColorUnfocused = getColor(reader.Value);
  							break;
  						case "forecolor":
  							_selection_ForeColor = getColor(reader.Value);
  							break;
  						case "forecolorunfocused":
  							_selection_ForeColorUnfocused = getColor(reader.Value);
  							break;
  						case "hidden":
  							_selection_Hidden = getBool(reader.Value);
  							break;
  						case "hideselection":
  							_selection_HideSelection = getBool(reader.Value);
  							break;
  						case "mode":
  							_selection_Mode = (SelectionMode)Enum.Parse(typeof(SelectionMode), reader.Value, true);
  							break;
  					}
  				}
  				reader.MoveToElement();
  			}
  
  			reader.Skip();
  		}
  
  		private void readScrolling(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "endatlastline":
  							_scrolling_EndAtLastLine = getBool(reader.Value);
  							break;
  						case "horizontalwidth":
  							_scrolling_HorizontalWidth = getInt(reader.Value);
  							break;
  						case "scrollbars":
  							string flags = reader.Value.Trim();
  							if (flags != string.Empty)
  							{
  								ScrollBars? sb = null;
  								foreach (string flag in flags.Split(' '))
  									sb |= (ScrollBars)Enum.Parse(typeof(ScrollBars), flag.Trim(), true);
  
  								if (sb.HasValue)
  									_scrolling_ScrollBars = sb;
  							}
  							break;
  						case "xoffset":
  							_scrolling_XOffset = getInt(reader.Value);
  							break;
  					}
  				}
  				reader.MoveToElement();
  			}
  
  			reader.Skip();
  		}
  
  		private void readMarkers(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  					if(reader.Name.ToLower() == "inherit")
  						_markers_List.Inherit = getBool(reader.Value);
  
  				reader.MoveToElement();
  			}
  
  			if (!reader.IsEmptyElement)
  			{
  				while (!(reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("markers", StringComparison.OrdinalIgnoreCase)))
  				{
  					reader.Read();
  					if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals("marker", StringComparison.OrdinalIgnoreCase))
  					{
  						if (reader.HasAttributes)
  						{
  							MarkersConfig mc = new MarkersConfig();
  							while (reader.MoveToNextAttribute())
  							{
  								string attrName = reader.Name.ToLower();
  								switch (attrName)
  								{
  									case "alpha":
  										mc.Alpha = getInt(reader.Value);
  										break;
  									case "backcolor":
  										mc.BackColor = getColor(reader.Value);
  										break;
  									case "forecolor":
  										mc.ForeColor = getColor(reader.Value);
  										break;
  									case "name":
  										mc.Name = reader.Value;
  										break;
  									case "number":
  										mc.Number = getInt(reader.Value);
  										break;
  									case "inherit":
  										mc.Inherit = getBool(reader.Value);
  										break;
  									case "symbol":
  										mc.Symbol = (MarkerSymbol)Enum.Parse(typeof(MarkerSymbol), reader.Value, true);
  										break;
  								}
  							}
  							
  							reader.MoveToElement();
  							_markers_List.Add(mc);
  						}
  					}
  				}
  			}
  			reader.Read();
  		}
  
  		private void readMargins(XmlReader reader)
  		{			
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "foldmargincolor":
  							_margin_List.FoldMarginColor = getColor(reader.Value);
  							break;
  						case "foldmarginhighlightcolor":
  							_margin_List.FoldMarginHighlightColor = getColor(reader.Value);
  							break;
  						case "left":
  							_margin_List.Left = getInt(reader.Value);
  							break;
  						case "right":
  							_margin_List.Right = getInt(reader.Value);
  							break;
  						case "inherit":
  							_margin_List.Inherit = getBool(reader.Value);
  							break;
  					}
  				}
  				reader.MoveToElement();
  			}
  			
  			
  			if (!reader.IsEmptyElement)
  			{
  				while (!(reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("margins", StringComparison.OrdinalIgnoreCase)))
  				{
  					reader.Read();
  					if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals("margin", StringComparison.OrdinalIgnoreCase))
  					{
  						if (reader.HasAttributes)
  						{
  							MarginConfig mc = new MarginConfig();
  							while (reader.MoveToNextAttribute())
  							{
  								string attrName = reader.Name.ToLower();
  								switch (attrName)
  								{
  									case "number":
  										mc.Number = int.Parse(reader.Value);
  										break;
  									case "inherit":
  										mc.Inherit = getBool(reader.Value);
  										break;
  									case "autotogglemarkernumber":
  										mc.AutoToggleMarkerNumber = getInt(reader.Value);
  										break;
  									case "isclickable":
  										mc.IsClickable = getBool(reader.Value);
  										break;
  									case "isfoldmargin":
  										mc.IsFoldMargin = getBool(reader.Value);
  										break;
  									case "ismarkermargin":
  										mc.IsMarkerMargin = getBool(reader.Value);
  										break;
  									case "type":
  										mc.Type = (MarginType)Enum.Parse(typeof(MarginType), reader.Value, true);
  										break;
  									case "width":
  										mc.Width = getInt(reader.Value);
  										break;
  								}
  							}
  							_margin_List.Add(mc);
  							reader.MoveToElement();
  						}
  					}
  				}
  			}
  
  			reader.Read();
  		}
  
  		private void readLongLines(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "edgecolor":
  							_longLines_EdgeColor = getColor(reader.Value);
  							break;
  						case "edgecolumn":
  							_longLines_EdgeColumn = getInt(reader.Value);
  							break;
  						case "edgemode":
  							_longLines_EdgeMode = (EdgeMode)Enum.Parse(typeof(EdgeMode), reader.Value, true);
  							break;
  					}
  				}
  				reader.MoveToElement();
  			}
  			reader.Skip();
  		}
  
  		private void readLineWrap(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "layoutcache":
  							_lineWrap_LayoutCache = (LineCache)Enum.Parse(typeof(LineCache), reader.Value, true);
  							break;
  						case "mode":
  							_lineWrap_Mode = (WrapMode)Enum.Parse(typeof(WrapMode), reader.Value, true);
  							break;
  						case "positioncachesize":
  							_lineWrap_PositionCacheSize = getInt(reader.Value);
  							break;
  						case "startindent":
  							_lineWrap_StartIndent = getInt(reader.Value);
  							break;
  						case "visualflags":
  							string flags = reader.Value.Trim();
  							if (flags != string.Empty)
  							{
  								WrapVisualFlag? wvf = null;
  								foreach (string flag in flags.Split(' '))
  									wvf |= (WrapVisualFlag)Enum.Parse(typeof(WrapVisualFlag), flag.Trim(), true);
  
  								if (wvf.HasValue)
  									_lineWrap_VisualFlags = wvf;
  							}
  							break;
  						case "visualflagslocation":
  							_lineWrap_VisualFlagsLocation = (WrapVisualLocation)Enum.Parse(typeof(WrapVisualLocation), reader.Value, true);
  							break;
  					}
  				}
  				reader.MoveToElement();
  			}
  
  			reader.Skip();
  		}
  
  		private void readLexer(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "whitespacechars":
  							_lexing_WhitespaceChars = reader.Value;
  							break;
  						case "wordchars":
  							_lexing_WordChars = reader.Value;
  							break;
  						case "lexername":
  							_lexing_Language = reader.Value;
  							break;
  						case "linecommentprefix":
  							_lexing_LineCommentPrefix = reader.Value;
  							break;
  						case "streamcommentprefix":
  							_lexing_StreamCommentPrefix = reader.Value;
  							break;
  						case "streamcommentsuffix":
  							_lexing_StreamCommentSuffix = reader.Value;
  							break;
  					}
  				}
  				reader.MoveToElement();
  			}
  
  			if (!reader.IsEmptyElement)
  			{
  				reader.Read();
  				while (!(reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("lexer", StringComparison.OrdinalIgnoreCase)))
  				{
  					if (reader.NodeType == XmlNodeType.Element)
  					{
  						if (reader.Name.Equals("properties", StringComparison.OrdinalIgnoreCase))
  							readLexerProperties(reader);
  						else if (reader.Name.Equals("keywords", StringComparison.OrdinalIgnoreCase))
  							readLexerKeywords(reader);
  					}
  				}
  			}
  			reader.Read();
  		}
  
  		private void readLexerKeywords(XmlReader reader)
  		{
  			bool? inherit = null;
  			int? list = null;
  			string keywords = null;
  
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "inherit":
  							inherit = getBool(reader.Value);
  							break;
  						case "list":
  							list = getInt(reader.Value);
  							break;
  					}
  				}
  
  				reader.MoveToElement();
  			}
  			
  			if (!reader.IsEmptyElement)
  				keywords = reader.ReadString().Trim();
  
  			_lexing_Keywords.Add(new KeyWordConfig(list.Value, keywords, inherit));
  
  			reader.Read();
  		}
  
  		private void readLexerProperties(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  					if (reader.Name.ToLower() == "inherit")
  						_lexing_Properties.Inherit = getBool(reader.Value);
  
  				reader.MoveToElement();
  			}
  
  			if (!reader.IsEmptyElement)
  			{
  				while (!(reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("properties", StringComparison.OrdinalIgnoreCase)))
  				{
  					reader.Read();
  					if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals("property", StringComparison.OrdinalIgnoreCase))
  					{
  						if (reader.HasAttributes)
  						{
  							string name = string.Empty;
  							string value = string.Empty;
  							while (reader.MoveToNextAttribute())
  							{
  								string attrName = reader.Name.ToLower();
  								switch (attrName)
  								{
  									case "name":
  										name = reader.Value;
  										break;
  									case "value":
  										value = reader.Value;
  										break;
  								}
  							}
  							_lexing_Properties.Add(name, value);
  							reader.MoveToElement();
  						}
  					}
  				}
  			}
  
  			reader.Read();
  		}			
  		
  
  		private void readIndicators(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "inherit":
  							_indicator_List.Inherit = getBool(reader.Value);
  							break;
  					}
  				}
  				reader.MoveToElement();
  			}
  
  			if (!reader.IsEmptyElement)
  			{
  				while (!(reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("indicators", StringComparison.OrdinalIgnoreCase)))
  				{
  					reader.Read();
  					if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals("indicator", StringComparison.OrdinalIgnoreCase))
  					{
  						if (reader.HasAttributes)
  						{
  							IndicatorConfig ic = new IndicatorConfig();
  							while (reader.MoveToNextAttribute())
  							{
  								string attrName = reader.Name.ToLower();
  								switch (attrName)
  								{
  									case "number":
  										ic.Number = int.Parse(reader.Value);
  										break;
  									case "color":
  										ic.Color = getColor(reader.Value);
  										break;
  									case "inherit":
  										ic.Inherit = getBool(reader.Value);
  										break;
  									case "isdrawnunder":
  										ic.IsDrawnUnder = getBool(reader.Value);
  										break;
  									case "style":
  										ic.Style = (IndicatorStyle)Enum.Parse(typeof(IndicatorStyle), reader.Value, true);
  										break;
  								}
  							}
  							_indicator_List.Add(ic);
  							reader.MoveToElement();
  						}
  					}
  				}
  			}
  			reader.Read();
  		}
  
  		private void readIndentation(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "backspaceunindents":
  							_indentation_BackspaceUnindents = getBool(reader.Value);
  							break;
  						case "indentwidth":
  							_indentation_IndentWidth = getInt(reader.Value);
  							break;
  						case "showguides":
  							_indentation_ShowGuides = getBool(reader.Value);
  							break;
  						case "tabindents":
  							_indentation_TabIndents = getBool(reader.Value);
  							break;
  						case "tabwidth":
  							_indentation_TabWidth = getInt(reader.Value);
  							break;
  						case "usetabs":
  							_indentation_UseTabs = getBool(reader.Value);
  							break;
  						case "smartindenttype":
  							_indentation_SmartIndentType = (SmartIndent)Enum.Parse(typeof(SmartIndent), reader.Value, true);
  							break;
  					}
  				}
  
  				reader.MoveToElement();
  			}
  
  			reader.Skip();
  		}
  
  		private void readHotSpot(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "activebackcolor":
  							_hotspot_ActiveBackColor = getColor(reader.Value);
  							break;
  						case "activeforecolor":
  							_hotspot_ActiveForeColor = getColor(reader.Value);
  							break;
  						case "activeunderline":
  							_hotspot_ActiveUnderline = getBool(reader.Value);
  							break;
  						case "singleline":
  							_hotspot_SingleLine = getBool(reader.Value);
  							break;
  						case "useactivebackcolor":
  							_hotspot_UseActiveBackColor = getBool(reader.Value);
  							break;
  						case "useactiveforecolor":
  							_hotspot_UseActiveForeColor = getBool(reader.Value);
  							break;
  					}
  				}
  
  				reader.MoveToElement();
  			}
  
  			reader.Skip();
  		}
  
  		private void readFolding(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "flags":
  							string flags = reader.Value.Trim();
  							if (flags != string.Empty)
  							{
  								FoldFlag? ff = null;
  								foreach (string flag in flags.Split(' '))
  									ff |= (FoldFlag)Enum.Parse(typeof(FoldFlag), flag.Trim(), true);
  
  								if (ff.HasValue)
  									_folding_Flags = ff;
  							}
  							break;
  						case "IsEnabled":
  							_folding_MarkerScheme = (FoldMarkerScheme)Enum.Parse(typeof(FoldMarkerScheme), reader.Value, true);
  							break;
  						case "usecompactfolding":
  							_folding_UseCompactFolding = getBool(reader.Value);
  							break;
  					}
  				}
  
  				reader.MoveToElement();
  			}
  
  			reader.Skip();
  		}
  
  		private void readEndOfLine(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "convertonpaste":
  							_endOfLine_ConvertOnPaste = getBool(reader.Value);
  							break;
  						case "isvisible":
  							_endOfLine_IsVisisble = getBool(reader.Value);
  							break;
  						case "mode":					
  							_endOfLine_Mode = (EndOfLineMode)Enum.Parse(typeof(EndOfLineMode), reader.Value, true);
  							break;
  					}
  				}
  
  				reader.MoveToElement();
  			}
  
  			reader.Skip();
  		}
  
  		private void readCommands(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "Inherit":
  							_commands_KeyBindingList.Inherit = getBool(reader.Value);
  							break;
  						case "AllowDuplicateBindings":
  							_commands_KeyBindingList.AllowDuplicateBindings = getBool(reader.Value);
  							break;
  					}
  				}
  
  				reader.MoveToElement();
  			}
  
  			if (!reader.IsEmptyElement)
  			{
  				while (!(reader.NodeType == XmlNodeType.EndElement && reader.Name.Equals("commands", StringComparison.OrdinalIgnoreCase)))
  				{
  					reader.Read();
  					if (reader.NodeType == XmlNodeType.Element && reader.Name.Equals("binding", StringComparison.OrdinalIgnoreCase))
  					{
  						if (reader.HasAttributes)
  						{
  							KeyBinding kb = new KeyBinding();
  							BindableCommand cmd = new BindableCommand();
  							bool? replaceCurrent = null;
  
  							while (reader.MoveToNextAttribute())
  							{
  								string attrName = reader.Name.ToLower();
  								switch (attrName)
  								{
  									case "key":
  										kb.KeyCode = Utilities.GetKeys(reader.Value);
  										break;
  									case "modifier":
  										if (reader.Value != string.Empty)
  										{
  											foreach (string modifier in reader.Value.Split(' '))
  												kb.Modifiers |= (Keys)Enum.Parse(typeof(Keys), modifier.Trim(), true);
  										}
  										break;
  									case "command":
  										cmd = (BindableCommand)Enum.Parse(typeof(BindableCommand), reader.Value, true);
  										break;
  									case "replacecurrent":
  										replaceCurrent = getBool(reader.Value);
  										break;
  								}
  							}
  
  							_commands_KeyBindingList.Add(new CommandBindingConfig(kb, replaceCurrent, cmd));
  						}
  
  						reader.MoveToElement();
  					}
  				}
  			}
  			reader.Read();
  		}
  
  		private void readClipboard(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "convertendoflineonpaste":
  							_clipboard_ConvertEndOfLineOnPaste = getBool(reader.Value);
  							break;
  					}
  				}
  				reader.MoveToElement();
  			}
  			reader.Skip();
  		}
  
  		private void readCaret(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "blinkrate":
  							//	This guy is a bit of an oddball becuase null means "I don't Care"
  							//	and we need some way of using the OS value.
  							string blinkRate = reader.Value;
  							if (blinkRate.ToLower() == "system")
  								_caret_BlinkRate = SystemInformation.CaretBlinkTime;
  							else
  								_caret_BlinkRate = getInt(blinkRate);
  							break;
  						case "color":
  							_caret_Color = getColor(reader.Value);
  							break;
  						case "currentlinebackgroundalpha":
  							_caret_CurrentLineBackgroundAlpha = getInt(reader.Value);
  							break;
  						case "currentlinebackgroundcolor":
  							_caret_CurrentLineBackgroundColor = getColor(reader.Value);
  							break;
  						case "highlightcurrentline":
  							_caret_HighlightCurrentLine = getBool(reader.Value);
  							break;
  						case "issticky":
  							_caret_IsSticky = getBool(reader.Value);
  							break;
  						case "style":
  							_caret_Style = (CaretStyle)Enum.Parse(typeof(CaretStyle), reader.Value, true);
  							break;
  						case "width":
  							_caret_Width = getInt(reader.Value);
  							break;
  					}
  				}
  				reader.MoveToElement();
  			}
  			reader.Skip();
  		}
  
  		private void readCallTip(XmlReader reader)
  		{
  			if (reader.HasAttributes)
  			{
  				while (reader.MoveToNextAttribute())
  				{
  					string attrName = reader.Name.ToLower();
  					switch (attrName)
  					{
  						case "backcolor":
  							_callTip_BackColor = getColor(reader.Value);
  							break;
  						case "forecolor":
  
gt: 							_callTip_ForeColor = getColor(reader.Value);