[svn] r5918: corsavy-addin/trunk: NemerleBinding.addin NemerleBinding.csproj Src/ConvertBuffer.cs Src/NRef...

nazgul svnadmin at nemerle.org
Mon Nov 7 22:48:55 CET 2005


Log:
Add (partially working) convert buffer to Nemerle feature to SharpDevelop addin

Author: nazgul
Date: Mon Nov  7 22:48:37 2005
New Revision: 5918

Added:
   corsavy-addin/trunk/Src/ConvertBuffer.cs
   corsavy-addin/trunk/Src/NRefactory/
   corsavy-addin/trunk/Src/NRefactory/NemerleToCSharpConvertVisitor.cs
   corsavy-addin/trunk/Src/NRefactory/Output/
   corsavy-addin/trunk/Src/NRefactory/Output/NemerleOutputVisitor.cs
   corsavy-addin/trunk/Src/NRefactory/Output/OutputFormatter.cs
   corsavy-addin/trunk/Src/NRefactory/Output/PrettyPrintOptions.cs
Modified:
   corsavy-addin/trunk/NemerleBinding.addin
   corsavy-addin/trunk/NemerleBinding.csproj

Modified: corsavy-addin/trunk/NemerleBinding.addin
==============================================================================
--- corsavy-addin/trunk/NemerleBinding.addin	(original)
+++ corsavy-addin/trunk/NemerleBinding.addin	Mon Nov  7 22:48:37 2005
@@ -87,6 +87,25 @@
 		                 projectfileextension = ".nproj"
 		                 class                = "NemerleBinding.NemerleLanguageBinding" />
 	</Path>
+	<Path name = "/SharpDevelop/Workbench/MainMenu/Tools">
+		<ComplexCondition action = "Disable">
+			<And>
+				<Or>
+					<Condition name = "WindowActive" activewindow="ICSharpCode.FormDesigner.FormDesignerViewContent"/>
+					<Condition name = "WindowActive" activewindow="ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.ITextEditorControlProvider"/>
+				</Or>
+				<Or>
+					<Condition name="ActiveContentExtension" activeextension=".cs"/>
+					<Condition name="ActiveContentExtension" activeextension=".vb"/>
+				</Or>
+			</And>
+			<MenuItem id = "ConvertBufferToNemerle"
+			          insertbefore = "ConvertBuffer"
+			          insertafter = "Separator2"
+			          label = "Convert buffer to Nemerle"
+			          class = "NemerleBinding.NemerleConvertBuffer"/>
+		</ComplexCondition>
+	</Path>
 
 
         <Path name = "/Workspace/Autostart">

Modified: corsavy-addin/trunk/NemerleBinding.csproj
==============================================================================
--- corsavy-addin/trunk/NemerleBinding.csproj	(original)
+++ corsavy-addin/trunk/NemerleBinding.csproj	Mon Nov  7 22:48:37 2005
@@ -41,15 +41,19 @@
     <Reference Include="System.Windows.Forms" />
     <Reference Include="System.XML" />
     <Reference Include="ICSharpCode.Core">
-      <HintPath>..\trunk\SharpDevelop\bin\ICSharpCode.Core.dll</HintPath>
+      <HintPath>..\sharpdevelop\SharpDevelop\bin\ICSharpCode.Core.dll</HintPath>
+      <SpecificVersion>False</SpecificVersion>
+    </Reference>
+    <Reference Include="ICSharpCode.SharpDevelop">
+      <HintPath>..\sharpdevelop\SharpDevelop\bin\ICSharpCode.SharpDevelop.dll</HintPath>
       <SpecificVersion>False</SpecificVersion>
     </Reference>
     <Reference Include="ICSharpCode.TextEditor">
-      <HintPath>..\trunk\SharpDevelop\bin\ICSharpCode.TextEditor.dll</HintPath>
+      <HintPath>..\sharpdevelop\SharpDevelop\bin\ICSharpCode.TextEditor.dll</HintPath>
       <SpecificVersion>False</SpecificVersion>
     </Reference>
-    <Reference Include="ICSharpCode.SharpDevelop">
-      <HintPath>..\trunk\SharpDevelop\bin\ICSharpCode.SharpDevelop.dll</HintPath>
+    <Reference Include="ICSharpCode.NRefactory">
+      <HintPath>..\sharpdevelop\SharpDevelop\bin\ICSharpCode.NRefactory.dll</HintPath>
       <SpecificVersion>False</SpecificVersion>
     </Reference>
   </ItemGroup>
@@ -72,6 +76,11 @@
     </None>
     <Compile Include="Src\EventHandlerCompletitionDataProvider.cs" />
     <Compile Include="Src\AutoStart.cs" />
+    <Compile Include="Src\ConvertBuffer.cs" />
+    <Compile Include="Src\NRefactory\Output\NemerleOutputVisitor.cs" />
+    <Compile Include="Src\NRefactory\Output\OutputFormatter.cs" />
+    <Compile Include="Src\NRefactory\Output\PrettyPrintOptions.cs" />
+    <Compile Include="Src\NRefactory\NemerleToCSharpConvertVisitor.cs" />
   </ItemGroup>
   <ItemGroup>
     <Content Include="templates\Nemerle.Form.xft" />
@@ -80,6 +89,8 @@
     <Content Include="templates\Library.xpt" />
     <Content Include="templates\Nemerle.Empty.xft" />
     <Content Include="templates\Nemerle.EmptyClass.xft" />
+    <Folder Include="Src\NRefactory" />
+    <Folder Include="Src\NRefactory\Output" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
 </Project>
\ No newline at end of file

Added: corsavy-addin/trunk/Src/ConvertBuffer.cs
==============================================================================
--- (empty file)
+++ corsavy-addin/trunk/Src/ConvertBuffer.cs	Mon Nov  7 22:48:37 2005
@@ -0,0 +1,61 @@
+// <file>
+//     <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
+//     <license see="prj:///doc/license.txt">GNU General Public License</license>
+//     <owner name="Mike Krüger" email="mike at icsharpcode.net"/>
+//     <version>$Revision: 501 $</version>
+// </file>
+
+using System;
+using System.IO;
+using System.Threading;
+using System.Drawing;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Windows.Forms;
+using System.Diagnostics;
+
+using System.CodeDom.Compiler;
+
+using ICSharpCode.SharpDevelop.Gui;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.Core;
+
+using ICSharpCode.NRefactory.PrettyPrinter;
+using ICSharpCode.NRefactory.Parser;
+
+namespace NemerleBinding
+{
+	public class NemerleConvertBuffer : ICSharpCode.SharpDevelop.AbstractMenuCommand
+	{
+		public override void Run()
+		{
+			IWorkbenchWindow window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow;
+			
+			if (window != null && window.ViewContent is IEditable) {
+				
+				ICSharpCode.NRefactory.Parser.IParser p = ICSharpCode.NRefactory.Parser.ParserFactory.CreateParser(SupportedLanguage.CSharp, new StringReader(((IEditable)window.ViewContent).Text));
+				p.Parse();
+				if (p.Errors.count > 0) {
+					
+					MessageService.ShowError("Correct source code errors first (only correct source code would convert).");
+					return;
+				}
+				
+				NemerleOutputVisitor nemv = new NemerleOutputVisitor();
+				
+				List<ISpecial> specials = p.Lexer.SpecialTracker.CurrentSpecials;
+				//PreProcessingDirective.CSharpToVB(specials);
+				new NemerleToCSharpConvertVisitor().Visit(p.CompilationUnit, null);
+				SpecialNodesInserter sni = new SpecialNodesInserter(specials,
+				                                                    new SpecialOutputVisitor(nemv.OutputFormatter));
+				nemv.NodeTracker.NodeVisiting += sni.AcceptNodeStart;
+				nemv.NodeTracker.NodeVisited  += sni.AcceptNodeEnd;
+				nemv.NodeTracker.NodeChildrenVisited += sni.AcceptNodeEnd;
+				nemv.Visit(p.CompilationUnit, null);
+				sni.Finish();
+				
+				FileService.NewFile("Generated.n", "Nemerle", nemv.Text);
+			}
+		}
+	}
+}

Added: corsavy-addin/trunk/Src/NRefactory/NemerleToCSharpConvertVisitor.cs
==============================================================================
--- (empty file)
+++ corsavy-addin/trunk/Src/NRefactory/NemerleToCSharpConvertVisitor.cs	Mon Nov  7 22:48:37 2005
@@ -0,0 +1,25 @@
+// <file>
+//     <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
+//     <license see="prj:///doc/license.txt">GNU General Public License</license>
+//     <owner name="Daniel Grunwald" email="daniel at danielgrunwald.de"/>
+//     <version>$Revision: 473 $</version>
+// </file>
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.AST;
+
+namespace NemerleBinding
+{
+	/// <summary>
+	/// This class converts C# constructs to their Nemerle equivalents.
+	/// </summary>
+	public class NemerleToCSharpConvertVisitor : AbstractASTVisitor
+	{
+	}
+}

Added: corsavy-addin/trunk/Src/NRefactory/Output/NemerleOutputVisitor.cs
==============================================================================
--- (empty file)
+++ corsavy-addin/trunk/Src/NRefactory/Output/NemerleOutputVisitor.cs	Mon Nov  7 22:48:37 2005
@@ -0,0 +1,2421 @@
+ďťż// <file>
+//     <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
+//     <license see="prj:///doc/license.txt">GNU General Public License</license>
+//     <owner name="Daniel Grunwald" email="daniel at danielgrunwald.de"/>
+//     <version>$Revision: 690 $</version>
+// </file>
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Diagnostics;
+
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.CSharp;
+using ICSharpCode.NRefactory.Parser.AST;
+using ICSharpCode.NRefactory.PrettyPrinter;
+
+namespace NemerleBinding
+{
+	public class NemerleOutputVisitor : IOutputASTVisitor
+	{
+		Errors                errors             = new Errors();
+		NemerleOutputFormatter outputFormatter;
+		PrettyPrintOptions    prettyPrintOptions = new PrettyPrintOptions();
+		NodeTracker           nodeTracker;
+//		Stack<WithStatement> withExpressionStack = new Stack<WithStatement>();
+		Stack withExpressionStack = new Stack();
+		
+		public string Text {
+			get {
+				return outputFormatter.Text;
+			}
+		}
+		
+		public Errors Errors {
+			get {
+				return errors;
+			}
+		}
+		
+		public object Options {
+			get {
+				return prettyPrintOptions;
+			}
+			set {
+				prettyPrintOptions = value as PrettyPrintOptions;
+			}
+		}
+		
+		public IOutputFormatter OutputFormatter {
+			get {
+				return outputFormatter;
+			}
+		}
+		
+		public NodeTracker NodeTracker {
+			get {
+				return nodeTracker;
+			}
+		}
+		
+		public NemerleOutputVisitor()
+		{
+			outputFormatter = new NemerleOutputFormatter(prettyPrintOptions);
+			nodeTracker     = new NodeTracker(this);
+		}
+		
+		#region ICSharpCode.NRefactory.Parser.IASTVisitor interface implementation
+		public object Visit(INode node, object data)
+		{
+			errors.Error(-1, -1, String.Format("Visited INode (should NEVER HAPPEN), node is : {0}", node.ToString()));
+			return node.AcceptChildren(this, data);
+		}
+		
+		public object Visit(CompilationUnit compilationUnit, object data)
+		{
+			nodeTracker.TrackedVisitChildren(compilationUnit, data);
+			outputFormatter.EndFile();
+			return null;
+		}
+		
+		string ConvertTypeString(string typeString)
+		{
+			switch (typeString) {
+				case "System.Boolean":
+					return "bool";
+				case "System.String":
+					return "string";
+				case "System.Char":
+					return "char";
+				case "System.Double":
+					return "double";
+				case "System.Single":
+					return "float";
+				case "System.Decimal":
+					return "decimal";
+				case "System.DateTime":
+					return "System.DateTime";
+				case "System.Int64":
+					return "long";
+				case "System.Int32":
+					return "int";
+				case "System.Int16":
+					return "short";
+				case "System.Byte":
+					return "byte";
+				case "System.Void":
+					return "void";
+				case "System.Object":
+					return "object";
+					
+				case "System.UInt64":
+					return "ulong";
+				case "System.UInt32":
+					return "uint";
+				case "System.UInt16":
+					return "ushort";
+				case "System.SByte":
+					return "sbyte";
+			}
+			return typeString;
+		}
+		
+		
+		void PrintTemplates(List<TemplateDefinition> templates)
+		{
+			if (templates.Count == 0) return;
+			outputFormatter.PrintToken(Tokens.LessThan);
+			for (int i = 0; i < templates.Count; i++) {
+				if (i > 0) PrintFormattedComma();
+				outputFormatter.PrintIdentifier(templates[i].Name);
+			}
+			outputFormatter.PrintToken(Tokens.GreaterThan);
+		}
+		
+		public object Visit(TypeReference typeReference, object data)
+		{
+			if (typeReference.IsArrayType) {
+				outputFormatter.PrintText ("array");
+				outputFormatter.Space();
+				outputFormatter.PrintToken(Tokens.OpenSquareBracket);
+				//for (int i = 0; i < typeReference.RankSpecifier.Length; ++i) {
+					
+					if (typeReference.RankSpecifier[0] > 1) {
+					    outputFormatter.PrintText (typeReference.RankSpecifier[0].ToString());
+						outputFormatter.PrintToken(Tokens.Comma);
+						if (this.prettyPrintOptions.SpacesWithinBrackets) {
+							outputFormatter.Space();
+						}
+					}
+			}
+			if (typeReference.IsGlobal) {
+				//outputFormatter.PrintText("global::");
+				errors.Error(-1, -1, String.Format("global aliases are not supported by Nemerle yet"));
+			}
+			if (typeReference.Type == null || typeReference.Type.Length ==0) {
+				outputFormatter.PrintText("void");
+			}  else {
+				if (typeReference.SystemType.Length > 0) {
+					outputFormatter.PrintText(ConvertTypeString(typeReference.SystemType));
+				} else {
+					outputFormatter.PrintText(typeReference.Type);
+				}
+				if (typeReference.GenericTypes != null && typeReference.GenericTypes.Count > 0) {
+					outputFormatter.PrintToken(Tokens.OpenSquareBracket);
+					AppendCommaSeparatedList(typeReference.GenericTypes);
+					outputFormatter.PrintToken(Tokens.CloseSquareBracket);
+				}
+			}
+			if (typeReference.PointerNestingLevel > 0) {
+				errors.Error(-1, -1, String.Format("pointer types are not supported by Nemerle"));
+			}
+			if (typeReference.IsArrayType) {
+				outputFormatter.PrintToken(Tokens.CloseSquareBracket);
+			}
+			return null;
+		}
+		
+		public object Visit(InnerClassTypeReference typeReference, object data)
+		{
+			nodeTracker.TrackedVisit(typeReference.BaseType, data);
+			outputFormatter.PrintToken(Tokens.Dot);
+			return Visit((TypeReference)typeReference, data); // call Visit(TypeReference, object)
+		}
+		
+		#region Global scope
+		void VisitAttributes(ICollection attributes, object data)
+		{
+			if (attributes == null || attributes.Count <= 0) {
+				return;
+			}
+			foreach (AttributeSection section in attributes) {
+				nodeTracker.TrackedVisit(section, data);
+			}
+		}
+		void PrintFormattedComma()
+		{
+			if (this.prettyPrintOptions.SpacesBeforeComma) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.Comma);
+			if (this.prettyPrintOptions.SpacesAfterComma) {
+				outputFormatter.Space();
+			}
+		}
+		
+		public object Visit(AttributeSection attributeSection, object data)
+		{
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.OpenSquareBracket);
+			if (this.prettyPrintOptions.SpacesWithinBrackets) {
+				outputFormatter.Space();
+			}
+			if (attributeSection.AttributeTarget != null && attributeSection.AttributeTarget != String.Empty) {
+				outputFormatter.PrintText(attributeSection.AttributeTarget);
+				outputFormatter.PrintToken(Tokens.Colon);
+				outputFormatter.Space();
+			}
+			Debug.Assert(attributeSection.Attributes != null);
+			for (int j = 0; j < attributeSection.Attributes.Count; ++j) {
+				nodeTracker.TrackedVisit((INode)attributeSection.Attributes[j], data);
+				if (j + 1 < attributeSection.Attributes.Count) {
+					PrintFormattedComma();
+				}
+			}
+			if (this.prettyPrintOptions.SpacesWithinBrackets) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.CloseSquareBracket);
+			outputFormatter.NewLine();
+			return null;
+		}
+		
+		public object Visit(ICSharpCode.NRefactory.Parser.AST.Attribute attribute, object data)
+		{
+			outputFormatter.PrintIdentifier(attribute.Name);
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			this.AppendCommaSeparatedList(attribute.PositionalArguments);
+			
+			if (attribute.NamedArguments != null && attribute.NamedArguments.Count > 0) {
+				if (attribute.PositionalArguments.Count > 0) {
+					PrintFormattedComma();
+				}
+				for (int i = 0; i < attribute.NamedArguments.Count; ++i) {
+					nodeTracker.TrackedVisit((INode)attribute.NamedArguments[i], data);
+					if (i + 1 < attribute.NamedArguments.Count) {
+						PrintFormattedComma();
+					}
+				}
+			}
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			return null;
+		}
+		
+		public object Visit(NamedArgumentExpression namedArgumentExpression, object data)
+		{
+			outputFormatter.PrintIdentifier(namedArgumentExpression.Name);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.Assign);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(namedArgumentExpression.Expression, data);
+			return null;
+		}
+		
+		public object Visit(Using u, object data)
+		{
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.Using);
+			outputFormatter.Space();
+			
+			outputFormatter.PrintIdentifier(u.Name);
+			
+			if (u.IsAlias) {
+				outputFormatter.Space();
+				outputFormatter.PrintToken(Tokens.Assign);
+				outputFormatter.Space();
+				nodeTracker.TrackedVisit(u.Alias, data);
+			}
+			
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			outputFormatter.NewLine();
+			return null;
+		}
+		
+		public object Visit(UsingDeclaration usingDeclaration, object data)
+		{
+			foreach (Using u in usingDeclaration.Usings) {
+				nodeTracker.TrackedVisit(u, data);
+			}
+			return null;
+		}
+		
+		public object Visit(NamespaceDeclaration namespaceDeclaration, object data)
+		{
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.Namespace);
+			outputFormatter.Space();
+			outputFormatter.PrintIdentifier(namespaceDeclaration.Name);
+			
+			outputFormatter.BeginBrace(this.prettyPrintOptions.NameSpaceBraceStyle);
+			
+			nodeTracker.TrackedVisitChildren(namespaceDeclaration, data);
+			
+			outputFormatter.EndBrace();
+			
+			return null;
+		}
+		
+		
+		void OutputEnumMembers(TypeDeclaration typeDeclaration, object data)
+		{
+			foreach (FieldDeclaration fieldDeclaration in typeDeclaration.Children) {
+				VariableDeclaration f = (VariableDeclaration)fieldDeclaration.Fields[0];
+				VisitAttributes(fieldDeclaration.Attributes, data);
+				outputFormatter.Indent();
+				outputFormatter.PrintIdentifier(f.Name);
+				if (f.Initializer != null && !f.Initializer.IsNull) {
+					outputFormatter.Space();
+					outputFormatter.PrintToken(Tokens.Assign);
+					outputFormatter.Space();
+					nodeTracker.TrackedVisit(f.Initializer, data);
+				}
+				outputFormatter.PrintToken(Tokens.Comma);
+				outputFormatter.NewLine();
+			}
+		}
+		
+		TypeDeclaration currentType = null;
+		
+		public object Visit(TypeDeclaration typeDeclaration, object data)
+		{
+			VisitAttributes(typeDeclaration.Attributes, data);
+			outputFormatter.Indent();
+			OutputModifier(typeDeclaration.Modifier);
+			switch (typeDeclaration.Type) {
+				case ClassType.Class:
+					outputFormatter.PrintToken(Tokens.Class);
+					break;
+				case ClassType.Enum:
+					outputFormatter.PrintToken(Tokens.Enum);
+					break;
+				case ClassType.Interface:
+					outputFormatter.PrintToken(Tokens.Interface);
+					break;
+				case ClassType.Struct:
+					outputFormatter.PrintToken(Tokens.Struct);
+					break;
+			}
+			outputFormatter.Space();
+			outputFormatter.PrintIdentifier(typeDeclaration.Name);
+			
+			PrintTemplates(typeDeclaration.Templates);
+			
+			if (typeDeclaration.BaseTypes != null && typeDeclaration.BaseTypes.Count > 0) {
+				outputFormatter.Space();
+				outputFormatter.PrintToken(Tokens.Colon);
+				outputFormatter.Space();
+				for (int i = 0; i < typeDeclaration.BaseTypes.Count; ++i) {
+					if (i > 0) {
+						PrintFormattedComma();
+					}
+					nodeTracker.TrackedVisit(typeDeclaration.BaseTypes[i], data);
+				}
+			}
+			
+			foreach (TemplateDefinition templateDefinition in typeDeclaration.Templates) {
+				nodeTracker.TrackedVisit(templateDefinition, data);
+			}
+			
+			switch (typeDeclaration.Type) {
+				case ClassType.Class:
+					outputFormatter.BeginBrace(this.prettyPrintOptions.ClassBraceStyle);
+					break;
+				case ClassType.Enum:
+					outputFormatter.BeginBrace(this.prettyPrintOptions.EnumBraceStyle);
+					break;
+				case ClassType.Interface:
+					outputFormatter.BeginBrace(this.prettyPrintOptions.InterfaceBraceStyle);
+					break;
+				case ClassType.Struct:
+					outputFormatter.BeginBrace(this.prettyPrintOptions.StructBraceStyle);
+					break;
+			}
+			
+			TypeDeclaration oldType = currentType;
+			currentType = typeDeclaration;
+			if (typeDeclaration.Type == ClassType.Enum) {
+				OutputEnumMembers(typeDeclaration, data);
+			} else {
+				nodeTracker.TrackedVisitChildren(typeDeclaration, data);
+			}
+			currentType = oldType;
+			outputFormatter.EndBrace();
+			
+			return null;
+		}
+		
+		public object Visit(TemplateDefinition templateDefinition, object data)
+		{
+			if (templateDefinition.Bases.Count == 0)
+				return null;
+			
+			outputFormatter.Space();
+			outputFormatter.PrintText("where");
+			outputFormatter.Space();
+			outputFormatter.PrintIdentifier(templateDefinition.Name);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.Colon);
+			outputFormatter.Space();
+			
+			for (int i = 0; i < templateDefinition.Bases.Count; ++i) {
+				nodeTracker.TrackedVisit(templateDefinition.Bases[i], data);
+				if (i + 1 < templateDefinition.Bases.Count) {
+					PrintFormattedComma();
+				}
+			}
+			return null;
+		}
+		
+		public object Visit(DelegateDeclaration delegateDeclaration, object data)
+		{
+			VisitAttributes(delegateDeclaration.Attributes, data);
+			OutputModifier(delegateDeclaration.Modifier);
+			outputFormatter.PrintToken(Tokens.Delegate);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(delegateDeclaration.ReturnType, data);
+			outputFormatter.Space();
+			outputFormatter.PrintIdentifier(delegateDeclaration.Name);
+			PrintTemplates(delegateDeclaration.Templates);
+			if (prettyPrintOptions.BeforeDelegateDeclarationParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			AppendCommaSeparatedList(delegateDeclaration.Parameters);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			foreach (TemplateDefinition templateDefinition in delegateDeclaration.Templates) {
+				nodeTracker.TrackedVisit(templateDefinition, data);
+			}
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			outputFormatter.NewLine();
+			return null;
+		}
+		
+		public object Visit(OptionDeclaration optionDeclaration, object data)
+		{
+			errors.Error(-1, -1, String.Format("OptionDeclaration is unsupported"));
+			return null;
+		}
+		#endregion
+		
+		#region Type level
+		public object Visit(FieldDeclaration fieldDeclaration, object data)
+		{
+			VisitAttributes(fieldDeclaration.Attributes, data);
+			outputFormatter.Indent();
+			OutputModifier(fieldDeclaration.Modifier);
+			AppendCommaSeparatedList(fieldDeclaration.Fields);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.Colon);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(fieldDeclaration.TypeReference, data);
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			outputFormatter.NewLine();
+			return null;
+		}
+		
+		public object Visit(VariableDeclaration variableDeclaration, object data)
+		{
+			outputFormatter.PrintIdentifier(variableDeclaration.Name);
+			if (!variableDeclaration.Initializer.IsNull) {
+				outputFormatter.Space();
+				outputFormatter.PrintToken(Tokens.Assign);
+				outputFormatter.Space();
+				nodeTracker.TrackedVisit(variableDeclaration.Initializer, data);
+			}
+			return null;
+		}
+		
+		public object Visit(PropertyDeclaration propertyDeclaration, object data)
+		{
+			VisitAttributes(propertyDeclaration.Attributes, data);
+			outputFormatter.Indent();
+			OutputModifier(propertyDeclaration.Modifier);
+			outputFormatter.PrintIdentifier(propertyDeclaration.Name);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.Colon);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(propertyDeclaration.TypeReference, data);
+			outputFormatter.Space();
+			if (propertyDeclaration.InterfaceImplementations.Count > 0) {
+				outputFormatter.PrintText("implements");
+				outputFormatter.Space();
+				nodeTracker.TrackedVisit(propertyDeclaration.InterfaceImplementations[0].InterfaceType, data);
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			nodeTracker.TrackedVisit(propertyDeclaration.GetRegion, data);
+			nodeTracker.TrackedVisit(propertyDeclaration.SetRegion, data);
+			--outputFormatter.IndentationLevel;
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			outputFormatter.NewLine();
+			return null;
+		}
+		
+		public object Visit(PropertyGetRegion propertyGetRegion, object data)
+		{
+			this.VisitAttributes(propertyGetRegion.Attributes, data);
+			outputFormatter.Indent();
+			outputFormatter.PrintText("get");
+			OutputBlock(propertyGetRegion.Block, prettyPrintOptions.PropertyGetBraceStyle);
+			return null;
+		}
+		
+		public object Visit(PropertySetRegion propertySetRegion, object data)
+		{
+			this.VisitAttributes(propertySetRegion.Attributes, data);
+			outputFormatter.Indent();
+			outputFormatter.PrintText("set");
+			OutputBlock(propertySetRegion.Block, prettyPrintOptions.PropertySetBraceStyle);
+			return null;
+		}
+		
+		public object Visit(EventDeclaration eventDeclaration, object data)
+		{
+			VisitAttributes(eventDeclaration.Attributes, data);
+			outputFormatter.Indent();
+			OutputModifier(eventDeclaration.Modifier);
+			outputFormatter.PrintToken(Tokens.Event);
+			outputFormatter.Space();
+			
+			if (eventDeclaration.InterfaceImplementations.Count > 0) {
+				nodeTracker.TrackedVisit(eventDeclaration.InterfaceImplementations[0].InterfaceType, data);
+				outputFormatter.PrintToken(Tokens.Dot);
+			}
+			
+			outputFormatter.PrintIdentifier(eventDeclaration.Name);
+			outputFormatter.Space();
+			outputFormatter.PrintToken (Tokens.Colon);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(eventDeclaration.TypeReference, data);
+			outputFormatter.Space();
+			
+			if (eventDeclaration.AddRegion.IsNull && eventDeclaration.RemoveRegion.IsNull) {
+				outputFormatter.PrintToken(Tokens.Semicolon);
+				outputFormatter.NewLine();
+			} else {
+				outputFormatter.BeginBrace(this.prettyPrintOptions.PropertyBraceStyle);
+				nodeTracker.TrackedVisit(eventDeclaration.AddRegion, data);
+				nodeTracker.TrackedVisit(eventDeclaration.RemoveRegion, data);
+				outputFormatter.EndBrace();
+			}
+			return null;
+		}
+		
+		public object Visit(EventAddRegion eventAddRegion, object data)
+		{
+			VisitAttributes(eventAddRegion.Attributes, data);
+			outputFormatter.Indent();
+			outputFormatter.PrintText("add");
+			OutputBlock(eventAddRegion.Block, prettyPrintOptions.EventAddBraceStyle);
+			return null;
+		}
+		
+		public object Visit(EventRemoveRegion eventRemoveRegion, object data)
+		{
+			VisitAttributes(eventRemoveRegion.Attributes, data);
+			outputFormatter.Indent();
+			outputFormatter.PrintText("remove");
+			OutputBlock(eventRemoveRegion.Block, prettyPrintOptions.EventRemoveBraceStyle);
+			return null;
+		}
+		
+		public object Visit(EventRaiseRegion eventRaiseRegion, object data)
+		{
+			// VB.NET only
+			return null;
+		}
+		
+		public object Visit(ParameterDeclarationExpression parameterDeclarationExpression, object data)
+		{
+			VisitAttributes(parameterDeclarationExpression.Attributes, data);
+			OutputModifier(parameterDeclarationExpression.ParamModifier);
+			outputFormatter.PrintIdentifier(parameterDeclarationExpression.ParameterName);
+			outputFormatter.Space();
+			outputFormatter.PrintToken (Tokens.Colon);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(parameterDeclarationExpression.TypeReference, data);
+			return null;
+		}
+		
+		public object Visit(MethodDeclaration methodDeclaration, object data)
+		{
+			VisitAttributes(methodDeclaration.Attributes, data);
+			outputFormatter.Indent();
+			OutputModifier(methodDeclaration.Modifier);
+			if (methodDeclaration.InterfaceImplementations.Count > 0) {
+				nodeTracker.TrackedVisit(methodDeclaration.InterfaceImplementations[0].InterfaceType, data);
+				outputFormatter.PrintToken(Tokens.Dot);
+			}
+			outputFormatter.PrintIdentifier(methodDeclaration.Name);
+			PrintTemplates(methodDeclaration.Templates);
+			if (prettyPrintOptions.BeforeMethodDeclarationParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			AppendCommaSeparatedList(methodDeclaration.Parameters);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			foreach (TemplateDefinition templateDefinition in methodDeclaration.Templates) {
+				nodeTracker.TrackedVisit(templateDefinition, data);
+			}
+			outputFormatter.Space();
+			outputFormatter.PrintToken (Tokens.Colon);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(methodDeclaration.TypeReference, data);
+			outputFormatter.Space();
+			
+			OutputBlock(methodDeclaration.Body, this.prettyPrintOptions.MethodBraceStyle);
+			return null;
+		}
+		
+		public object Visit(ConstructorDeclaration constructorDeclaration, object data)
+		{
+			VisitAttributes(constructorDeclaration.Attributes, data);
+			outputFormatter.Indent();
+			OutputModifier(constructorDeclaration.Modifier);
+			outputFormatter.PrintToken (Tokens.This);
+
+			if (prettyPrintOptions.BeforeConstructorDeclarationParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			AppendCommaSeparatedList(constructorDeclaration.Parameters);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			// FIXME
+			nodeTracker.TrackedVisit(constructorDeclaration.ConstructorInitializer, data);
+			OutputBlock(constructorDeclaration.Body, this.prettyPrintOptions.ConstructorBraceStyle);
+			return null;
+		}
+		
+		public object Visit(ConstructorInitializer constructorInitializer, object data)
+		{
+			if (constructorInitializer.IsNull) {
+				return null;
+			}
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.Colon);
+			outputFormatter.Space();
+			if (constructorInitializer.ConstructorInitializerType == ConstructorInitializerType.Base) {
+				outputFormatter.PrintToken(Tokens.Base);
+			} else {
+				outputFormatter.PrintToken(Tokens.This);
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			AppendCommaSeparatedList(constructorInitializer.Arguments);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			return null;
+		}
+		
+		public object Visit(IndexerDeclaration indexerDeclaration, object data)
+		{
+			VisitAttributes(indexerDeclaration.Attributes, data);
+			outputFormatter.Indent();
+			OutputModifier(indexerDeclaration.Modifier);
+			nodeTracker.TrackedVisit(indexerDeclaration.TypeReference, data);
+			outputFormatter.Space();
+			if (indexerDeclaration.InterfaceImplementations.Count > 0) {
+				nodeTracker.TrackedVisit(indexerDeclaration.InterfaceImplementations[0].InterfaceType, data);
+				outputFormatter.PrintToken(Tokens.Dot);
+			}
+			outputFormatter.PrintToken(Tokens.This);
+			outputFormatter.PrintToken(Tokens.OpenSquareBracket);
+			if (this.prettyPrintOptions.SpacesWithinBrackets) {
+				outputFormatter.Space();
+			}
+			AppendCommaSeparatedList(indexerDeclaration.Parameters);
+			if (this.prettyPrintOptions.SpacesWithinBrackets) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.CloseSquareBracket);
+			outputFormatter.NewLine();
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			nodeTracker.TrackedVisit(indexerDeclaration.GetRegion, data);
+			nodeTracker.TrackedVisit(indexerDeclaration.SetRegion, data);
+			--outputFormatter.IndentationLevel;
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			outputFormatter.NewLine();
+			return null;
+		}
+		
+		public object Visit(DestructorDeclaration destructorDeclaration, object data)
+		{
+			VisitAttributes(destructorDeclaration.Attributes, data);
+			outputFormatter.Indent();
+			OutputModifier(destructorDeclaration.Modifier);
+			outputFormatter.PrintToken(Tokens.BitwiseComplement);
+			outputFormatter.PrintIdentifier(destructorDeclaration.Name);
+			if (prettyPrintOptions.BeforeConstructorDeclarationParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			
+			OutputBlock(destructorDeclaration.Body, this.prettyPrintOptions.DestructorBraceStyle);
+			return null;
+		}
+		
+		public object Visit(OperatorDeclaration operatorDeclaration, object data)
+		{
+			// TODO: implement me
+//			VisitAttributes(operatorDeclaration.Attributes, data);
+//			outputFormatter.Indent();
+//			OutputModifier(operatorDeclaration.Modifier);
+//			switch (operatorDeclaration.OperatorType) {
+//				case OperatorType.Explicit:
+//					outputFormatter.PrintToken(Tokens.Explicit);
+//					break;
+//				case OperatorType.Implicit:
+//					outputFormatter.PrintToken(Tokens.Implicit);
+//					break;
+//				default:
+//					Visit(operatorDeclaration.OpratorDeclarator.TypeReference, data);
+//					break;
+//			}
+//			outputFormatter.Space();
+//			outputFormatter.PrintToken(Tokens.Operator);
+//			outputFormatter.Space();
+//			if (!operatorDeclaration.OpratorDeclarator.IsConversion) {
+//				outputFormatter.PrintIdentifier(Tokens.GetTokenString(operatorDeclaration.OpratorDeclarator.OverloadOperatorToken));
+//			} else {
+//				Visit(operatorDeclaration.OpratorDeclarator.TypeReference, data);
+//			}
+//
+//			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+//			Visit(operatorDeclaration.OpratorDeclarator.FirstParameterType, data);
+//			outputFormatter.Space();
+//			outputFormatter.PrintIdentifier(operatorDeclaration.OpratorDeclarator.FirstParameterName);
+//			if (operatorDeclaration.OpratorDeclarator.OperatorType == OperatorType.Binary) {
+//				outputFormatter.PrintToken(Tokens.Comma);
+//				outputFormatter.Space();
+//				Visit(operatorDeclaration.OpratorDeclarator.SecondParameterType, data);
+//				outputFormatter.Space();
+//				outputFormatter.PrintIdentifier(operatorDeclaration.OpratorDeclarator.SecondParameterName);
+//			}
+//			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+//
+//			if (operatorDeclaration.Body.IsNull) {
+//				outputFormatter.PrintToken(Tokens.Semicolon);
+//			} else {
+//				outputFormatter.NewLine();
+//				outputFormatter.Indent();
+//				outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+//				outputFormatter.NewLine();
+//				++outputFormatter.IndentationLevel;
+//				operatorDeclaration.Body.AcceptChildren(this, data);
+//				--outputFormatter.IndentationLevel;
+//				outputFormatter.Indent();
+//				outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+//			}
+//			outputFormatter.NewLine();
+			return null;
+		}
+		
+		public object Visit(DeclareDeclaration declareDeclaration, object data)
+		{
+			VisitAttributes(declareDeclaration.Attributes, data);
+			outputFormatter.Indent();
+			outputFormatter.PrintText(String.Format("[System.Runtime.InteropServices.DllImport({0}", declareDeclaration.Library));
+			if (declareDeclaration.Alias != null && declareDeclaration.Alias.Length >0) {
+				outputFormatter.PrintText(String.Format(", EntryPoint={0}", declareDeclaration.Alias));
+			}
+			
+			switch (declareDeclaration.Charset) {
+				case CharsetModifier.ANSI:
+					outputFormatter.PrintText(", CharSet=System.Runtime.InteropServices.CharSet.Ansi");
+					break;
+				case CharsetModifier.Unicode:
+					outputFormatter.PrintText(", CharSet=System.Runtime.InteropServices.CharSet.Unicode");
+					break;
+				case CharsetModifier.Auto:
+					outputFormatter.PrintText(", CharSet=System.Runtime.InteropServices.CharSet.Auto");
+					break;
+			}
+			
+			outputFormatter.PrintText(")]");
+			outputFormatter.NewLine();
+			outputFormatter.Indent();
+			
+			OutputModifier(declareDeclaration.Modifier);
+			outputFormatter.PrintToken(Tokens.Static);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.Extern);
+			outputFormatter.Space();
+			
+			nodeTracker.TrackedVisit(declareDeclaration.TypeReference, data);
+			outputFormatter.Space();
+			outputFormatter.PrintIdentifier(declareDeclaration.Name);
+			
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			AppendCommaSeparatedList(declareDeclaration.Parameters);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			outputFormatter.NewLine();
+			return null;
+		}
+		#endregion
+		
+		#region Statements
+		
+		void OutputBlock(BlockStatement blockStatement, BraceStyle braceStyle)
+		{
+			nodeTracker.BeginNode(blockStatement);
+			if (blockStatement.IsNull) {
+				outputFormatter.PrintToken(Tokens.Semicolon);
+				outputFormatter.NewLine();
+				nodeTracker.EndNode(blockStatement);
+			} else {
+				outputFormatter.BeginBrace(braceStyle);
+				foreach (Statement stmt in blockStatement.Children) {
+					outputFormatter.Indent();
+					nodeTracker.TrackedVisit(stmt, null);
+					if (!outputFormatter.LastCharacterIsNewLine)
+						outputFormatter.NewLine();
+				}
+				nodeTracker.EndNode(blockStatement);
+				outputFormatter.EndBrace();
+			}
+		}
+		
+		public object Visit(BlockStatement blockStatement, object data)
+		{
+			OutputBlock(blockStatement, BraceStyle.NextLine);
+			return null;
+		}
+		
+		public object Visit(AddHandlerStatement addHandlerStatement, object data)
+		{
+			nodeTracker.TrackedVisit(addHandlerStatement.EventExpression, data);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.PlusAssign);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(addHandlerStatement.HandlerExpression, data);
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public object Visit(RemoveHandlerStatement removeHandlerStatement, object data)
+		{
+			nodeTracker.TrackedVisit(removeHandlerStatement.EventExpression, data);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.MinusAssign);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(removeHandlerStatement.HandlerExpression, data);
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public object Visit(RaiseEventStatement raiseEventStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.If);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			outputFormatter.PrintIdentifier(raiseEventStatement.EventName);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.NotEqual);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.Null);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			
+			outputFormatter.BeginBrace(BraceStyle.EndOfLine);
+			
+			outputFormatter.Indent();
+			outputFormatter.PrintIdentifier(raiseEventStatement.EventName);
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			this.AppendCommaSeparatedList(raiseEventStatement.Arguments);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			
+			outputFormatter.NewLine();
+			outputFormatter.EndBrace();
+			
+			return null;
+		}
+		
+		public object Visit(EraseStatement eraseStatement, object data)
+		{
+			foreach (Expression expr in eraseStatement.Expressions) {
+				outputFormatter.Indent();
+				expr.AcceptVisitor(this, data);
+				outputFormatter.Space();
+				outputFormatter.PrintToken(Tokens.Assign);
+				outputFormatter.Space();
+				outputFormatter.PrintToken(Tokens.Null);
+				outputFormatter.PrintToken(Tokens.Semicolon);
+				outputFormatter.NewLine();
+			}
+			return null;
+		}
+		
+		public object Visit(ErrorStatement errorStatement, object data)
+		{
+			errors.Error(-1, -1, String.Format("ErrorStatement is unsupported"));
+			return null;
+		}
+		
+		public object Visit(OnErrorStatement onErrorStatement, object data)
+		{
+			errors.Error(-1, -1, String.Format("OnErrorStatement is unsupported"));
+			return null;
+		}
+		
+		public object Visit(ReDimStatement reDimStatement, object data)
+		{
+			// TODO: implement me
+			errors.Error(-1, -1, String.Format("ReDimStatement is unsupported"));
+			return null;
+		}
+		
+//		public object Visit(ReDimClause reDimClause, object data)
+//		{
+//			// TODO: implement me
+//			errors.Error(-1, -1, String.Format("ReDimClause is unsupported"));
+//			return null;
+//		}
+		
+		public object Visit(StatementExpression statementExpression, object data)
+		{
+			nodeTracker.TrackedVisit(statementExpression.Expression, data);
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public object Visit(LocalVariableDeclaration localVariableDeclaration, object data)
+		{
+			for (int i = 0; i < localVariableDeclaration.Variables.Count; ++i) {
+				VariableDeclaration v = (VariableDeclaration)localVariableDeclaration.Variables[i];
+				outputFormatter.NewLine();
+				outputFormatter.Indent();
+				OutputModifier(localVariableDeclaration.Modifier);
+				nodeTracker.TrackedVisit(localVariableDeclaration.GetTypeForVariable(i), data);
+				outputFormatter.Space();
+				nodeTracker.TrackedVisit(v, data);
+				outputFormatter.PrintToken(Tokens.Semicolon);
+				outputFormatter.NewLine();
+			}
+			return null;
+		}
+		
+		public object Visit(EmptyStatement emptyStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public virtual object Visit(YieldStatement yieldStatement, object data)
+		{
+			Debug.Assert(yieldStatement != null);
+			Debug.Assert(yieldStatement.Statement != null);
+			outputFormatter.PrintText("yield");
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(yieldStatement.Statement, data);
+			return null;
+		}
+		
+		public object Visit(ReturnStatement returnStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Return);
+			if (!returnStatement.Expression.IsNull) {
+				outputFormatter.Space();
+				nodeTracker.TrackedVisit(returnStatement.Expression, data);
+			}
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public object Visit(IfElseStatement ifElseStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.If);
+			if (this.prettyPrintOptions.IfParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(ifElseStatement.Condition, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			foreach (Statement stmt in ifElseStatement.TrueStatement) {
+				nodeTracker.TrackedVisit(stmt, data);
+			}
+			--outputFormatter.IndentationLevel;
+			
+			foreach (ElseIfSection elseIfSection in ifElseStatement.ElseIfSections) {
+				nodeTracker.TrackedVisit(elseIfSection, data);
+			}
+			
+			if (ifElseStatement.HasElseStatements) {
+				outputFormatter.Indent();
+				outputFormatter.PrintToken(Tokens.Else);
+				outputFormatter.NewLine();
+				++outputFormatter.IndentationLevel;
+				foreach (Statement stmt in ifElseStatement.FalseStatement) {
+					nodeTracker.TrackedVisit(stmt, data);
+				}
+				--outputFormatter.IndentationLevel;
+			}
+			
+			return null;
+		}
+		
+		public object Visit(ElseIfSection elseIfSection, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Else);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.If);
+			if (prettyPrintOptions.IfParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(elseIfSection.Condition, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			nodeTracker.TrackedVisit(elseIfSection.EmbeddedStatement, data);
+			outputFormatter.NewLine();
+			--outputFormatter.IndentationLevel;
+			return null;
+		}
+		
+		public object Visit(ForStatement forStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.For);
+			if (this.prettyPrintOptions.ForParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			outputFormatter.DoIndent = false;
+			outputFormatter.DoNewLine = false;
+			outputFormatter.EmitSemicolon = false;
+			for (int i = 0; i < forStatement.Initializers.Count; ++i) {
+				INode node = (INode)forStatement.Initializers[i];
+				nodeTracker.TrackedVisit(node, data);
+				if (i + 1 < forStatement.Initializers.Count) {
+					outputFormatter.PrintToken(Tokens.Comma);
+				}
+			}
+			outputFormatter.EmitSemicolon = true;
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			outputFormatter.EmitSemicolon = false;
+			if (!forStatement.Condition.IsNull) {
+				if (this.prettyPrintOptions.SpacesAfterSemicolon) {
+					outputFormatter.Space();
+				}
+				nodeTracker.TrackedVisit(forStatement.Condition, data);
+			}
+			outputFormatter.EmitSemicolon = true;
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			outputFormatter.EmitSemicolon = false;
+			if (forStatement.Iterator != null && forStatement.Iterator.Count > 0) {
+				if (this.prettyPrintOptions.SpacesAfterSemicolon) {
+					outputFormatter.Space();
+				}
+				
+				for (int i = 0; i < forStatement.Iterator.Count; ++i) {
+					INode node = (INode)forStatement.Iterator[i];
+					nodeTracker.TrackedVisit(node, data);
+					if (i + 1 < forStatement.Iterator.Count) {
+						outputFormatter.PrintToken(Tokens.Comma);
+					}
+				}
+			}
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			outputFormatter.EmitSemicolon = true;
+			outputFormatter.DoNewLine     = true;
+			outputFormatter.DoIndent      = true;
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			if (forStatement.EmbeddedStatement is BlockStatement) {
+				nodeTracker.TrackedVisit(forStatement.EmbeddedStatement, false);
+			} else {
+				nodeTracker.TrackedVisit(forStatement.EmbeddedStatement, data);
+			}
+			outputFormatter.NewLine();
+			--outputFormatter.IndentationLevel;
+			return null;
+		}
+		
+		public object Visit(LabelStatement labelStatement, object data)
+		{
+			outputFormatter.PrintIdentifier(labelStatement.Label);
+			outputFormatter.PrintToken(Tokens.Colon);
+			return null;
+		}
+		
+		public object Visit(GotoStatement gotoStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Goto);
+			outputFormatter.Space();
+			outputFormatter.PrintIdentifier(gotoStatement.Label);
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public object Visit(SwitchStatement switchStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Switch);
+			if (this.prettyPrintOptions.SwitchParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(switchStatement.SwitchExpression, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			foreach (SwitchSection section in switchStatement.SwitchSections) {
+				nodeTracker.TrackedVisit(section, data);
+			}
+			--outputFormatter.IndentationLevel;
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			return null;
+		}
+		
+		public object Visit(SwitchSection switchSection, object data)
+		{
+			foreach (CaseLabel label in switchSection.SwitchLabels) {
+				nodeTracker.TrackedVisit(label, data);
+			}
+			
+			++outputFormatter.IndentationLevel;
+			foreach (Statement stmt in switchSection.Children) {
+				outputFormatter.Indent();
+				nodeTracker.TrackedVisit(stmt, data);
+				outputFormatter.NewLine();
+			}
+			
+			// Check if a 'break' should be auto inserted.
+			if (switchSection.Children.Count == 0 ||
+			    !(switchSection.Children[switchSection.Children.Count - 1] is BreakStatement ||
+			      switchSection.Children[switchSection.Children.Count - 1] is ContinueStatement ||
+			      switchSection.Children[switchSection.Children.Count - 1] is ReturnStatement)) {
+				outputFormatter.Indent();
+				outputFormatter.PrintToken(Tokens.Break);
+				outputFormatter.PrintToken(Tokens.Semicolon);
+				outputFormatter.NewLine();
+			}
+			
+			--outputFormatter.IndentationLevel;
+			return null;
+		}
+		
+		public object Visit(CaseLabel caseLabel, object data)
+		{
+			outputFormatter.Indent();
+			if (caseLabel.IsDefault) {
+				outputFormatter.PrintToken(Tokens.Default);
+			} else {
+				outputFormatter.PrintToken(Tokens.Case);
+				outputFormatter.Space();
+				if (caseLabel.BinaryOperatorType != BinaryOperatorType.None) {
+					errors.Error(-1, -1, String.Format("Case labels with binary operators are unsupported : {0}", caseLabel.BinaryOperatorType));
+				}
+				nodeTracker.TrackedVisit(caseLabel.Label, data);
+			}
+			outputFormatter.PrintToken(Tokens.Colon);
+			outputFormatter.NewLine();
+			return null;
+		}
+		
+		public object Visit(BreakStatement breakStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Break);
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public object Visit(StopStatement stopStatement, object data)
+		{
+			outputFormatter.PrintText("System.Diagnostics.Debugger.Break()");
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public object Visit(ResumeStatement resumeStatement, object data)
+		{
+			errors.Error(-1, -1, String.Format("Resume statement is unsupported."));
+			return null;
+		}
+		
+		public object Visit(EndStatement endStatement, object data)
+		{
+			outputFormatter.PrintText("System.Environment.Exit(0)");
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public object Visit(ContinueStatement continueStatement, object data)
+		{
+			outputFormatter.PrintText("Nemerle.Imperative.Continue ()");
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public object Visit(GotoCaseStatement gotoCaseStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Goto);
+			outputFormatter.Space();
+			if (gotoCaseStatement.IsDefaultCase) {
+				outputFormatter.PrintToken(Tokens.Default);
+			} else {
+				outputFormatter.PrintToken(Tokens.Case);
+				outputFormatter.Space();
+				nodeTracker.TrackedVisit(gotoCaseStatement.Expression, data);
+			}
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		void PrintLoopCheck(DoLoopStatement doLoopStatement)
+		{
+			outputFormatter.PrintToken(Tokens.While);
+			if (this.prettyPrintOptions.WhileParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			
+			if (doLoopStatement.ConditionType == ConditionType.Until) {
+				outputFormatter.PrintToken(Tokens.Not);
+			}
+			
+			nodeTracker.TrackedVisit(doLoopStatement.Condition, null);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+		}
+		
+		public object Visit(DoLoopStatement doLoopStatement, object data)
+		{
+			if (doLoopStatement.ConditionPosition == ConditionPosition.None) {
+				errors.Error(-1, -1, String.Format("Unknown condition position for loop : {0}.", doLoopStatement));
+			}
+			
+			if (doLoopStatement.ConditionPosition == ConditionPosition.Start) {
+				PrintLoopCheck(doLoopStatement);
+			} else {
+				outputFormatter.PrintToken(Tokens.Do);
+			}
+			
+			++outputFormatter.IndentationLevel;
+			if (doLoopStatement.EmbeddedStatement is BlockStatement) {
+				nodeTracker.TrackedVisit(doLoopStatement.EmbeddedStatement, false);
+			} else {
+				nodeTracker.TrackedVisit(doLoopStatement.EmbeddedStatement, data);
+			}
+			--outputFormatter.IndentationLevel;
+			
+			if (doLoopStatement.ConditionPosition == ConditionPosition.End) {
+				PrintLoopCheck(doLoopStatement);
+				outputFormatter.PrintToken(Tokens.Semicolon);
+				outputFormatter.NewLine();
+			}
+			
+			return null;
+		}
+		
+		public object Visit(ForeachStatement foreachStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Foreach);
+			if (this.prettyPrintOptions.ForeachParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(foreachStatement.TypeReference, data);
+			outputFormatter.Space();
+			outputFormatter.PrintIdentifier(foreachStatement.VariableName);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.In);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(foreachStatement.Expression, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			if (foreachStatement.EmbeddedStatement is BlockStatement) {
+				nodeTracker.TrackedVisit(foreachStatement.EmbeddedStatement, false);
+			} else {
+				nodeTracker.TrackedVisit(foreachStatement.EmbeddedStatement, data);
+			}
+			--outputFormatter.IndentationLevel;
+			return null;
+		}
+		
+		public object Visit(LockStatement lockStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Lock);
+			if (this.prettyPrintOptions.LockParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(lockStatement.LockExpression, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			outputFormatter.NewLine();
+			
+			++outputFormatter.IndentationLevel;
+			nodeTracker.TrackedVisit(lockStatement.EmbeddedStatement, data);
+			--outputFormatter.IndentationLevel;
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			return null;
+		}
+		
+		public object Visit(UsingStatement usingStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Using);
+			if (this.prettyPrintOptions.UsingParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			outputFormatter.DoIndent = false;
+			outputFormatter.DoNewLine = false;
+			outputFormatter.EmitSemicolon = false;
+			
+			nodeTracker.TrackedVisit(usingStatement.ResourceAcquisition, data);
+			outputFormatter.DoIndent = true;
+			outputFormatter.DoNewLine = true;
+			outputFormatter.EmitSemicolon = true;
+			
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			outputFormatter.NewLine();
+			
+			++outputFormatter.IndentationLevel;
+			nodeTracker.TrackedVisit(usingStatement.EmbeddedStatement, data);
+			--outputFormatter.IndentationLevel;
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			return null;
+		}
+		
+		public object Visit(WithStatement withStatement, object data)
+		{
+			withExpressionStack.Push(withStatement);
+			nodeTracker.TrackedVisit(withStatement.Body, data);
+			withExpressionStack.Pop();
+			return null;
+		}
+		
+		public object Visit(TryCatchStatement tryCatchStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Try);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			outputFormatter.NewLine();
+			
+			++outputFormatter.IndentationLevel;
+			nodeTracker.TrackedVisit(tryCatchStatement.StatementBlock, data);
+			--outputFormatter.IndentationLevel;
+			
+			foreach (CatchClause catchClause in tryCatchStatement.CatchClauses) {
+				nodeTracker.TrackedVisit(catchClause, data);
+			}
+			
+			if (!tryCatchStatement.FinallyBlock.IsNull) {
+				outputFormatter.Indent();
+				outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+				outputFormatter.Space();
+				outputFormatter.PrintToken(Tokens.Finally);
+				outputFormatter.Space();
+				outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+				outputFormatter.NewLine();
+				++outputFormatter.IndentationLevel;
+				nodeTracker.TrackedVisit(tryCatchStatement.FinallyBlock, data);
+				--outputFormatter.IndentationLevel;
+			}
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			return null;
+		}
+		
+		public object Visit(CatchClause catchClause, object data)
+		{
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.Catch);
+			
+			if (!catchClause.TypeReference.IsNull) {
+				if (this.prettyPrintOptions.CatchParentheses) {
+					outputFormatter.Space();
+				}
+				outputFormatter.PrintToken(Tokens.OpenParenthesis);
+				outputFormatter.PrintIdentifier(catchClause.TypeReference.Type);
+				if (catchClause.VariableName.Length > 0) {
+					outputFormatter.Space();
+					outputFormatter.PrintIdentifier(catchClause.VariableName);
+				}
+				outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			}
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			nodeTracker.TrackedVisit(catchClause.StatementBlock, data);
+			--outputFormatter.IndentationLevel;
+			return null;
+		}
+		
+		public object Visit(ThrowStatement throwStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Throw);
+			if (!throwStatement.Expression.IsNull) {
+				outputFormatter.Space();
+				nodeTracker.TrackedVisit(throwStatement.Expression, data);
+			}
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			return null;
+		}
+		
+		public object Visit(FixedStatement fixedStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Fixed);
+			if (this.prettyPrintOptions.FixedParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(fixedStatement.TypeReference, data);
+			outputFormatter.Space();
+			AppendCommaSeparatedList(fixedStatement.PointerDeclarators);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			if (fixedStatement.EmbeddedStatement is BlockStatement) {
+				nodeTracker.TrackedVisit(fixedStatement.EmbeddedStatement, false);
+			} else {
+				nodeTracker.TrackedVisit(fixedStatement.EmbeddedStatement, data);
+			}
+			--outputFormatter.IndentationLevel;
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			return null;
+		}
+		
+		public object Visit(UnsafeStatement unsafeStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Unsafe);
+			nodeTracker.TrackedVisit(unsafeStatement.Block, data);
+			return null;
+		}
+		
+		public object Visit(CheckedStatement checkedStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Checked);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			nodeTracker.TrackedVisit(checkedStatement.Block, false);
+			--outputFormatter.IndentationLevel;
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			return null;
+		}
+		
+		public object Visit(UncheckedStatement uncheckedStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Unchecked);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			outputFormatter.NewLine();
+			++outputFormatter.IndentationLevel;
+			nodeTracker.TrackedVisit(uncheckedStatement.Block, false);
+			--outputFormatter.IndentationLevel;
+			outputFormatter.Indent();
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			return null;
+		}
+		
+		public object Visit(ExitStatement exitStatement, object data)
+		{
+			if (exitStatement.ExitType == ExitType.Function || exitStatement.ExitType == ExitType.Sub || exitStatement.ExitType == ExitType.Property) {
+				outputFormatter.PrintText("Nemerle.Imperative.Return ()");
+			} else {
+				outputFormatter.PrintText("Nemerle.Imperative.Break ()");
+			}
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			outputFormatter.PrintText("// might not be correct. Was : Exit " + exitStatement.ExitType);
+			outputFormatter.NewLine();
+			return null;
+		}
+		
+		public object Visit(ForNextStatement forNextStatement, object data)
+		{
+			outputFormatter.PrintToken(Tokens.For);
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			if (!forNextStatement.TypeReference.IsNull) {
+				nodeTracker.TrackedVisit(forNextStatement.TypeReference, data);
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintIdentifier(forNextStatement.VariableName);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.Assign);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(forNextStatement.Start, data);
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			outputFormatter.Space();
+			outputFormatter.PrintIdentifier(forNextStatement.VariableName);
+			outputFormatter.Space();
+			PrimitiveExpression pe = forNextStatement.Step as PrimitiveExpression;
+			if (pe == null || !(pe.Value is int) || ((int)pe.Value) >= 0)
+				outputFormatter.PrintToken(Tokens.LessEqual);
+			else
+				outputFormatter.PrintToken(Tokens.GreaterEqual);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(forNextStatement.End, data);
+			outputFormatter.PrintToken(Tokens.Semicolon);
+			outputFormatter.Space();
+			outputFormatter.PrintIdentifier(forNextStatement.VariableName);
+			if (forNextStatement.Step.IsNull) {
+				outputFormatter.PrintToken(Tokens.Increment);
+			} else {
+				outputFormatter.Space();
+				outputFormatter.PrintToken(Tokens.PlusAssign);
+				outputFormatter.Space();
+				nodeTracker.TrackedVisit(forNextStatement.Step, data);
+			}
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			
+			return nodeTracker.TrackedVisit(forNextStatement.EmbeddedStatement, data);
+		}
+		#endregion
+		
+		#region Expressions
+		public object Visit(ClassReferenceExpression classReferenceExpression, object data)
+		{
+			// TODO: implement me (if possible)
+			errors.Error(-1, -1, String.Format("Unsupported expression : {0}", classReferenceExpression));
+			return null;
+		}
+		
+		string ConvertCharLiteral(char ch)
+		{
+			if (ch == '\'') return "\\'";
+			return ConvertChar(ch);
+		}
+		
+		string ConvertChar(char ch)
+		{
+			switch (ch) {
+				case '\\':
+					return "\\\\";
+				case '\0':
+					return "\\0";
+				case '\a':
+					return "\\a";
+				case '\b':
+					return "\\b";
+				case '\f':
+					return "\\f";
+				case '\n':
+					return "\\n";
+				case '\r':
+					return "\\r";
+				case '\t':
+					return "\\t";
+				case '\v':
+					return "\\v";
+				default:
+					if (char.IsControl(ch)) {
+						return "\\u" + (int)ch;
+					} else {
+						return ch.ToString();
+					}
+			}
+		}
+		
+		string ConvertString(string str)
+		{
+			StringBuilder sb = new StringBuilder();
+			foreach (char ch in str) {
+				if (ch == '"')
+					sb.Append("\\\"");
+				else
+					sb.Append(ConvertChar(ch));
+			}
+			return sb.ToString();
+		}
+		
+		public object Visit(PrimitiveExpression primitiveExpression, object data)
+		{
+			if (primitiveExpression.Value == null) {
+				outputFormatter.PrintToken(Tokens.Null);
+				return null;
+			}
+			
+			object val = primitiveExpression.Value;
+			
+			if (val is bool) {
+				if ((bool)val) {
+					outputFormatter.PrintToken(Tokens.True);
+				} else {
+					outputFormatter.PrintToken(Tokens.False);
+				}
+				return null;
+			}
+			
+			if (val is string) {
+				outputFormatter.PrintText('"' + ConvertString(val.ToString()) + '"');
+				return null;
+			}
+			
+			if (val is char) {
+				outputFormatter.PrintText("'" + ConvertCharLiteral((char)val) + "'");
+				return null;
+			}
+			
+			if (val is decimal) {
+				outputFormatter.PrintText(((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m");
+				return null;
+			}
+			
+			if (val is float) {
+				outputFormatter.PrintText(((float)val).ToString(NumberFormatInfo.InvariantInfo) + "f");
+				return null;
+			}
+			
+			if (val is double) {
+				string text = ((double)val).ToString(NumberFormatInfo.InvariantInfo);
+				if (text.IndexOf('.') < 0 && text.IndexOf('E') < 0)
+					outputFormatter.PrintText(text + ".0");
+				else
+					outputFormatter.PrintText(text);
+				return null;
+			}
+			
+			if (val is IFormattable) {
+				outputFormatter.PrintText(((IFormattable)val).ToString(null, NumberFormatInfo.InvariantInfo));
+				if (val is uint || val is ulong) {
+					outputFormatter.PrintText("u");
+				}
+				if (val is long || val is ulong) {
+					outputFormatter.PrintText("l");
+				}
+			} else {
+				outputFormatter.PrintText(val.ToString());
+			}
+			
+			return null;
+		}
+		
+		bool IsNullLiteralExpression(Expression expr)
+		{
+			PrimitiveExpression pe = expr as PrimitiveExpression;
+			if (pe == null) return false;
+			return pe.Value == null;
+		}
+		
+		public object Visit(BinaryOperatorExpression binaryOperatorExpression, object data)
+		{
+			// VB-operators that require special representation:
+			switch (binaryOperatorExpression.Op) {
+				case BinaryOperatorType.ReferenceEquality:
+				case BinaryOperatorType.ReferenceInequality:
+					if (IsNullLiteralExpression(binaryOperatorExpression.Left) || IsNullLiteralExpression(binaryOperatorExpression.Right)) {
+						// prefer a == null to object.ReferenceEquals(a, null)
+						break;
+					}
+					
+					if (binaryOperatorExpression.Op == BinaryOperatorType.ReferenceInequality)
+						outputFormatter.PrintToken(Tokens.Not);
+					outputFormatter.PrintText("object.ReferenceEquals");
+					if (prettyPrintOptions.BeforeMethodCallParentheses) {
+						outputFormatter.Space();
+					}
+					
+					outputFormatter.PrintToken(Tokens.OpenParenthesis);
+					nodeTracker.TrackedVisit(binaryOperatorExpression.Left, data);
+					PrintFormattedComma();
+					nodeTracker.TrackedVisit(binaryOperatorExpression.Right, data);
+					outputFormatter.PrintToken(Tokens.CloseParenthesis);
+					return null;
+			}
+			nodeTracker.TrackedVisit(binaryOperatorExpression.Left, data);
+			switch (binaryOperatorExpression.Op) {
+				case BinaryOperatorType.Add:
+					if (prettyPrintOptions.AroundAdditiveOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.Plus);
+					if (prettyPrintOptions.AroundAdditiveOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+					
+				case BinaryOperatorType.Subtract:
+					if (prettyPrintOptions.AroundAdditiveOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.Minus);
+					if (prettyPrintOptions.AroundAdditiveOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+					
+				case BinaryOperatorType.Multiply:
+					if (prettyPrintOptions.AroundMultiplicativeOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.Times);
+					if (prettyPrintOptions.AroundMultiplicativeOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+					
+				case BinaryOperatorType.Divide:
+				case BinaryOperatorType.DivideInteger:
+					if (prettyPrintOptions.AroundMultiplicativeOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.Div);
+					if (prettyPrintOptions.AroundMultiplicativeOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+					
+				case BinaryOperatorType.Modulus:
+					if (prettyPrintOptions.AroundMultiplicativeOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.Mod);
+					if (prettyPrintOptions.AroundMultiplicativeOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+					
+				case BinaryOperatorType.ShiftLeft:
+					if (prettyPrintOptions.AroundShiftOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.ShiftLeft);
+					if (prettyPrintOptions.AroundShiftOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+					
+				case BinaryOperatorType.ShiftRight:
+					if (prettyPrintOptions.AroundShiftOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.GreaterThan);
+					outputFormatter.PrintToken(Tokens.GreaterThan);
+					if (prettyPrintOptions.AroundShiftOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+					
+				case BinaryOperatorType.BitwiseAnd:
+					if (prettyPrintOptions.AroundBitwiseOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.BitwiseAnd);
+					if (prettyPrintOptions.AroundBitwiseOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+				case BinaryOperatorType.BitwiseOr:
+					if (prettyPrintOptions.AroundBitwiseOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.BitwiseOr);
+					if (prettyPrintOptions.AroundBitwiseOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+				case BinaryOperatorType.ExclusiveOr:
+					if (prettyPrintOptions.AroundBitwiseOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.Xor);
+					if (prettyPrintOptions.AroundBitwiseOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+					
+				case BinaryOperatorType.LogicalAnd:
+					if (prettyPrintOptions.AroundLogicalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.LogicalAnd);
+					if (prettyPrintOptions.AroundLogicalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+				case BinaryOperatorType.LogicalOr:
+					if (prettyPrintOptions.AroundLogicalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.LogicalOr);
+					if (prettyPrintOptions.AroundLogicalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+					
+				case BinaryOperatorType.AsCast:
+					outputFormatter.Space();
+					outputFormatter.PrintToken(Tokens.As);
+					outputFormatter.Space();
+					break;
+					
+				case BinaryOperatorType.TypeCheck:
+					outputFormatter.Space();
+					outputFormatter.PrintToken(Tokens.Is);
+					outputFormatter.Space();
+					break;
+					
+				case BinaryOperatorType.Equality:
+				case BinaryOperatorType.ReferenceEquality:
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.Equal);
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+				case BinaryOperatorType.GreaterThan:
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.GreaterThan);
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+				case BinaryOperatorType.GreaterThanOrEqual:
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.GreaterEqual);
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+				case BinaryOperatorType.InEquality:
+				case BinaryOperatorType.ReferenceInequality:
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.NotEqual);
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+				case BinaryOperatorType.LessThan:
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.LessThan);
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+				case BinaryOperatorType.LessThanOrEqual:
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.LessEqual);
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+				case BinaryOperatorType.NullCoalescing:
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					outputFormatter.PrintToken(Tokens.DoubleQuestion);
+					if (prettyPrintOptions.AroundRelationalOperatorParentheses) {
+						outputFormatter.Space();
+					}
+					break;
+				default:
+					errors.Error(-1, -1, String.Format("Unknown binary operator {0}", binaryOperatorExpression.Op));
+					return null;
+			}
+			nodeTracker.TrackedVisit(binaryOperatorExpression.Right, data);
+			return null;
+		}
+		
+		public object Visit(ParenthesizedExpression parenthesizedExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(parenthesizedExpression.Expression, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			return null;
+		}
+		
+		public object Visit(InvocationExpression invocationExpression, object data)
+		{
+			nodeTracker.TrackedVisit(invocationExpression.TargetObject, data);
+			
+			if (invocationExpression.TypeArguments != null && invocationExpression.TypeArguments.Count > 0) {
+				outputFormatter.PrintToken(Tokens.LessThan);
+				AppendCommaSeparatedList(invocationExpression.TypeArguments);
+				outputFormatter.PrintToken(Tokens.GreaterThan);
+			}
+			
+			if (prettyPrintOptions.BeforeMethodCallParentheses) {
+				outputFormatter.Space();
+			}
+			
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			AppendCommaSeparatedList(invocationExpression.Arguments);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			return null;
+		}
+		
+		public object Visit(IdentifierExpression identifierExpression, object data)
+		{
+			outputFormatter.PrintIdentifier(identifierExpression.Identifier);
+			return null;
+		}
+		
+		public object Visit(TypeReferenceExpression typeReferenceExpression, object data)
+		{
+			nodeTracker.TrackedVisit(typeReferenceExpression.TypeReference, data);
+			return null;
+		}
+		
+		public object Visit(UnaryOperatorExpression unaryOperatorExpression, object data)
+		{
+			switch (unaryOperatorExpression.Op) {
+				case UnaryOperatorType.BitNot:
+					outputFormatter.PrintToken(Tokens.BitwiseComplement);
+					break;
+				case UnaryOperatorType.Decrement:
+					outputFormatter.PrintToken(Tokens.Decrement);
+					break;
+				case UnaryOperatorType.Increment:
+					outputFormatter.PrintToken(Tokens.Increment);
+					break;
+				case UnaryOperatorType.Minus:
+					outputFormatter.PrintToken(Tokens.Minus);
+					break;
+				case UnaryOperatorType.Not:
+					outputFormatter.PrintToken(Tokens.Not);
+					break;
+				case UnaryOperatorType.Plus:
+					outputFormatter.PrintToken(Tokens.Plus);
+					break;
+				case UnaryOperatorType.PostDecrement:
+					nodeTracker.TrackedVisit(unaryOperatorExpression.Expression, data);
+					outputFormatter.PrintToken(Tokens.Decrement);
+					return null;
+				case UnaryOperatorType.PostIncrement:
+					nodeTracker.TrackedVisit(unaryOperatorExpression.Expression, data);
+					outputFormatter.PrintToken(Tokens.Increment);
+					return null;
+				case UnaryOperatorType.Star:
+					outputFormatter.PrintToken(Tokens.Times);
+					break;
+				case UnaryOperatorType.BitWiseAnd:
+					outputFormatter.PrintToken(Tokens.BitwiseAnd);
+					break;
+				default:
+					errors.Error(-1, -1, String.Format("Unknown unary operator {0}", unaryOperatorExpression.Op));
+					return null;
+			}
+			nodeTracker.TrackedVisit(unaryOperatorExpression.Expression, data);
+			return null;
+		}
+		
+		public object Visit(AssignmentExpression assignmentExpression, object data)
+		{
+			nodeTracker.TrackedVisit(assignmentExpression.Left, data);
+			if (this.prettyPrintOptions.AroundAssignmentParentheses) {
+				outputFormatter.Space();
+			}
+			switch (assignmentExpression.Op) {
+				case AssignmentOperatorType.Assign:
+					outputFormatter.PrintToken(Tokens.Assign);
+					break;
+				case AssignmentOperatorType.Add:
+					outputFormatter.PrintToken(Tokens.PlusAssign);
+					break;
+				case AssignmentOperatorType.Subtract:
+					outputFormatter.PrintToken(Tokens.MinusAssign);
+					break;
+				case AssignmentOperatorType.Multiply:
+					outputFormatter.PrintToken(Tokens.TimesAssign);
+					break;
+				case AssignmentOperatorType.Divide:
+					outputFormatter.PrintToken(Tokens.DivAssign);
+					break;
+				case AssignmentOperatorType.ShiftLeft:
+					outputFormatter.PrintToken(Tokens.ShiftLeftAssign);
+					break;
+				case AssignmentOperatorType.ShiftRight:
+					outputFormatter.PrintToken(Tokens.GreaterThan);
+					outputFormatter.PrintToken(Tokens.GreaterEqual);
+					break;
+				case AssignmentOperatorType.ExclusiveOr:
+					outputFormatter.PrintToken(Tokens.XorAssign);
+					break;
+				case AssignmentOperatorType.Modulus:
+					outputFormatter.PrintToken(Tokens.ModAssign);
+					break;
+				case AssignmentOperatorType.BitwiseAnd:
+					outputFormatter.PrintToken(Tokens.BitwiseAndAssign);
+					break;
+				case AssignmentOperatorType.BitwiseOr:
+					outputFormatter.PrintToken(Tokens.BitwiseOrAssign);
+					break;
+				default:
+					errors.Error(-1, -1, String.Format("Unknown assignment operator {0}", assignmentExpression.Op));
+					return null;
+			}
+			if (this.prettyPrintOptions.AroundAssignmentParentheses) {
+				outputFormatter.Space();
+			}
+			nodeTracker.TrackedVisit(assignmentExpression.Right, data);
+			return null;
+		}
+		
+		public object Visit(SizeOfExpression sizeOfExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Sizeof);
+			if (prettyPrintOptions.SizeOfParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(sizeOfExpression.TypeReference, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			return null;
+		}
+		
+		public object Visit(TypeOfExpression typeOfExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Typeof);
+			if (prettyPrintOptions.TypeOfParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(typeOfExpression.TypeReference, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			return null;
+		}
+		
+		public object Visit(DefaultValueExpression defaultValueExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Default);
+			if (prettyPrintOptions.TypeOfParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(defaultValueExpression.TypeReference, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			return null;
+		}
+		
+		public object Visit(TypeOfIsExpression typeOfIsExpression, object data)
+		{
+			nodeTracker.TrackedVisit(typeOfIsExpression.Expression, data);
+			outputFormatter.Space();
+			outputFormatter.PrintToken(Tokens.Is);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(typeOfIsExpression.TypeReference, data);
+			return null;
+		}
+		
+		public object Visit(AddressOfExpression addressOfExpression, object data)
+		{
+			// TODO: implement me
+			errors.Error(-1, -1, String.Format("Unsupported expression : {0}", addressOfExpression));
+//			DebugOutput(addressOfExpression);
+//			string procedureName    = addressOfExpression.Procedure.AcceptVisitor(this, data).ToString();
+//			string eventHandlerType = "EventHandler";
+//			bool   foundEventHandler = false;
+//			// try to resolve the type of the eventhandler using a little trick :)
+//			foreach (INode node in currentType.Children) {
+//				MethodDeclaration md = node as MethodDeclaration;
+//				if (md != null && md.Parameters != null && md.Parameters.Count > 0) {
+//					if (procedureName == md.Name || procedureName.EndsWith("." + md.Name)) {
+//						ParameterDeclarationExpression pde = (ParameterDeclarationExpression)md.Parameters[md.Parameters.Count - 1];
+//						string typeName = GetTypeString(pde.TypeReference);
+//						if (typeName.EndsWith("Args")) {
+//							eventHandlerType = typeName.Substring(0, typeName.Length - "Args".Length) + "Handler";
+//							foundEventHandler = true;
+//						}
+//					}
+//				}
+//			}
+//			return String.Concat(foundEventHandler ? "new " : "/* might be wrong, please check */ new ",
+//			                     eventHandlerType,
+//			                     "(",
+//			                     procedureName,
+//			                     ")");
+			return null;
+		}
+		
+		public object Visit(AnonymousMethodExpression anonymousMethodExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Delegate);
+			
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			AppendCommaSeparatedList(anonymousMethodExpression.Parameters);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			OutputBlock(anonymousMethodExpression.Body, this.prettyPrintOptions.MethodBraceStyle);
+			
+			return null;
+		}
+		
+		public object Visit(CheckedExpression checkedExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Checked);
+			if (prettyPrintOptions.CheckedParentheses) {
+				outputFormatter.Space();
+			}
+			
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(checkedExpression.Expression, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			return null;
+		}
+		
+		public object Visit(UncheckedExpression uncheckedExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Unchecked);
+			if (prettyPrintOptions.UncheckedParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(uncheckedExpression.Expression, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			return null;
+		}
+		
+		public object Visit(PointerReferenceExpression pointerReferenceExpression, object data)
+		{
+			nodeTracker.TrackedVisit(pointerReferenceExpression.TargetObject, data);
+			outputFormatter.PrintToken(Tokens.Pointer);
+			outputFormatter.PrintIdentifier(pointerReferenceExpression.Identifier);
+			return null;
+		}
+		
+		public object Visit(CastExpression castExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			nodeTracker.TrackedVisit(castExpression.CastTo, data);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			if (this.prettyPrintOptions.SpacesAfterTypeCast) {
+				outputFormatter.Space();
+			}
+			nodeTracker.TrackedVisit(castExpression.Expression, data);
+			return null;
+		}
+		
+		public object Visit(StackAllocExpression stackAllocExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.Stackalloc);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(stackAllocExpression.TypeReference, data);
+			outputFormatter.PrintToken(Tokens.OpenSquareBracket);
+			if (this.prettyPrintOptions.SpacesWithinBrackets) {
+				outputFormatter.Space();
+			}
+			nodeTracker.TrackedVisit(stackAllocExpression.Expression, data);
+			if (this.prettyPrintOptions.SpacesWithinBrackets) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.CloseSquareBracket);
+			return null;
+		}
+		
+		public object Visit(IndexerExpression indexerExpression, object data)
+		{
+			nodeTracker.TrackedVisit(indexerExpression.TargetObject, data);
+			outputFormatter.PrintToken(Tokens.OpenSquareBracket);
+			if (this.prettyPrintOptions.SpacesWithinBrackets) {
+				outputFormatter.Space();
+			}
+			AppendCommaSeparatedList(indexerExpression.Indices);
+			if (this.prettyPrintOptions.SpacesWithinBrackets) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.CloseSquareBracket);
+			return null;
+		}
+		
+		public object Visit(ThisReferenceExpression thisReferenceExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.This);
+			return null;
+		}
+		
+		public object Visit(BaseReferenceExpression baseReferenceExpression, object data) {
+			outputFormatter.PrintToken(Tokens.Base);
+			return null;
+		}
+		
+		public object Visit(ObjectCreateExpression objectCreateExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.New);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(objectCreateExpression.CreateType, data);
+			if (prettyPrintOptions.NewParentheses) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.OpenParenthesis);
+			AppendCommaSeparatedList(objectCreateExpression.Parameters);
+			outputFormatter.PrintToken(Tokens.CloseParenthesis);
+			return null;
+		}
+		
+		public object Visit(ArrayCreateExpression arrayCreateExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.New);
+			outputFormatter.Space();
+			nodeTracker.TrackedVisit(arrayCreateExpression.CreateType, data);
+			for (int i = 0; i < arrayCreateExpression.Parameters.Count; ++i) {
+				outputFormatter.PrintToken(Tokens.OpenSquareBracket);
+				if (this.prettyPrintOptions.SpacesWithinBrackets) {
+					outputFormatter.Space();
+				}
+				nodeTracker.TrackedVisit((INode)arrayCreateExpression.Parameters[i], data);
+				if (this.prettyPrintOptions.SpacesWithinBrackets) {
+					outputFormatter.Space();
+				}
+				outputFormatter.PrintToken(Tokens.CloseSquareBracket);
+			}
+			
+			
+			if (!arrayCreateExpression.ArrayInitializer.IsNull) {
+				outputFormatter.Space();
+				nodeTracker.TrackedVisit(arrayCreateExpression.ArrayInitializer, data);
+			}
+			return null;
+		}
+		
+		public object Visit(FieldReferenceExpression fieldReferenceExpression, object data)
+		{
+			Expression target = fieldReferenceExpression.TargetObject;
+			if (target.IsNull && withExpressionStack.Count > 0) {
+				target = ((WithStatement)withExpressionStack.Peek()).Expression;
+			}
+			
+			nodeTracker.TrackedVisit(target, data);
+			outputFormatter.PrintToken(Tokens.Dot);
+			outputFormatter.PrintIdentifier(fieldReferenceExpression.FieldName);
+			return null;
+		}
+		
+		public object Visit(DirectionExpression directionExpression, object data)
+		{
+			switch (directionExpression.FieldDirection) {
+				case FieldDirection.Out:
+					outputFormatter.PrintToken(Tokens.Out);
+					outputFormatter.Space();
+					break;
+				case FieldDirection.Ref:
+					outputFormatter.PrintToken(Tokens.Ref);
+					outputFormatter.Space();
+					break;
+			}
+			nodeTracker.TrackedVisit(directionExpression.Expression, data);
+			return null;
+		}
+		
+		public object Visit(ArrayInitializerExpression arrayInitializerExpression, object data)
+		{
+			outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
+			this.AppendCommaSeparatedList(arrayInitializerExpression.CreateExpressions);
+			outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
+			return null;
+		}
+		
+		public object Visit(ConditionalExpression conditionalExpression, object data)
+		{
+			nodeTracker.TrackedVisit(conditionalExpression.Condition, data);
+			if (this.prettyPrintOptions.ConditionalOperatorBeforeConditionSpace) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.Question);
+			if (this.prettyPrintOptions.ConditionalOperatorAfterConditionSpace) {
+				outputFormatter.Space();
+			}
+			nodeTracker.TrackedVisit(conditionalExpression.TrueExpression, data);
+			if (this.prettyPrintOptions.ConditionalOperatorBeforeSeparatorSpace) {
+				outputFormatter.Space();
+			}
+			outputFormatter.PrintToken(Tokens.Colon);
+			if (this.prettyPrintOptions.ConditionalOperatorAfterSeparatorSpace) {
+				outputFormatter.Space();
+			}
+			nodeTracker.TrackedVisit(conditionalExpression.FalseExpression, data);
+			return null;
+		}
+		
+		public object Visit(ArrayCreationParameter arrayCreationParameter, object data)
+		{
+			if (arrayCreationParameter.IsExpressionList) {
+				AppendCommaSeparatedList(arrayCreationParameter.Expressions);
+			} else {
+				for (int j = 0; j < arrayCreationParameter.Dimensions; ++j) {
+					outputFormatter.PrintToken(Tokens.Comma);
+				}
+			}
+			return null;
+		}
+		
+		#endregion
+		#endregion
+		
+		void OutputModifier(ParamModifier modifier)
+		{
+			switch (modifier) {
+				case ParamModifier.None:
+				case ParamModifier.In:
+					break;
+				case ParamModifier.Out:
+					outputFormatter.PrintToken(Tokens.Out);
+					outputFormatter.Space();
+					break;
+				case ParamModifier.Params:
+					outputFormatter.PrintToken(Tokens.Params);
+					outputFormatter.Space();
+					break;
+				case ParamModifier.Ref:
+					outputFormatter.PrintToken(Tokens.Ref);
+					outputFormatter.Space();
+					break;
+				case ParamModifier.Optional:
+					errors.Error(-1, -1, String.Format("Optional parameters aren't supported in C#"));
+					break;
+				default:
+					errors.Error(-1, -1, String.Format("Unsupported modifier : {0}", modifier));
+					break;
+			}
+		}
+		
+		void OutputModifier(Modifier modifier)
+		{
+			ArrayList tokenList = new ArrayList();
+			if ((modifier & Modifier.Unsafe) != 0) {
+				tokenList.Add(Tokens.Unsafe);
+			}
+			if ((modifier & Modifier.Public) != 0) {
+				tokenList.Add(Tokens.Public);
+			}
+			if ((modifier & Modifier.Private) != 0) {
+				tokenList.Add(Tokens.Private);
+			}
+			if ((modifier & Modifier.Protected) != 0) {
+				tokenList.Add(Tokens.Protected);
+			}
+			if ((modifier & Modifier.Static) != 0) {
+				tokenList.Add(Tokens.Static);
+			}
+			if ((modifier & Modifier.Internal) != 0) {
+				tokenList.Add(Tokens.Internal);
+			}
+			if ((modifier & Modifier.Override) != 0) {
+				tokenList.Add(Tokens.Override);
+			}
+			if ((modifier & Modifier.Abstract) != 0) {
+				tokenList.Add(Tokens.Abstract);
+			}
+			if ((modifier & Modifier.Virtual) != 0) {
+				tokenList.Add(Tokens.Virtual);
+			}
+			if ((modifier & Modifier.New) != 0) {
+				tokenList.Add(Tokens.New);
+			}
+			if ((modifier & Modifier.Sealed) != 0) {
+				tokenList.Add(Tokens.Sealed);
+			}
+			if ((modifier & Modifier.Extern) != 0) {
+				tokenList.Add(Tokens.Extern);
+			}
+			if ((modifier & Modifier.Const) != 0) {
+				tokenList.Add(Tokens.Const);
+			}
+			if ((modifier & Modifier.Readonly) != 0) {
+				tokenList.Add(Tokens.Readonly);
+			}
+			if ((modifier & Modifier.Volatile) != 0) {
+				tokenList.Add(Tokens.Volatile);
+			}
+			outputFormatter.PrintTokenList(tokenList);
+			
+			if ((modifier & Modifier.Partial) != 0) {
+				outputFormatter.PrintText("partial ");
+			}
+		}
+		
+		void AppendCommaSeparatedList(IList list)
+		{
+			if (list != null) {
+				for (int i = 0; i < list.Count; ++i) {
+					nodeTracker.TrackedVisit(((INode)list[i]), null);
+					if (i + 1 < list.Count) {
+						PrintFormattedComma();
+					}
+					if ((i + 1) % 10 == 0) {
+						outputFormatter.NewLine();
+						outputFormatter.Indent();
+					}
+				}
+			}
+		}
+	}
+}

Added: corsavy-addin/trunk/Src/NRefactory/Output/OutputFormatter.cs
==============================================================================
--- (empty file)
+++ corsavy-addin/trunk/Src/NRefactory/Output/OutputFormatter.cs	Mon Nov  7 22:48:37 2005
@@ -0,0 +1,135 @@
+ďťż// <file>
+//     <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
+//     <license see="prj:///doc/license.txt">GNU General Public License</license>
+//     <owner name="Mike KrĂźger" email="mike at icsharpcode.net"/>
+//     <version>$Revision: 230 $</version>
+// </file>
+
+using System.Text;
+using System.Collections;
+using System.Diagnostics;
+
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.CSharp;
+using ICSharpCode.NRefactory.Parser.AST;
+using ICSharpCode.NRefactory.PrettyPrinter;
+
+namespace NemerleBinding
+{
+	public sealed class NemerleOutputFormatter : AbstractOutputFormatter
+	{
+		PrettyPrintOptions prettyPrintOptions;
+		
+		bool          emitSemicolon  = true;
+		
+		public bool EmitSemicolon {
+			get {
+				return emitSemicolon;
+			}
+			set {
+				emitSemicolon = value;
+			}
+		}
+		
+		public NemerleOutputFormatter(PrettyPrintOptions prettyPrintOptions) : base(prettyPrintOptions)
+		{
+			this.prettyPrintOptions = prettyPrintOptions;
+		}
+		
+		public override void PrintToken(int token)
+		{
+			if (token == Tokens.Semicolon && !EmitSemicolon) {
+				return;
+			}
+			PrintText(Tokens.GetTokenString(token));
+		}
+		
+		Stack braceStack = new Stack();
+		
+		public void BeginBrace(BraceStyle style)
+		{
+			switch (style) {
+				case BraceStyle.EndOfLine:
+					Space();
+					PrintToken(Tokens.OpenCurlyBrace);
+					NewLine();
+					++IndentationLevel;
+					break;
+				case BraceStyle.NextLine:
+					NewLine();
+					Indent();
+					PrintToken(Tokens.OpenCurlyBrace);
+					NewLine();
+					++IndentationLevel;
+					break;
+				case BraceStyle.NextLineShifted:
+					NewLine();
+					++IndentationLevel;
+					Indent();
+					PrintToken(Tokens.OpenCurlyBrace);
+					NewLine();
+					break;
+				case BraceStyle.NextLineShifted2:
+					NewLine();
+					++IndentationLevel;
+					Indent();
+					PrintToken(Tokens.OpenCurlyBrace);
+					NewLine();
+					++IndentationLevel;
+					break;
+			}
+			braceStack.Push(style);
+		}
+		
+		public void EndBrace()
+		{
+			BraceStyle style = (BraceStyle)braceStack.Pop();
+			switch (style) {
+				case BraceStyle.EndOfLine:
+				case BraceStyle.NextLine:
+					--IndentationLevel;
+					Indent();
+					PrintToken(Tokens.CloseCurlyBrace);
+					NewLine();
+					break;
+				case BraceStyle.NextLineShifted:
+					Indent();
+					PrintToken(Tokens.CloseCurlyBrace);
+					NewLine();
+					--IndentationLevel;
+					break;
+				case BraceStyle.NextLineShifted2:
+					--IndentationLevel;
+					Indent();
+					PrintToken(Tokens.CloseCurlyBrace);
+					NewLine();
+					--IndentationLevel;
+					break;
+			}
+		}
+		
+		public override void PrintIdentifier(string identifier)
+		{
+			if (Keywords.GetToken(identifier) >= 0)
+				PrintText("@");
+			PrintText(identifier);
+		}
+		
+		public override void PrintComment(Comment comment)
+		{
+			switch (comment.CommentType) {
+				case CommentType.Block:	
+					PrintText("/*");
+					PrintText(comment.CommentText);
+					PrintText("*/");
+					break;
+				case CommentType.Documentation:
+					WriteInPreviousLine("///" + comment.CommentText);
+					break;
+				default:
+					WriteInPreviousLine("//" + comment.CommentText);
+					break;
+			}
+		}
+	}
+}

Added: corsavy-addin/trunk/Src/NRefactory/Output/PrettyPrintOptions.cs
==============================================================================
--- (empty file)
+++ corsavy-addin/trunk/Src/NRefactory/Output/PrettyPrintOptions.cs	Mon Nov  7 22:48:37 2005
@@ -0,0 +1,505 @@
+ďťż// <file>
+//     <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
+//     <license see="prj:///doc/license.txt">GNU General Public License</license>
+//     <owner name="Mike KrĂźger" email="mike at icsharpcode.net"/>
+//     <version>$Revision: 230 $</version>
+// </file>
+
+using System.Text;
+using System.Collections;
+using System.Diagnostics;
+
+using ICSharpCode.NRefactory.Parser;
+using ICSharpCode.NRefactory.Parser.AST;
+using ICSharpCode.NRefactory.PrettyPrinter;
+
+namespace NemerleBinding
+{
+	public enum BraceStyle {
+		EndOfLine,
+		NextLine,
+		NextLineShifted,
+		NextLineShifted2
+	}
+	
+	/// <summary>
+	/// Description of PrettyPrintOptions.	
+	/// </summary>
+	public class PrettyPrintOptions : AbstractPrettyPrintOptions
+	{
+		#region BraceStyle
+		BraceStyle nameSpaceBraceStyle = BraceStyle.NextLine;
+		BraceStyle classBraceStyle     = BraceStyle.NextLine;
+		BraceStyle interfaceBraceStyle = BraceStyle.NextLine;
+		BraceStyle structBraceStyle    = BraceStyle.NextLine;
+		BraceStyle enumBraceStyle      = BraceStyle.NextLine;
+		
+		BraceStyle constructorBraceStyle  = BraceStyle.NextLine;
+		BraceStyle destructorBraceStyle   = BraceStyle.NextLine;
+		BraceStyle methodBraceStyle       = BraceStyle.NextLine;
+		
+		BraceStyle propertyBraceStyle     = BraceStyle.EndOfLine;
+		BraceStyle propertyGetBraceStyle  = BraceStyle.EndOfLine;
+		BraceStyle propertySetBraceStyle  = BraceStyle.EndOfLine;
+		
+		BraceStyle eventAddBraceStyle     = BraceStyle.EndOfLine;
+		BraceStyle eventRemoveBraceStyle  = BraceStyle.EndOfLine;
+		
+		public BraceStyle NameSpaceBraceStyle {
+			get {
+				return nameSpaceBraceStyle;
+			}
+			set {
+				nameSpaceBraceStyle = value;
+			}
+		}
+		
+		public BraceStyle ClassBraceStyle {
+			get {
+				return classBraceStyle;
+			}
+			set {
+				classBraceStyle = value;
+			}
+		}
+		
+		public BraceStyle InterfaceBraceStyle {
+			get {
+				return interfaceBraceStyle;
+			}
+			set {
+				interfaceBraceStyle = value;
+			}
+		}
+		
+		public BraceStyle StructBraceStyle {
+			get {
+				return structBraceStyle;
+			}
+			set {
+				structBraceStyle = value;
+			}
+		}
+		
+		public BraceStyle EnumBraceStyle {
+			get {
+				return enumBraceStyle;
+			}
+			set {
+				enumBraceStyle = value;
+			}
+		}
+		
+		
+		public BraceStyle ConstructorBraceStyle {
+			get {
+				return constructorBraceStyle;
+			}
+			set {
+				constructorBraceStyle = value;
+			}
+		}
+		
+		public BraceStyle DestructorBraceStyle {
+			get {
+				return destructorBraceStyle;
+			}
+			set {
+				destructorBraceStyle = value;
+			}
+		}
+		
+		public BraceStyle MethodBraceStyle {
+			get {
+				return methodBraceStyle;
+			}
+			set {
+				methodBraceStyle = value;
+			}
+		}
+		
+		public BraceStyle PropertyBraceStyle {
+			get {
+				return propertyBraceStyle;
+			}
+			set {
+				propertyBraceStyle = value;
+			}
+		}
+		public BraceStyle PropertyGetBraceStyle {
+			get {
+				return propertyGetBraceStyle;
+			}
+			set {
+				propertyGetBraceStyle = value;
+			}
+		}
+		public BraceStyle PropertySetBraceStyle {
+			get {
+				return propertySetBraceStyle;
+			}
+			set {
+				propertySetBraceStyle = value;
+			}
+		}
+		
+		public BraceStyle EventAddBraceStyle {
+			get {
+				return eventAddBraceStyle;
+			}
+			set {
+				eventAddBraceStyle = value;
+			}
+		}
+		public BraceStyle EventRemoveBraceStyle {
+			get {
+				return eventRemoveBraceStyle;
+			}
+			set {
+				eventRemoveBraceStyle = value;
+			}
+		}
+		#endregion
+		
+		#region Before Parentheses
+		bool beforeMethodCallParentheses        = false;
+		bool beforeDelegateDeclarationParentheses = false;
+		bool beforeMethodDeclarationParentheses = false;
+		bool beforeConstructorDeclarationParentheses = false;
+		
+		bool ifParentheses      = true;
+		bool whileParentheses   = true;
+		bool forParentheses     = true;
+		bool foreachParentheses = true;
+		bool catchParentheses   = true;
+		bool switchParentheses  = true;
+		bool lockParentheses    = true;
+		bool usingParentheses   = true;
+		bool fixedParentheses   = true;
+		bool sizeOfParentheses  = false;
+		bool typeOfParentheses  = false;
+		bool checkedParentheses  = false;
+		bool uncheckedParentheses  = false;
+		bool newParentheses  = false;
+		
+		public bool CheckedParentheses {
+			get {
+				return checkedParentheses;
+			}
+			set {
+				checkedParentheses = value;
+			}
+		}
+		public bool NewParentheses {
+			get {
+				return newParentheses;
+			}
+			set {
+				newParentheses = value;
+			}
+		}
+		public bool SizeOfParentheses {
+			get {
+				return sizeOfParentheses;
+			}
+			set {
+				sizeOfParentheses = value;
+			}
+		}
+		public bool TypeOfParentheses {
+			get {
+				return typeOfParentheses;
+			}
+			set {
+				typeOfParentheses = value;
+			}
+		}
+		public bool UncheckedParentheses {
+			get {
+				return uncheckedParentheses;
+			}
+			set {
+				uncheckedParentheses = value;
+			}
+		}
+		
+		public bool BeforeConstructorDeclarationParentheses {
+			get {
+				return beforeConstructorDeclarationParentheses;
+			}
+			set {
+				beforeConstructorDeclarationParentheses = value;
+			}
+		}
+		
+		public bool BeforeDelegateDeclarationParentheses {
+			get {
+				return beforeDelegateDeclarationParentheses;
+			}
+			set {
+				beforeDelegateDeclarationParentheses = value;
+			}
+		}
+		
+		public bool BeforeMethodCallParentheses {
+			get {
+				return beforeMethodCallParentheses;
+			}
+			set {
+				beforeMethodCallParentheses = value;
+			}
+		}
+		
+		public bool BeforeMethodDeclarationParentheses {
+			get {
+				return beforeMethodDeclarationParentheses;
+			}
+			set {
+				beforeMethodDeclarationParentheses = value;
+			}
+		}
+		
+		public bool IfParentheses {
+			get {
+				return ifParentheses;
+			}
+			set {
+				ifParentheses = value;
+			}
+		}
+		
+		public bool WhileParentheses {
+			get {
+				return whileParentheses;
+			}
+			set {
+				whileParentheses = value;
+			}
+		}
+		public bool ForeachParentheses {
+			get {
+				return foreachParentheses;
+			}
+			set {
+				foreachParentheses = value;
+			}
+		}
+		public bool LockParentheses {
+			get {
+				return lockParentheses;
+			}
+			set {
+				lockParentheses = value;
+			}
+		}
+		public bool UsingParentheses {
+			get {
+				return usingParentheses;
+			}
+			set {
+				usingParentheses = value;
+			}
+		}
+		
+		public bool CatchParentheses {
+			get {
+				return catchParentheses;
+			}
+			set {
+				catchParentheses = value;
+			}
+		}
+		public bool FixedParentheses {
+			get {
+				return fixedParentheses;
+			}
+			set {
+				fixedParentheses = value;
+			}
+		}
+		public bool SwitchParentheses {
+			get {
+				return switchParentheses;
+			}
+			set {
+				switchParentheses = value;
+			}
+		}
+		public bool ForParentheses {
+			get {
+				return forParentheses;
+			}
+			set {
+				forParentheses = value;
+			}
+		}
+		
+		#endregion
+		
+		#region AroundOperators
+		bool aroundAssignmentParentheses = true;
+		bool aroundLogicalOperatorParentheses = true;
+		bool aroundEqualityOperatorParentheses = true;
+		bool aroundRelationalOperatorParentheses = true;
+		bool aroundBitwiseOperatorParentheses = true;
+		bool aroundAdditiveOperatorParentheses = true;
+		bool aroundMultiplicativeOperatorParentheses = true;
+		bool aroundShiftOperatorParentheses = true;
+		
+		public bool AroundAdditiveOperatorParentheses {
+			get {
+				return aroundAdditiveOperatorParentheses;
+			}
+			set {
+				aroundAdditiveOperatorParentheses = value;
+			}
+		}
+		public bool AroundAssignmentParentheses {
+			get {
+				return aroundAssignmentParentheses;
+			}
+			set {
+				aroundAssignmentParentheses = value;
+			}
+		}
+		public bool AroundBitwiseOperatorParentheses {
+			get {
+				return aroundBitwiseOperatorParentheses;
+			}
+			set {
+				aroundBitwiseOperatorParentheses = value;
+			}
+		}
+		public bool AroundEqualityOperatorParentheses {
+			get {
+				return aroundEqualityOperatorParentheses;
+			}
+			set {
+				aroundEqualityOperatorParentheses = value;
+			}
+		}
+		public bool AroundLogicalOperatorParentheses {
+			get {
+				return aroundLogicalOperatorParentheses;
+			}
+			set {
+				aroundLogicalOperatorParentheses = value;
+			}
+		}
+		public bool AroundMultiplicativeOperatorParentheses {
+			get {
+				return aroundMultiplicativeOperatorParentheses;
+			}
+			set {
+				aroundMultiplicativeOperatorParentheses = value;
+			}
+		}
+		public bool AroundRelationalOperatorParentheses {
+			get {
+				return aroundRelationalOperatorParentheses;
+			}
+			set {
+				aroundRelationalOperatorParentheses = value;
+			}
+		}
+		public bool AroundShiftOperatorParentheses {
+			get {
+				return aroundShiftOperatorParentheses;
+			}
+			set {
+				aroundShiftOperatorParentheses = value;
+			}
+		}
+		#endregion
+		
+		#region SpacesInConditionalOperator
+		bool conditionalOperatorBeforeConditionSpace = true;
+		bool conditionalOperatorAfterConditionSpace = true;
+		
+		bool conditionalOperatorBeforeSeparatorSpace = true;
+		bool conditionalOperatorAfterSeparatorSpace = true;
+		
+		public bool ConditionalOperatorAfterConditionSpace {
+			get {
+				return conditionalOperatorAfterConditionSpace;
+			}
+			set {
+				conditionalOperatorAfterConditionSpace = value;
+			}
+		}
+		public bool ConditionalOperatorAfterSeparatorSpace {
+			get {
+				return conditionalOperatorAfterSeparatorSpace;
+			}
+			set {
+				conditionalOperatorAfterSeparatorSpace = value;
+			}
+		}
+		public bool ConditionalOperatorBeforeConditionSpace {
+			get {
+				return conditionalOperatorBeforeConditionSpace;
+			}
+			set {
+				conditionalOperatorBeforeConditionSpace = value;
+			}
+		}
+		public bool ConditionalOperatorBeforeSeparatorSpace {
+			get {
+				return conditionalOperatorBeforeSeparatorSpace;
+			}
+			set {
+				conditionalOperatorBeforeSeparatorSpace = value;
+			}
+		}
+		#endregion
+
+		#region OtherSpaces
+		bool spacesWithinBrackets = false;
+		bool spacesAfterComma     = true;
+		bool spacesBeforeComma    = false;
+		bool spacesAfterSemicolon = true;
+		bool spacesAfterTypeCast  = false;
+		
+		public bool SpacesAfterComma {
+			get {
+				return spacesAfterComma;
+			}
+			set {
+				spacesAfterComma = value;
+			}
+		}
+		public bool SpacesAfterSemicolon {
+			get {
+				return spacesAfterSemicolon;
+			}
+			set {
+				spacesAfterSemicolon = value;
+			}
+		}
+		public bool SpacesAfterTypeCast {
+			get {
+				return spacesAfterTypeCast;
+			}
+			set {
+				spacesAfterTypeCast = value;
+			}
+		}
+		public bool SpacesBeforeComma {
+			get {
+				return spacesBeforeComma;
+			}
+			set {
+				spacesBeforeComma = value;
+			}
+		}
+		public bool SpacesWithinBrackets {
+			get {
+				return spacesWithinBrackets;
+			}
+			set {
+				spacesWithinBrackets = value;
+			}
+		}
+		#endregion
+	}
+}



More information about the svn mailing list