From 906253d37f1b4f9bcd36490a3abfaa522ae28514 Mon Sep 17 00:00:00 2001
From: Daniel Grunwald <daniel@danielgrunwald.de>
Date: Wed, 24 May 2006 19:18:59 +0000
Subject: [PATCH] Add NRefactory demo application.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1418 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
---
 samples/NRefactoryDemo/AssemblyInfo.cs        |  27 ++
 samples/NRefactoryDemo/AstView.Designer.cs    |  62 ++++
 samples/NRefactoryDemo/AstView.cs             | 227 +++++++++++++
 samples/NRefactoryDemo/AstView.resx           | 120 +++++++
 samples/NRefactoryDemo/EditDialog.Designer.cs |  91 ++++++
 samples/NRefactoryDemo/EditDialog.cs          |  22 ++
 samples/NRefactoryDemo/EditDialog.resx        | 120 +++++++
 samples/NRefactoryDemo/MainForm.Designer.cs   | 305 ++++++++++++++++++
 samples/NRefactoryDemo/MainForm.cs            | 135 ++++++++
 samples/NRefactoryDemo/MainForm.resx          | 120 +++++++
 samples/NRefactoryDemo/NRefactoryDemo.csproj  |  66 ++++
 samples/NRefactoryDemo/NRefactoryDemo.sln     |  16 +
 .../OverlayIconManager.cs                     |  24 +-
 .../Project/SubversionAddIn.csproj            |   3 +-
 .../Gui/Editor/AdvancedHighlighter.cs         |   6 +-
 .../Editor/AdvancedHighlightingStrategy.cs    |   5 -
 .../Src/TextEditor/Gui/Editor/ErrorDrawer.cs  |   7 +-
 .../Gui/Editor/ParserFoldingStrategy.cs       |   2 -
 .../Gui/Editor/QuickClassBrowserPanel.cs      |   6 +-
 .../SharpDevelopTextEditorProperties.cs       |   4 +-
 .../Gui/Editor/TextEditorDisplayBinding.cs    |  10 +-
 .../ResourceService/ResourceService.cs        |  10 +-
 22 files changed, 1341 insertions(+), 47 deletions(-)
 create mode 100644 samples/NRefactoryDemo/AssemblyInfo.cs
 create mode 100644 samples/NRefactoryDemo/AstView.Designer.cs
 create mode 100644 samples/NRefactoryDemo/AstView.cs
 create mode 100644 samples/NRefactoryDemo/AstView.resx
 create mode 100644 samples/NRefactoryDemo/EditDialog.Designer.cs
 create mode 100644 samples/NRefactoryDemo/EditDialog.cs
 create mode 100644 samples/NRefactoryDemo/EditDialog.resx
 create mode 100644 samples/NRefactoryDemo/MainForm.Designer.cs
 create mode 100644 samples/NRefactoryDemo/MainForm.cs
 create mode 100644 samples/NRefactoryDemo/MainForm.resx
 create mode 100644 samples/NRefactoryDemo/NRefactoryDemo.csproj
 create mode 100644 samples/NRefactoryDemo/NRefactoryDemo.sln

diff --git a/samples/NRefactoryDemo/AssemblyInfo.cs b/samples/NRefactoryDemo/AssemblyInfo.cs
new file mode 100644
index 0000000000..78d62092a8
--- /dev/null
+++ b/samples/NRefactoryDemo/AssemblyInfo.cs
@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following
+// attributes.
+//
+// change them to the information which is associated with the assembly
+// you compile.
+
+[assembly: AssemblyTitle("NRefactory Demo")]
+[assembly: AssemblyDescription("Graphical application to demonstrate NRefactory")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("icsharpcode.net")]
+[assembly: AssemblyProduct("SharpDevelop")]
+[assembly: AssemblyCopyright("2006, Daniel Grunwald")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has following format :
+//
+// Major.Minor.Build.Revision
+//
+// You can specify all values by your own or you can build default build and revision
+// numbers with the '*' character (the default):
+
+[assembly: AssemblyVersion("1.0.*")]
+
diff --git a/samples/NRefactoryDemo/AstView.Designer.cs b/samples/NRefactoryDemo/AstView.Designer.cs
new file mode 100644
index 0000000000..72ed6913e7
--- /dev/null
+++ b/samples/NRefactoryDemo/AstView.Designer.cs
@@ -0,0 +1,62 @@
+/*
+ * Created by SharpDevelop.
+ * User: Daniel Grunwald
+ * Date: ${DATE}
+ * Time: ${TIME}
+ */
+namespace NRefactoryDemo
+{
+	partial class AstView : System.Windows.Forms.UserControl
+	{
+		/// <summary>
+		/// Designer variable used to keep track of non-visual components.
+		/// </summary>
+		private System.ComponentModel.IContainer components = null;
+		
+		/// <summary>
+		/// Disposes resources used by the control.
+		/// </summary>
+		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+		protected override void Dispose(bool disposing)
+		{
+			if (disposing) {
+				if (components != null) {
+					components.Dispose();
+				}
+			}
+			base.Dispose(disposing);
+		}
+		
+		/// <summary>
+		/// This method is required for Windows Forms designer support.
+		/// Do not change the method contents inside the source code editor. The Forms designer might
+		/// not be able to load this method if it was changed manually.
+		/// </summary>
+		private void InitializeComponent()
+		{
+			this.tree = new System.Windows.Forms.TreeView();
+			this.SuspendLayout();
+			// 
+			// tree
+			// 
+			this.tree.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.tree.HideSelection = false;
+			this.tree.Location = new System.Drawing.Point(0, 0);
+			this.tree.Name = "tree";
+			this.tree.ShowRootLines = false;
+			this.tree.Size = new System.Drawing.Size(186, 182);
+			this.tree.TabIndex = 0;
+			this.tree.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TreeKeyDown);
+			// 
+			// AstView
+			// 
+			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+			this.Controls.Add(this.tree);
+			this.Name = "AstView";
+			this.Size = new System.Drawing.Size(186, 182);
+			this.ResumeLayout(false);
+		}
+		private System.Windows.Forms.TreeView tree;
+	}
+}
diff --git a/samples/NRefactoryDemo/AstView.cs b/samples/NRefactoryDemo/AstView.cs
new file mode 100644
index 0000000000..63cd60293d
--- /dev/null
+++ b/samples/NRefactoryDemo/AstView.cs
@@ -0,0 +1,227 @@
+/*
+ * Created by SharpDevelop.
+ * User: Daniel Grunwald
+ * Date: 07.05.2006
+ * Time: 18:25
+ */
+
+using System;
+using System.Collections;
+using System.Windows.Forms;
+using System.Reflection;
+
+using ICSharpCode.NRefactory.Parser.AST;
+using ICSharpCode.NRefactory.Parser;
+
+namespace NRefactoryDemo
+{
+	public partial class AstView
+	{
+		CompilationUnit unit;
+		
+		public CompilationUnit Unit {
+			get {
+				return unit;
+			}
+			set {
+				unit = value;
+				UpdateTree();
+			}
+		}
+		
+		void UpdateTree()
+		{
+			tree.Nodes.Clear();
+			tree.Nodes.Add(new CollectionNode("CompilationUnit", unit.Children));
+			tree.SelectedNode = tree.Nodes[0];
+		}
+		
+		public AstView()
+		{
+			InitializeComponent();
+		}
+		
+		public void DeleteSelectedNode()
+		{
+			if (tree.SelectedNode is ElementNode) {
+				INode element = (tree.SelectedNode as ElementNode).element;
+				if (tree.SelectedNode.Parent is CollectionNode) {
+					if (MessageBox.Show("Remove selected node from parent collection?", "Remove node", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+					    == DialogResult.Yes)
+					{
+						IList col = (tree.SelectedNode.Parent as CollectionNode).collection;
+						col.Remove(element);
+						(tree.SelectedNode.Parent as CollectionNode).Update();
+					}
+				} else if (tree.SelectedNode.Parent is ElementNode) {
+					if (MessageBox.Show("Set selected property to null?", "Remove node", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+					    == DialogResult.Yes)
+					{
+						// get parent element
+						element = (tree.SelectedNode.Parent as ElementNode).element;
+						string propertyName = (string)tree.SelectedNode.Tag;
+						element.GetType().GetProperty(propertyName).SetValue(element, null, null);
+						(tree.SelectedNode.Parent as ElementNode).Update();
+					}
+				}
+			} else if (tree.SelectedNode is CollectionNode) {
+				if (MessageBox.Show("Remove all elements from selected collection?", "Clear collection", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+				    == DialogResult.Yes)
+				{
+					IList col = (tree.SelectedNode as CollectionNode).collection;
+					col.Clear();
+					(tree.SelectedNode as CollectionNode).Update();
+				}
+			}
+		}
+		
+		public void EditSelectedNode()
+		{
+			TreeNode node = tree.SelectedNode;
+			while (!(node is ElementNode)) {
+				if (node == null) {
+					return;
+				}
+				node = node.Parent;
+			}
+			INode element = ((ElementNode)node).element;
+			using (EditDialog dlg = new EditDialog(element)) {
+				dlg.ShowDialog();
+			}
+			((ElementNode)node).Update();
+		}
+		
+		public void ApplyTransformation(IAstVisitor visitor)
+		{
+			if (tree.SelectedNode == tree.Nodes[0]) {
+				visitor.Visit(unit, null);
+				UpdateTree();
+			} else {
+				string name = visitor.GetType().Name;
+				ElementNode elementNode = tree.SelectedNode as ElementNode;
+				CollectionNode collectionNode = tree.SelectedNode as CollectionNode;
+				if (elementNode != null) {
+					if (MessageBox.Show(("Apply " + name + " to selected element '" + elementNode.Text + "'?"),
+					                    "Apply transformation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+					    == DialogResult.Yes)
+					{
+						elementNode.element.AcceptVisitor(visitor, null);
+						elementNode.Update();
+					}
+				} else if (collectionNode != null) {
+					if (MessageBox.Show(("Apply " + name + " to all elements in selected collection '" + collectionNode.Text + "'?"),
+					                    "Apply transformation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
+					    == DialogResult.Yes)
+					{
+						foreach (TreeNode subNode in collectionNode.Nodes) {
+							if (subNode is ElementNode) {
+								(subNode as ElementNode).element.AcceptVisitor(visitor, null);
+							}
+						}
+						collectionNode.Update();
+					}
+				}
+			}
+		}
+		
+		static TreeNode CreateNode(object child)
+		{
+			if (child == null) {
+				return new TreeNode("*null reference*");
+			} else if (child is INode) {
+				return new ElementNode(child as INode);
+			} else {
+				return new TreeNode(child.ToString());
+			}
+		}
+		
+		class CollectionNode : TreeNode
+		{
+			internal IList collection;
+			string baseName;
+			
+			public CollectionNode(string text, IList children) : base(text)
+			{
+				this.baseName = text;
+				this.collection = children;
+				Update();
+			}
+			
+			public void Update()
+			{
+				if (collection.Count == 0) {
+					Text = baseName + " (empty collection)";
+				} else if (collection.Count == 1) {
+					Text = baseName + " (collection with 1 element)";
+				} else {
+					Text = baseName + " (collection with " + collection.Count + " elements)";
+				}
+				Nodes.Clear();
+				foreach (object child in collection) {
+					Nodes.Add(CreateNode(child));
+				}
+				Expand();
+			}
+		}
+		
+		class ElementNode : TreeNode
+		{
+			internal INode element;
+			
+			public ElementNode(INode node)
+			{
+				this.element = node;
+				Update();
+			}
+			
+			public void Update()
+			{
+				Nodes.Clear();
+				Type type = element.GetType();
+				Text = type.Name;
+				if (Tag != null) { // HACK: after editing property element
+					Text = Tag.ToString() + " = " + Text;
+				}
+				if (!(element is INullable && (element as INullable).IsNull)) {
+					AddProperties(type, element);
+					if (element.Children.Count > 0) {
+						Nodes.Add(new CollectionNode("Children", element.Children));
+					}
+				}
+			}
+			
+			void AddProperties(Type type, INode node)
+			{
+				if (type == typeof(AbstractNode))
+					return;
+				foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)) {
+					if (pi.DeclaringType != type) // don't add derived properties
+						continue;
+					if (pi.Name == "IsNull")
+						continue;
+					object value = pi.GetValue(node, null);
+					if (value is IList) {
+						Nodes.Add(new CollectionNode(pi.Name, (IList)value));
+					} else if (value is string) {
+						Text += " " + pi.Name + "='" + value + "'";
+					} else {
+						TreeNode treeNode = CreateNode(value);
+						treeNode.Text = pi.Name + " = " + treeNode.Text;
+						treeNode.Tag = pi.Name;
+						Nodes.Add(treeNode);
+					}
+				}
+				AddProperties(type.BaseType, node);
+			}
+		}
+		
+		void TreeKeyDown(object sender, KeyEventArgs e)
+		{
+			if (e.KeyData == Keys.Delete) {
+				DeleteSelectedNode();
+			} else if (e.KeyData == Keys.Space || e.KeyData == Keys.Enter) {
+				EditSelectedNode();
+			}
+		}
+	}
+}
diff --git a/samples/NRefactoryDemo/AstView.resx b/samples/NRefactoryDemo/AstView.resx
new file mode 100644
index 0000000000..7080a7d118
--- /dev/null
+++ b/samples/NRefactoryDemo/AstView.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/samples/NRefactoryDemo/EditDialog.Designer.cs b/samples/NRefactoryDemo/EditDialog.Designer.cs
new file mode 100644
index 0000000000..434fe29222
--- /dev/null
+++ b/samples/NRefactoryDemo/EditDialog.Designer.cs
@@ -0,0 +1,91 @@
+/*
+ * Created by SharpDevelop.
+ * User: Daniel Grunwald
+ * Date: ${DATE}
+ * Time: ${TIME}
+ */
+namespace NRefactoryDemo
+{
+	partial class EditDialog : System.Windows.Forms.Form
+	{
+		/// <summary>
+		/// Designer variable used to keep track of non-visual components.
+		/// </summary>
+		private System.ComponentModel.IContainer components = null;
+		
+		/// <summary>
+		/// Disposes resources used by the form.
+		/// </summary>
+		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+		protected override void Dispose(bool disposing)
+		{
+			if (disposing) {
+				if (components != null) {
+					components.Dispose();
+				}
+			}
+			base.Dispose(disposing);
+		}
+		
+		/// <summary>
+		/// This method is required for Windows Forms designer support.
+		/// Do not change the method contents inside the source code editor. The Forms designer might
+		/// not be able to load this method if it was changed manually.
+		/// </summary>
+		private void InitializeComponent()
+		{
+			this.propertyGrid = new System.Windows.Forms.PropertyGrid();
+			this.panel1 = new System.Windows.Forms.Panel();
+			this.okButton = new System.Windows.Forms.Button();
+			this.panel1.SuspendLayout();
+			this.SuspendLayout();
+			// 
+			// propertyGrid
+			// 
+			this.propertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.propertyGrid.HelpVisible = false;
+			this.propertyGrid.Location = new System.Drawing.Point(0, 0);
+			this.propertyGrid.Name = "propertyGrid";
+			this.propertyGrid.PropertySort = System.Windows.Forms.PropertySort.Alphabetical;
+			this.propertyGrid.Size = new System.Drawing.Size(477, 436);
+			this.propertyGrid.TabIndex = 0;
+			this.propertyGrid.ToolbarVisible = false;
+			// 
+			// panel1
+			// 
+			this.panel1.Controls.Add(this.okButton);
+			this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
+			this.panel1.Location = new System.Drawing.Point(0, 436);
+			this.panel1.Name = "panel1";
+			this.panel1.Size = new System.Drawing.Size(477, 38);
+			this.panel1.TabIndex = 1;
+			// 
+			// okButton
+			// 
+			this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+			this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+			this.okButton.Location = new System.Drawing.Point(390, 6);
+			this.okButton.Name = "okButton";
+			this.okButton.Size = new System.Drawing.Size(75, 23);
+			this.okButton.TabIndex = 0;
+			this.okButton.Text = "OK";
+			this.okButton.UseVisualStyleBackColor = true;
+			// 
+			// EditDialog
+			// 
+			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+			this.CancelButton = this.okButton;
+			this.ClientSize = new System.Drawing.Size(477, 474);
+			this.Controls.Add(this.propertyGrid);
+			this.Controls.Add(this.panel1);
+			this.Name = "EditDialog";
+			this.Text = "EditDialog";
+			this.panel1.ResumeLayout(false);
+			this.ResumeLayout(false);
+		}
+		private System.Windows.Forms.PropertyGrid propertyGrid;
+		private System.Windows.Forms.Button okButton;
+		private System.Windows.Forms.Panel panel1;
+	}
+}
diff --git a/samples/NRefactoryDemo/EditDialog.cs b/samples/NRefactoryDemo/EditDialog.cs
new file mode 100644
index 0000000000..cd3f653e73
--- /dev/null
+++ b/samples/NRefactoryDemo/EditDialog.cs
@@ -0,0 +1,22 @@
+/*
+ * Created by SharpDevelop.
+ * User: Daniel Grunwald
+ * Date: 07.05.2006
+ * Time: 19:57
+ */
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace NRefactoryDemo
+{
+	public partial class EditDialog
+	{
+		public EditDialog(object element)
+		{
+			InitializeComponent();
+			propertyGrid.SelectedObject = element;
+		}
+	}
+}
diff --git a/samples/NRefactoryDemo/EditDialog.resx b/samples/NRefactoryDemo/EditDialog.resx
new file mode 100644
index 0000000000..7080a7d118
--- /dev/null
+++ b/samples/NRefactoryDemo/EditDialog.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/samples/NRefactoryDemo/MainForm.Designer.cs b/samples/NRefactoryDemo/MainForm.Designer.cs
new file mode 100644
index 0000000000..cb051b1733
--- /dev/null
+++ b/samples/NRefactoryDemo/MainForm.Designer.cs
@@ -0,0 +1,305 @@
+/*
+ * Created by SharpDevelop.
+ * User: Daniel Grunwald
+ * Date: 07.05.2006
+ * Time: 18:09
+ */
+namespace NRefactoryDemo
+{
+	partial class MainForm : System.Windows.Forms.Form
+	{
+		/// <summary>
+		/// Designer variable used to keep track of non-visual components.
+		/// </summary>
+		private System.ComponentModel.IContainer components = null;
+		
+		/// <summary>
+		/// Disposes resources used by the form.
+		/// </summary>
+		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+		protected override void Dispose(bool disposing)
+		{
+			if (disposing) {
+				if (components != null) {
+					components.Dispose();
+				}
+			}
+			base.Dispose(disposing);
+		}
+		
+		/// <summary>
+		/// This method is required for Windows Forms designer support.
+		/// Do not change the method contents inside the source code editor. The Forms designer might
+		/// not be able to load this method if it was changed manually.
+		/// </summary>
+		private void InitializeComponent()
+		{
+			this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+			this.codeTextBox = new System.Windows.Forms.TextBox();
+			this.astPanel = new System.Windows.Forms.Panel();
+			this.groupBox2 = new System.Windows.Forms.GroupBox();
+			this.transformationComboBox = new System.Windows.Forms.ComboBox();
+			this.applyTransformation = new System.Windows.Forms.Button();
+			this.deleteSelectedNode = new System.Windows.Forms.Button();
+			this.panel1 = new System.Windows.Forms.Panel();
+			this.arrowUpPictureBox = new System.Windows.Forms.PictureBox();
+			this.arrowDownPictureBox = new System.Windows.Forms.PictureBox();
+			this.groupBox1 = new System.Windows.Forms.GroupBox();
+			this.clearSpecialsButton = new System.Windows.Forms.Button();
+			this.specialsLabel = new System.Windows.Forms.Label();
+			this.generateVBButton = new System.Windows.Forms.Button();
+			this.parseVBButton = new System.Windows.Forms.Button();
+			this.generateCSharpButton = new System.Windows.Forms.Button();
+			this.parseCSharpButton = new System.Windows.Forms.Button();
+			this.editNodeButton = new System.Windows.Forms.Button();
+			this.splitContainer1.Panel1.SuspendLayout();
+			this.splitContainer1.Panel2.SuspendLayout();
+			this.splitContainer1.SuspendLayout();
+			this.groupBox2.SuspendLayout();
+			this.panel1.SuspendLayout();
+			((System.ComponentModel.ISupportInitialize)(this.arrowUpPictureBox)).BeginInit();
+			((System.ComponentModel.ISupportInitialize)(this.arrowDownPictureBox)).BeginInit();
+			this.groupBox1.SuspendLayout();
+			this.SuspendLayout();
+			// 
+			// splitContainer1
+			// 
+			this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+			this.splitContainer1.Name = "splitContainer1";
+			this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+			// 
+			// splitContainer1.Panel1
+			// 
+			this.splitContainer1.Panel1.Controls.Add(this.codeTextBox);
+			this.splitContainer1.Panel1MinSize = 50;
+			// 
+			// splitContainer1.Panel2
+			// 
+			this.splitContainer1.Panel2.Controls.Add(this.astPanel);
+			this.splitContainer1.Panel2.Controls.Add(this.groupBox2);
+			this.splitContainer1.Panel2.Controls.Add(this.panel1);
+			this.splitContainer1.Panel2MinSize = 150;
+			this.splitContainer1.Size = new System.Drawing.Size(512, 411);
+			this.splitContainer1.SplitterDistance = 146;
+			this.splitContainer1.TabIndex = 0;
+			// 
+			// codeTextBox
+			// 
+			this.codeTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.codeTextBox.Location = new System.Drawing.Point(0, 0);
+			this.codeTextBox.Multiline = true;
+			this.codeTextBox.Name = "codeTextBox";
+			this.codeTextBox.Size = new System.Drawing.Size(512, 146);
+			this.codeTextBox.TabIndex = 0;
+			this.codeTextBox.Text = "using System;\r\nclass MainClass\r\n{\r\n  // This is the entry method of the applicati" +
+			"on\r\n  public static void Main()\r\n  {\r\n    Console.WriteLine(\"Hello, World!\");\r\n " +
+			" }\r\n}";
+			// 
+			// astPanel
+			// 
+			this.astPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+			this.astPanel.Location = new System.Drawing.Point(128, 60);
+			this.astPanel.Name = "astPanel";
+			this.astPanel.Size = new System.Drawing.Size(384, 201);
+			this.astPanel.TabIndex = 2;
+			// 
+			// groupBox2
+			// 
+			this.groupBox2.Controls.Add(this.transformationComboBox);
+			this.groupBox2.Controls.Add(this.applyTransformation);
+			this.groupBox2.Controls.Add(this.editNodeButton);
+			this.groupBox2.Controls.Add(this.deleteSelectedNode);
+			this.groupBox2.Dock = System.Windows.Forms.DockStyle.Left;
+			this.groupBox2.Location = new System.Drawing.Point(0, 60);
+			this.groupBox2.Name = "groupBox2";
+			this.groupBox2.Size = new System.Drawing.Size(128, 201);
+			this.groupBox2.TabIndex = 1;
+			this.groupBox2.TabStop = false;
+			this.groupBox2.Text = "Apply transformations";
+			// 
+			// transformationComboBox
+			// 
+			this.transformationComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+			this.transformationComboBox.DropDownWidth = 200;
+			this.transformationComboBox.FormattingEnabled = true;
+			this.transformationComboBox.Items.AddRange(new object[] {
+									"CSharpConstructsVisitor",
+									"ToVBNetConvertVisitor",
+									"VBNetConstructsConvertVisitor",
+									"ToCSharpConvertVisitor"});
+			this.transformationComboBox.Location = new System.Drawing.Point(9, 78);
+			this.transformationComboBox.Name = "transformationComboBox";
+			this.transformationComboBox.Size = new System.Drawing.Size(112, 21);
+			this.transformationComboBox.TabIndex = 2;
+			// 
+			// applyTransformation
+			// 
+			this.applyTransformation.Location = new System.Drawing.Point(25, 105);
+			this.applyTransformation.Name = "applyTransformation";
+			this.applyTransformation.Size = new System.Drawing.Size(96, 23);
+			this.applyTransformation.TabIndex = 3;
+			this.applyTransformation.Text = "Run visitor";
+			this.applyTransformation.UseVisualStyleBackColor = true;
+			this.applyTransformation.Click += new System.EventHandler(this.ApplyTransformationClick);
+			// 
+			// deleteSelectedNode
+			// 
+			this.deleteSelectedNode.Location = new System.Drawing.Point(9, 20);
+			this.deleteSelectedNode.Name = "deleteSelectedNode";
+			this.deleteSelectedNode.Size = new System.Drawing.Size(110, 23);
+			this.deleteSelectedNode.TabIndex = 0;
+			this.deleteSelectedNode.Text = "Delete node";
+			this.deleteSelectedNode.UseVisualStyleBackColor = true;
+			this.deleteSelectedNode.Click += new System.EventHandler(this.DeleteSelectedNodeClick);
+			// 
+			// panel1
+			// 
+			this.panel1.Controls.Add(this.arrowUpPictureBox);
+			this.panel1.Controls.Add(this.arrowDownPictureBox);
+			this.panel1.Controls.Add(this.groupBox1);
+			this.panel1.Controls.Add(this.generateVBButton);
+			this.panel1.Controls.Add(this.parseVBButton);
+			this.panel1.Controls.Add(this.generateCSharpButton);
+			this.panel1.Controls.Add(this.parseCSharpButton);
+			this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
+			this.panel1.Location = new System.Drawing.Point(0, 0);
+			this.panel1.Name = "panel1";
+			this.panel1.Size = new System.Drawing.Size(512, 60);
+			this.panel1.TabIndex = 0;
+			// 
+			// arrowUpPictureBox
+			// 
+			this.arrowUpPictureBox.Location = new System.Drawing.Point(404, 3);
+			this.arrowUpPictureBox.Name = "arrowUpPictureBox";
+			this.arrowUpPictureBox.Size = new System.Drawing.Size(29, 54);
+			this.arrowUpPictureBox.TabIndex = 2;
+			this.arrowUpPictureBox.TabStop = false;
+			this.arrowUpPictureBox.Paint += new System.Windows.Forms.PaintEventHandler(this.ArrowUpPictureBoxPaint);
+			// 
+			// arrowDownPictureBox
+			// 
+			this.arrowDownPictureBox.Location = new System.Drawing.Point(123, 3);
+			this.arrowDownPictureBox.Name = "arrowDownPictureBox";
+			this.arrowDownPictureBox.Size = new System.Drawing.Size(29, 54);
+			this.arrowDownPictureBox.TabIndex = 2;
+			this.arrowDownPictureBox.TabStop = false;
+			this.arrowDownPictureBox.Paint += new System.Windows.Forms.PaintEventHandler(this.ArrowDownPictureBoxPaint);
+			// 
+			// groupBox1
+			// 
+			this.groupBox1.Controls.Add(this.clearSpecialsButton);
+			this.groupBox1.Controls.Add(this.specialsLabel);
+			this.groupBox1.Location = new System.Drawing.Point(3, -2);
+			this.groupBox1.Name = "groupBox1";
+			this.groupBox1.Size = new System.Drawing.Size(114, 59);
+			this.groupBox1.TabIndex = 4;
+			this.groupBox1.TabStop = false;
+			// 
+			// clearSpecialsButton
+			// 
+			this.clearSpecialsButton.Location = new System.Drawing.Point(31, 30);
+			this.clearSpecialsButton.Name = "clearSpecialsButton";
+			this.clearSpecialsButton.Size = new System.Drawing.Size(75, 23);
+			this.clearSpecialsButton.TabIndex = 1;
+			this.clearSpecialsButton.Text = "Clear";
+			this.clearSpecialsButton.UseVisualStyleBackColor = true;
+			this.clearSpecialsButton.Click += new System.EventHandler(this.ClearSpecialsButtonClick);
+			// 
+			// specialsLabel
+			// 
+			this.specialsLabel.Location = new System.Drawing.Point(6, 16);
+			this.specialsLabel.Name = "specialsLabel";
+			this.specialsLabel.Size = new System.Drawing.Size(100, 23);
+			this.specialsLabel.TabIndex = 0;
+			this.specialsLabel.Text = "# specials saved";
+			// 
+			// generateVBButton
+			// 
+			this.generateVBButton.Location = new System.Drawing.Point(281, 31);
+			this.generateVBButton.Name = "generateVBButton";
+			this.generateVBButton.Size = new System.Drawing.Size(117, 23);
+			this.generateVBButton.TabIndex = 3;
+			this.generateVBButton.Text = "Generate VB code";
+			this.generateVBButton.UseVisualStyleBackColor = true;
+			this.generateVBButton.Click += new System.EventHandler(this.GenerateVBButtonClick);
+			// 
+			// parseVBButton
+			// 
+			this.parseVBButton.Location = new System.Drawing.Point(158, 31);
+			this.parseVBButton.Name = "parseVBButton";
+			this.parseVBButton.Size = new System.Drawing.Size(117, 23);
+			this.parseVBButton.TabIndex = 1;
+			this.parseVBButton.Text = "Parse VB code";
+			this.parseVBButton.UseVisualStyleBackColor = true;
+			this.parseVBButton.Click += new System.EventHandler(this.ParseVBButtonClick);
+			// 
+			// generateCSharpButton
+			// 
+			this.generateCSharpButton.Location = new System.Drawing.Point(281, 6);
+			this.generateCSharpButton.Name = "generateCSharpButton";
+			this.generateCSharpButton.Size = new System.Drawing.Size(117, 23);
+			this.generateCSharpButton.TabIndex = 2;
+			this.generateCSharpButton.Text = "Generate C# code";
+			this.generateCSharpButton.UseVisualStyleBackColor = true;
+			this.generateCSharpButton.Click += new System.EventHandler(this.GenerateCSharpButtonClick);
+			// 
+			// parseCSharpButton
+			// 
+			this.parseCSharpButton.Location = new System.Drawing.Point(158, 6);
+			this.parseCSharpButton.Name = "parseCSharpButton";
+			this.parseCSharpButton.Size = new System.Drawing.Size(117, 23);
+			this.parseCSharpButton.TabIndex = 0;
+			this.parseCSharpButton.Text = "Parse C# code";
+			this.parseCSharpButton.UseVisualStyleBackColor = true;
+			this.parseCSharpButton.Click += new System.EventHandler(this.ParseCSharpButtonClick);
+			// 
+			// editNodeButton
+			// 
+			this.editNodeButton.Location = new System.Drawing.Point(9, 49);
+			this.editNodeButton.Name = "editNodeButton";
+			this.editNodeButton.Size = new System.Drawing.Size(110, 23);
+			this.editNodeButton.TabIndex = 1;
+			this.editNodeButton.Text = "Edit node";
+			this.editNodeButton.UseVisualStyleBackColor = true;
+			this.editNodeButton.Click += new System.EventHandler(this.EditNodeButtonClick);
+			// 
+			// MainForm
+			// 
+			this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+			this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+			this.ClientSize = new System.Drawing.Size(512, 411);
+			this.Controls.Add(this.splitContainer1);
+			this.Name = "MainForm";
+			this.Text = "NRefactoryDemo";
+			this.splitContainer1.Panel1.ResumeLayout(false);
+			this.splitContainer1.Panel1.PerformLayout();
+			this.splitContainer1.Panel2.ResumeLayout(false);
+			this.splitContainer1.ResumeLayout(false);
+			this.groupBox2.ResumeLayout(false);
+			this.panel1.ResumeLayout(false);
+			((System.ComponentModel.ISupportInitialize)(this.arrowUpPictureBox)).EndInit();
+			((System.ComponentModel.ISupportInitialize)(this.arrowDownPictureBox)).EndInit();
+			this.groupBox1.ResumeLayout(false);
+			this.ResumeLayout(false);
+		}
+		private System.Windows.Forms.Button editNodeButton;
+		private System.Windows.Forms.ComboBox transformationComboBox;
+		private System.Windows.Forms.Button applyTransformation;
+		private System.Windows.Forms.Button deleteSelectedNode;
+		private System.Windows.Forms.Panel astPanel;
+		private System.Windows.Forms.GroupBox groupBox2;
+		private System.Windows.Forms.Button parseCSharpButton;
+		private System.Windows.Forms.Button generateCSharpButton;
+		private System.Windows.Forms.Button parseVBButton;
+		private System.Windows.Forms.Button generateVBButton;
+		private System.Windows.Forms.PictureBox arrowUpPictureBox;
+		private System.Windows.Forms.PictureBox arrowDownPictureBox;
+		private System.Windows.Forms.Label specialsLabel;
+		private System.Windows.Forms.Button clearSpecialsButton;
+		private System.Windows.Forms.GroupBox groupBox1;
+		private System.Windows.Forms.Panel panel1;
+		private System.Windows.Forms.TextBox codeTextBox;
+		private System.Windows.Forms.SplitContainer splitContainer1;
+	}
+}
diff --git a/samples/NRefactoryDemo/MainForm.cs b/samples/NRefactoryDemo/MainForm.cs
new file mode 100644
index 0000000000..e52c1e34b2
--- /dev/null
+++ b/samples/NRefactoryDemo/MainForm.cs
@@ -0,0 +1,135 @@
+/*
+ * Created by SharpDevelop.
+ * User: Daniel Grunwald
+ * Date: 07.05.2006
+ * Time: 18:09
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Windows.Forms;
+
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.PrettyPrinter;
+
+namespace NRefactoryDemo
+{
+	/// <summary>
+	/// Graphical application to demonstrate NRefactory.
+	/// </summary>
+	public partial class MainForm
+	{
+		[STAThread]
+		public static void Main(string[] args)
+		{
+			Application.EnableVisualStyles();
+			Application.SetCompatibleTextRenderingDefault(false);
+			Application.Run(new MainForm());
+		}
+		
+		AstView astView = new AstView();
+		
+		public MainForm()
+		{
+			// The InitializeComponent() call is required for Windows Forms designer support.
+			InitializeComponent();
+			astView.Dock = DockStyle.Fill;
+			astPanel.Controls.Add(astView);
+			ParseCSharpButtonClick(null, null);
+			transformationComboBox.SelectedIndex = 0;
+		}
+		
+		void ClearSpecialsButtonClick(object sender, EventArgs e)
+		{
+			SetSpecials(new ISpecial[0]);
+		}
+		
+		IList<ISpecial> savedSpecialsList;
+		
+		void SetSpecials(IList<ISpecial> specialsList)
+		{
+			savedSpecialsList = specialsList;
+			specialsLabel.Text = specialsList.Count + " specials saved";
+		}
+		
+		void ArrowDownPictureBoxPaint(object sender, PaintEventArgs e)
+		{
+			Size size = arrowDownPictureBox.Size;
+			e.Graphics.DrawLine(Pens.Black, size.Width / 2, 0, size.Width / 2, size.Height);
+			e.Graphics.DrawLine(Pens.Black, 0, size.Height - size.Width / 2, size.Width / 2, size.Height);
+			e.Graphics.DrawLine(Pens.Black, size.Width - 1, size.Height - size.Width / 2, size.Width / 2, size.Height);
+		}
+		
+		void ArrowUpPictureBoxPaint(object sender, PaintEventArgs e)
+		{
+			Size size = arrowUpPictureBox.Size;
+			e.Graphics.DrawLine(Pens.Black, size.Width / 2, 0, size.Width / 2, size.Height);
+			e.Graphics.DrawLine(Pens.Black, 0, size.Width / 2, size.Width / 2, 0);
+			e.Graphics.DrawLine(Pens.Black, size.Width - 1, size.Width / 2, size.Width / 2, 0);
+		}
+		
+		void ParseCSharpButtonClick(object sender, EventArgs e)
+		{
+			Parse(SupportedLanguage.CSharp, codeTextBox.Text);
+		}
+		
+		void ParseVBButtonClick(object sender, EventArgs e)
+		{
+			Parse(SupportedLanguage.VBNet, codeTextBox.Text);
+		}
+		
+		void Parse(SupportedLanguage language, string text)
+		{
+			using (IParser parser = ParserFactory.CreateParser(language, new StringReader(text))) {
+				parser.Parse();
+				SetSpecials(parser.Lexer.SpecialTracker.RetrieveSpecials());
+				astView.Unit = parser.CompilationUnit;
+				if (parser.Errors.count > 0) {
+					MessageBox.Show(parser.Errors.ErrorOutput, "Parse errors");
+				}
+			}
+		}
+		
+		void GenerateCSharpButtonClick(object sender, EventArgs e)
+		{
+			GenerateCode(new CSharpOutputVisitor());
+		}
+		
+		void GenerateVBButtonClick(object sender, EventArgs e)
+		{
+			GenerateCode(new VBNetOutputVisitor());
+		}
+		
+		void GenerateCode(IOutputASTVisitor outputVisitor)
+		{
+			using (SpecialNodesInserter.Install(savedSpecialsList, outputVisitor)) {
+				outputVisitor.Visit(astView.Unit, null);
+			}
+			codeTextBox.Text = outputVisitor.Text.Replace("\t", "  ");
+		}
+		
+		void DeleteSelectedNodeClick(object sender, EventArgs e)
+		{
+			astView.DeleteSelectedNode();
+		}
+		
+		void ApplyTransformationClick(object sender, EventArgs e)
+		{
+			try {
+				string typeName = typeof(ToCSharpConvertVisitor).Namespace + "." + transformationComboBox.SelectedItem.ToString();
+				Type type = typeof(ToCSharpConvertVisitor).Assembly.GetType(typeName);
+				astView.ApplyTransformation((IAstVisitor)Activator.CreateInstance(type));
+			} catch (Exception ex) {
+				MessageBox.Show(ex.ToString(), "Error");
+				astView.Unit = astView.Unit; // complete refresh
+			}
+		}
+		
+		void EditNodeButtonClick(object sender, EventArgs e)
+		{
+			astView.EditSelectedNode();
+		}
+	}
+}
diff --git a/samples/NRefactoryDemo/MainForm.resx b/samples/NRefactoryDemo/MainForm.resx
new file mode 100644
index 0000000000..7080a7d118
--- /dev/null
+++ b/samples/NRefactoryDemo/MainForm.resx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/samples/NRefactoryDemo/NRefactoryDemo.csproj b/samples/NRefactoryDemo/NRefactoryDemo.csproj
new file mode 100644
index 0000000000..b628bf969b
--- /dev/null
+++ b/samples/NRefactoryDemo/NRefactoryDemo.csproj
@@ -0,0 +1,66 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>NRefactoryDemo</RootNamespace>
+    <AssemblyName>NRefactoryDemo</AssemblyName>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{63199047-9D5D-474C-B3CC-62ABBB071B67}</ProjectGuid>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
+    <IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
+    <OutputPath>bin\Debug\</OutputPath>
+    <Optimize>False</Optimize>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugSymbols>True</DebugSymbols>
+    <DebugType>Full</DebugType>
+    <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+    <BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
+    <IntermediateOutputPath>obj\Release\</IntermediateOutputPath>
+    <OutputPath>bin\Release\</OutputPath>
+    <Optimize>True</Optimize>
+    <DefineConstants>TRACE</DefineConstants>
+    <DebugSymbols>False</DebugSymbols>
+    <DebugType>None</DebugType>
+    <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+    <Reference Include="ICSharpCode.NRefactory">
+      <HintPath>..\..\bin\ICSharpCode.NRefactory.dll</HintPath>
+      <SpecificVersion>False</SpecificVersion>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="MainForm.cs" />
+    <Compile Include="MainForm.Designer.cs">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="AssemblyInfo.cs" />
+    <EmbeddedResource Include="MainForm.resx">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </EmbeddedResource>
+    <Compile Include="AstView.Designer.cs">
+      <DependentUpon>AstView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="AstView.cs" />
+    <EmbeddedResource Include="AstView.resx">
+      <DependentUpon>AstView.cs</DependentUpon>
+    </EmbeddedResource>
+    <Compile Include="EditDialog.Designer.cs">
+      <DependentUpon>EditDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="EditDialog.cs" />
+    <EmbeddedResource Include="EditDialog.resx">
+      <DependentUpon>EditDialog.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
+</Project>
\ No newline at end of file
diff --git a/samples/NRefactoryDemo/NRefactoryDemo.sln b/samples/NRefactoryDemo/NRefactoryDemo.sln
new file mode 100644
index 0000000000..95bdc80be1
--- /dev/null
+++ b/samples/NRefactoryDemo/NRefactoryDemo.sln
@@ -0,0 +1,16 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# SharpDevelop 2.1.0.1394
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NRefactoryDemo", "NRefactoryDemo.csproj", "{63199047-9D5D-474C-B3CC-62ABBB071B67}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{63199047-9D5D-474C-B3CC-62ABBB071B67}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{63199047-9D5D-474C-B3CC-62ABBB071B67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{63199047-9D5D-474C-B3CC-62ABBB071B67}.Release|Any CPU.Build.0 = Release|Any CPU
+		{63199047-9D5D-474C-B3CC-62ABBB071B67}.Release|Any CPU.ActiveCfg = Release|Any CPU
+	EndGlobalSection
+EndGlobal
diff --git a/src/AddIns/Misc/SubversionAddIn/Project/Src/Gui/ProjectBrowserVisitor/OverlayIconManager.cs b/src/AddIns/Misc/SubversionAddIn/Project/Src/Gui/ProjectBrowserVisitor/OverlayIconManager.cs
index 2a597aef2a..d7436c3fe1 100644
--- a/src/AddIns/Misc/SubversionAddIn/Project/Src/Gui/ProjectBrowserVisitor/OverlayIconManager.cs
+++ b/src/AddIns/Misc/SubversionAddIn/Project/Src/Gui/ProjectBrowserVisitor/OverlayIconManager.cs
@@ -153,20 +153,24 @@ namespace ICSharpCode.Svn
 			}
 			FileNode fileNode = node as FileNode;
 			Status status;
-			if (fileNode != null) {
-				status = client.SingleStatus(fileNode.FileName);
-			} else {
-				DirectoryNode directoryNode = node as DirectoryNode;
-				if (directoryNode != null) {
-					status = client.SingleStatus(directoryNode.Directory);
+			try {
+				if (fileNode != null) {
+					status = client.SingleStatus(fileNode.FileName);
 				} else {
-					SolutionNode solNode = node as SolutionNode;
-					if (solNode != null) {
-						status = client.SingleStatus(solNode.Solution.Directory);
+					DirectoryNode directoryNode = node as DirectoryNode;
+					if (directoryNode != null) {
+						status = client.SingleStatus(directoryNode.Directory);
 					} else {
-						return;
+						SolutionNode solNode = node as SolutionNode;
+						if (solNode != null) {
+							status = client.SingleStatus(solNode.Solution.Directory);
+						} else {
+							return;
+						}
 					}
 				}
+			} catch (SvnException) {
+				return;
 			}
 			if (node.TreeView != null) {
 				node.TreeView.BeginInvoke(new MethodInvoker(delegate {
diff --git a/src/AddIns/Misc/SubversionAddIn/Project/SubversionAddIn.csproj b/src/AddIns/Misc/SubversionAddIn/Project/SubversionAddIn.csproj
index 2ff4a5d5c0..97f182c682 100644
--- a/src/AddIns/Misc/SubversionAddIn/Project/SubversionAddIn.csproj
+++ b/src/AddIns/Misc/SubversionAddIn/Project/SubversionAddIn.csproj
@@ -15,6 +15,7 @@
     <OutputPath>..\..\..\..\..\AddIns\AddIns\Misc\SubversionAddin\</OutputPath>
     <Optimize>false</Optimize>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>Full</DebugType>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugSymbols>False</DebugSymbols>
@@ -94,6 +95,7 @@
     <Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs">
       <Link>Configuration\GlobalAssemblyInfo.cs</Link>
     </Compile>
+    <EmbeddedResource Include="Resources\TortoiseSvnNotFoundForm.xfrm" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj">
@@ -114,7 +116,6 @@
       <Link>msvcr70.dll</Link>
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
-    <Content Include="Resources\TortoiseSvnNotFoundForm.xfrm" />
     <Content Include="..\RequiredLibraries\LIBAPR.DLL">
       <Link>LIBAPR.DLL</Link>
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/AdvancedHighlighter.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/AdvancedHighlighter.cs
index ef279f6be3..0f52516cc9 100644
--- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/AdvancedHighlighter.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/AdvancedHighlighter.cs
@@ -7,13 +7,9 @@
 
 using System;
 using System.Collections.Generic;
-using System.Drawing;
-using System.IO;
-using System.Xml;
-using System.Windows.Forms;
+using ICSharpCode.SharpDevelop.Gui;
 using ICSharpCode.TextEditor;
 using ICSharpCode.TextEditor.Document;
-using ICSharpCode.SharpDevelop.Gui;
 
 namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
 {
diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/AdvancedHighlightingStrategy.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/AdvancedHighlightingStrategy.cs
index 211ea877ec..00867c889a 100644
--- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/AdvancedHighlightingStrategy.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/AdvancedHighlightingStrategy.cs
@@ -7,11 +7,6 @@
 
 using System;
 using System.Collections.Generic;
-using System.Drawing;
-using System.IO;
-using System.Xml;
-using System.Windows.Forms;
-using ICSharpCode.TextEditor;
 using ICSharpCode.TextEditor.Document;
 
 namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ErrorDrawer.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ErrorDrawer.cs
index cf3f19c5a2..1f81b8cbf3 100644
--- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ErrorDrawer.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ErrorDrawer.cs
@@ -6,15 +6,10 @@
 // </file>
 
 using System;
-using System.IO;
-using System.Collections.Generic;
 using System.Drawing;
-using System.Drawing.Text;
-
-using ICSharpCode.TextEditor.Document;
 using ICSharpCode.Core;
-using ICSharpCode.SharpDevelop.Gui;
 using ICSharpCode.TextEditor;
+using ICSharpCode.TextEditor.Document;
 
 namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
 {
diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ParserFoldingStrategy.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ParserFoldingStrategy.cs
index c58b66f7c3..fb8c57935b 100644
--- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ParserFoldingStrategy.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/ParserFoldingStrategy.cs
@@ -6,8 +6,6 @@
 // </file>
 
 using System;
-using System.Drawing;
-using System.Collections;
 using System.Collections.Generic;
 using ICSharpCode.Core;
 using ICSharpCode.SharpDevelop.Dom;
diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/QuickClassBrowserPanel.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/QuickClassBrowserPanel.cs
index 56161ae14e..cce27838fe 100644
--- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/QuickClassBrowserPanel.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/QuickClassBrowserPanel.cs
@@ -7,13 +7,13 @@
 
 // created on 07.03.2004 at 19:12
 using System;
-using System.Threading;
 using System.Collections;
-using System.IO;
 using System.Drawing;
+using System.IO;
 using System.Windows.Forms;
-using ICSharpCode.SharpDevelop.Dom;
+
 using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop.Dom;
 
 namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
 {
diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextEditorProperties.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextEditorProperties.cs
index 46de747066..bede4cf39c 100644
--- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextEditorProperties.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/SharpDevelopTextEditorProperties.cs
@@ -6,13 +6,11 @@
 // </file>
 
 using System;
-using System.Text;
 using System.Drawing;
+using System.Text;
 
 using ICSharpCode.Core;
 using ICSharpCode.SharpDevelop.Gui.OptionPanels;
-
-using ICSharpCode.TextEditor;
 using ICSharpCode.TextEditor.Document;
 
 namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs
index c65db69c3d..9467642cfb 100644
--- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs
@@ -6,20 +6,16 @@
 // </file>
 
 using System;
-using System.IO;
 using System.Drawing;
-using System.Windows.Forms;
 using System.Drawing.Printing;
+using System.IO;
+using System.Windows.Forms;
 
+using ICSharpCode.Core;
 using ICSharpCode.SharpDevelop.Dom;
-
 using ICSharpCode.SharpDevelop.Gui;
 using ICSharpCode.TextEditor;
 using ICSharpCode.TextEditor.Document;
-using ICSharpCode.SharpDevelop.Project;
-using ICSharpCode.SharpDevelop.Internal.Undo;
-
-using ICSharpCode.Core;
 
 namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
 {
diff --git a/src/Main/Core/Project/Src/Services/ResourceService/ResourceService.cs b/src/Main/Core/Project/Src/Services/ResourceService/ResourceService.cs
index f8be596a4a..518afc6562 100644
--- a/src/Main/Core/Project/Src/Services/ResourceService/ResourceService.cs
+++ b/src/Main/Core/Project/Src/Services/ResourceService/ResourceService.cs
@@ -396,14 +396,12 @@ namespace ICSharpCode.Core
 		/// instead of an icon in the dabase. It is converted automatically.
 		/// </summary>
 		/// <returns>
-		/// The icon in the (localized) resource database.
+		/// The icon in the (localized) resource database, or null, if the icon cannot
+		/// be found.
 		/// </returns>
 		/// <param name="name">
 		/// The name of the requested icon.
 		/// </param>
-		/// <exception cref="ResourceNotFoundException">
-		/// Is thrown when the GlobalResource manager can't find a requested resource.
-		/// </exception>
 		public static Icon GetIcon(string name)
 		{
 			lock (iconCache) {
@@ -445,7 +443,9 @@ namespace ICSharpCode.Core
 				if (bitmapCache.TryGetValue(name, out bmp))
 					return bmp;
 				bmp = (Bitmap)GetImageResource(name);
-				Debug.Assert(bmp != null, "Resource " + name);
+				if (bmp == null) {
+					throw new ResourceNotFoundException(name);
+				}
 				bitmapCache[name] = bmp;
 				return bmp;
 			}