public override void WriteNamespace(SolutionFile File, string Namespace, Action Body)
        {
            File.WriteSpace(Keywords.@namespace).WriteLine(Namespace);

            File.WriteLine();

            File.Indent(this, Body);
        }
        public override void WriteNamespace(SolutionFile File, string Namespace, Action Body)
        {
            var RootlessNamespace = Namespace.SkipUntilOrEmpty(".");

            if (string.IsNullOrEmpty(RootlessNamespace))
            {
                Body();
                return;
            }

            File.Write(Keywords.Namespace);
            File.WriteSpace();
            File.Write(Namespace);
            File.WriteLine();

            File.Indent(this, Body);

            File.Write(Keywords.End);
            File.WriteSpace();
            File.Write(Keywords.Namespace);
        }
        public override void WriteMethod(SolutionFile File, SolutionProjectLanguageMethod Method, SolutionBuilder Context)
        {
            #region WriteMethodBody
            Action WriteMethodBody =
                delegate
            {
                this.WriteMethodBody(File, Method.Code, Context);

                if (!Method.IsConstructor)
                {
                    File.WriteIndent();

                    // empty?
                    var IsStatic = Method.IsStatic;

                    if (Method.DeclaringType != null)
                    {
                        if (Method.DeclaringType.IsStatic)
                        {
                            IsStatic = true;
                        }
                    }

                    if (IsStatic)
                    {
                        File.Write("0");
                    }
                    else
                    {
                        if (Method.ReturnType == null)
                        {
                            File.Write("()");
                        }
                    }

                    File.WriteLine();
                }
            };
            #endregion


            if (Method.IsLambda)
            {
                var Parameters = Method.Parameters.ToQueue();

                var rec = default(Action <bool>);

                rec = WriteIndent =>
                {
                    if (WriteIndent)
                    {
                        File.WriteIndent();
                    }

                    File.WriteSpace(Keywords.fun);

                    if (Parameters.Count == 0)
                    {
                        File.Write("(").Write(")").WriteSpace();
                    }
                    else
                    {
                        InternalWriteParameters(File, Method, Parameters.Dequeue());
                    }

                    File.WriteSpaces("->").WriteLine();

                    File.Indent(this,
                                delegate
                    {
                        if (Parameters.Count == 0)
                        {
                            WriteMethodBody();
                        }
                        else
                        {
                            rec(true);
                        }
                    }
                                );
                };

                rec(false);
            }
            else
            {
                this.WriteSummary(File, Method.Summary, Method.Parameters.ToArray());


                File.WriteIndent();

                if (Method.Name == "Main")
                {
                    File.Write("[<Microsoft.FSharp.Core.EntryPoint>]");
                    File.WriteLine();
                    File.WriteIndent();
                }

                if (Method.DeclaringType.IsStatic)
                {
                    File.WriteSpace(Keywords.let);
                }
                else
                {
                    if (Method.IsOverride)
                    {
                        File.WriteSpace(Keywords.@override);
                    }
                    else
                    {
                        File.WriteSpace(Keywords.member);
                    }

                    File.Write("this").Write(".");
                }
                File.Write(Method.Name);
                File.Write("(");
                InternalWriteParameters(File, Method, Method.Parameters.ToArray());
                File.Write(")");
                File.WriteSpace().WriteLine("=");
                File.Indent(this, WriteMethodBody);
            }
        }
        public override void WriteType(SolutionFile File, SolutionProjectLanguageType Type, SolutionBuilder Context)
        {
            // http://msdn.microsoft.com/en-us/library/dd233205.aspx

            File.Write(this, Context, Type.Comments);

            File.Region(
                delegate
            {
                WriteNamespace(File, Type.Namespace,
                               delegate
                {
                    File.WriteUsingNamespaceList(this, Type);

                    File.WriteLine();

                    this.WriteSummary(
                        File,
                        Type.Summary
                        );

                    File.Region(
                        delegate
                    {
                        File.WriteIndent();

                        var Constructor = Type.Methods.SingleOrDefault(k => k.IsConstructor);


                        if (Type.IsStatic)
                        {
                            File.WriteSpace(Keywords.@module);
                            WriteTypeName(File, Type);
                            File.WriteSpace();
                            File.Write("=");

                            File.WriteLine();
                        }
                        else
                        {
                            File.Write("[<Sealed>]");
                            File.WriteLine();
                            File.WriteIndent();

                            File.WriteSpace(Keywords.type);

                            if (Type.IsInternal)
                            {
                                File.WriteSpace(Keywords.@internal);
                            }

                            WriteTypeName(File, Type);
                            File.Write("(");

                            if (Constructor != null)
                            {
                                this.InternalWriteParameters(File, Constructor, Constructor.Parameters.ToArray());
                            }

                            File.WriteSpace(")");

                            File.WriteSpace(Keywords.@as);
                            File.WriteSpace("me");

                            File.WriteSpace("=");
                            File.WriteLine();

                            File.Indent(this,
                                        delegate
                            {
                                if (Type.BaseType != null)
                                {
                                    File.WriteIndent();
                                    File.WriteSpace(Keywords.@inherit);

                                    WriteTypeName(File, Type.BaseType);
                                    File.Write("(");
                                    File.WriteSpace(")");
                                    File.WriteLine();
                                }

                                // only need this if there are any members beyond ctor?
                                File.WriteIndent();
                                File.WriteSpace(Keywords.@let);
                                File.Write("this");
                                File.WriteSpaces("=");
                                File.Write("me");
                                File.WriteLine();

                                File.WriteLine();

                                File.WriteIndent();
                                File.WriteSpace(Keywords.@do);
                                File.Write("()");
                                File.WriteLine();

                                File.WriteLine();
                            }
                                        );
                        }

                        // .ctor !

                        File.Indent(this,
                                    delegate
                        {
                            if (!Type.IsStatic)
                            {
                                #region Fields with FieldConstructor
                                Type.Fields.WithEach(
                                    Field =>
                                {
                                    // http://msdn.microsoft.com/en-us/library/dd469494.aspx



                                    if (Field.FieldConstructor != null)
                                    {
                                        File.WriteIndent().WriteSpace(Keywords.let).Write(Field.Name).WriteSpaces("=");
                                        this.WritePseudoCallExpression(File, Field.FieldConstructor, Context);
                                    }
                                    else
                                    {
                                        // first asignment shall do a let
                                        if (Field.IsReadOnly)
                                        {
                                            return;
                                        }

                                        File.WriteIndent().WriteSpace(Keywords.let).WriteSpace(Keywords.mutable);
                                        File.Write(Field.Name).WriteSpaces(":");
                                        WriteTypeName(File, Field.FieldType);

                                        File.WriteSpaces("=").Write(Keywords.@null);
                                    }

                                    File.WriteLine();
                                }
                                    );
                                #endregion


                                if (Constructor != null)
                                {
                                    this.WriteMethodBody(
                                        File, Constructor.Code, Context
                                        );
                                }

                                File.WriteLine();
                                File.WriteLine();
                            }

                            foreach (var item in (from m in Type.Methods where !m.IsConstructor select m).ToArray())
                            {
                                if (item.DeclaringType == null)
                                {
                                    item.DeclaringType = Type;
                                }

                                this.WriteMethod(
                                    File,
                                    item,
                                    Context
                                    );

                                File.WriteLine();
                            }
                        }
                                    );
                    }
                        );
                }
                               );
            }
                );
        }
        public override void WriteType(SolutionFile File, SolutionProjectLanguageType Type, SolutionBuilder Context)
        {
            File.Write(this, Context, Type.Comments);



            // should the namespaces be clickable?


            File.WriteUsingNamespaceList(this, Type);

            File.WriteLine();

            File.Region(
                delegate
            {
                WriteNamespace(File, Type.Namespace,
                               delegate
                {
                    this.WriteSummary(
                        File,

                        Type.Summary
                        );


                    File.Region(
                        delegate
                    {
                        File.WriteIndent();

                        if (Type.IsPartial)
                        {
                            File.WriteSpace(Keywords.Partial);
                        }

                        File.WriteSpace(Keywords.Public);

                        if (Type.IsSealed)
                        {
                            File.WriteSpace(Keywords.NotInheritable);
                        }

                        if (!Type.IsStatic)
                        {
                            File.WriteSpace(Keywords.Class);
                        }
                        else
                        {
                            File.WriteSpace(Keywords.Module);
                        }

                        File.Write(Type);
                        File.WriteLine();

                        File.Indent(this,
                                    delegate
                        {
                            Type.BaseType.With(
                                BaseType =>
                            {
                                File.WriteIndent().WriteSpace(Keywords.Inherits);
                                WriteTypeName(File, BaseType);
                                File.WriteLine();
                            }
                                );

                            #region Fields
                            Type.Fields.WithEach(
                                Field =>
                            {
                                this.WriteSummary(File, Field.Summary);

                                File.WriteIndent();

                                if (Field.IsPrivate)
                                {
                                    File.WriteSpace(Keywords.Private);
                                }
                                else
                                {
                                    File.WriteSpace(Keywords.Public);
                                }

                                if (Field.IsReadOnly)
                                {
                                    File.WriteSpace(Keywords.ReadOnly);
                                }

                                File.WriteSpace(Field.Name);
                                File.WriteSpace(Keywords.As);

                                if (Field.FieldConstructor == null)
                                {
                                    WriteTypeName(File, Field.FieldType);
                                }
                                else
                                {
                                    WritePseudoCallExpression(File, Field.FieldConstructor, Context);
                                }

                                File.WriteLine();

                                File.WriteLine();
                            }
                                );


                            #endregion

                            #region Methods
                            foreach (var item in Type.Methods.ToArray())
                            {
                                if (item.DeclaringType == null)
                                {
                                    item.DeclaringType = Type;
                                }

                                this.WriteMethod(
                                    File,
                                    item,
                                    Context
                                    );


                                File.WriteLine();
                            }
                            #endregion



                            File.WriteLine();
                        }
                                    );

                        File.WriteIndent();
                        File.Write(Keywords.End);
                        File.WriteSpace();
                        if (!Type.IsStatic)
                        {
                            File.Write(Keywords.Class);
                        }
                        else
                        {
                            File.Write(Keywords.Module);
                        }
                    }
                        );
                    File.WriteLine();
                }
                               );
            }
                );
            File.WriteLine();
        }
        public override void WriteType(SolutionFile File, SolutionProjectLanguageType Type, SolutionBuilder Context)
        {
            File.Write(this, Context, Type.Comments);

            File.WriteUsingNamespaceList(this, Type);


            File.WriteLine();

            File.Region(
                delegate
            {
                WriteNamespace(File, Type.Namespace,
                               delegate
                {
                    if (Type.Summary != null)
                    {
                        this.WriteSummary(
                            File,
                            Type.Summary
                            );
                    }

                    File.Region(
                        delegate
                    {
                        File.WriteIndent();

                        if (Type.IsInternal)
                        {
                            File.WriteSpace(Keywords.@internal);
                        }
                        else
                        {
                            File.WriteSpace(Keywords.@public);
                        }

                        if (Type.IsStatic)
                        {
                            File.WriteSpace(Keywords.@static);
                        }


                        if (Type.IsSealed)
                        {
                            File.WriteSpace(Keywords.@sealed);
                        }

                        if (Type.IsPartial)
                        {
                            File.WriteSpace(Keywords.@partial);
                        }


                        if (Type.IsInterface)
                        {
                            File.WriteSpace(Keywords.@interface);
                        }
                        else
                        {
                            File.WriteSpace(Keywords.@class);
                        }

                        File.Write(Type);

                        if (Type.BaseType != null)
                        {
                            File.WriteSpaces(":");
                            WriteTypeName(File, Type.BaseType);
                        }

                        File.WriteLine();

                        File.WriteIndent();
                        File.WriteLine("{");
                        File.Indent(this,
                                    delegate
                        {
                            #region Fields
                            Type.Fields.WithEach(
                                Field =>
                            {
                                this.WriteSummary(File, Field.Summary);

                                File.WriteIndent();

                                if (Field.IsPrivate)
                                {
                                    File.WriteSpace(Keywords.@private);
                                }
                                else
                                {
                                    File.WriteSpace(Keywords.@public);
                                }

                                if (Field.IsReadOnly)
                                {
                                    File.WriteSpace(Keywords.@readonly);
                                }

                                WriteTypeName(File, Field.FieldType);
                                File.WriteSpace().Write(Field.Name);

                                if (Field.FieldConstructor != null)
                                {
                                    File.WriteSpaces("=");
                                    this.WritePseudoCallExpression(File, Field.FieldConstructor, Context);
                                }

                                File.WriteLine(";");

                                File.WriteLine();
                            }
                                );


                            #endregion


                            #region Properties
                            foreach (var m in Type.Properties.ToArray())
                            {
                                File.WriteIndent();

                                if (Type.IsInterface)
                                {
                                }
                                else
                                {
                                    File.Write(Keywords.@public);
                                    File.WriteSpace();

                                    if (m.IsStatic)
                                    {
                                        File.Write(Keywords.@static);
                                        File.WriteSpace();
                                    }
                                }

                                WriteTypeName(File, m.PropertyType);
                                File.WriteSpace();
                                File.Write(m.Name);

                                if (m.IsAutoProperty)
                                {
                                    File.WriteSpace();
                                    File.Write("{");
                                }
                                else
                                {
                                    File.WriteLine();
                                    File.WriteIndent();
                                    File.WriteLine("{");
                                }


                                Action <SolutionProjectLanguageMethod, Keyword> Property = (mm, kk) =>
                                {
                                    if (mm != null)
                                    {
                                        if (m.IsAutoProperty)
                                        {
                                            File.WriteSpace();
                                        }
                                        else
                                        {
                                            File.WriteIndent();
                                        }
                                        File.Write(kk);
                                        if (mm.Code == null)
                                        {
                                            File.Write(";");
                                            if (m.IsAutoProperty)
                                            {
                                            }
                                            else
                                            {
                                                File.WriteLine();
                                            }
                                        }
                                        else
                                        {
                                            File.WriteLine();
                                            this.WriteMethodBody(File, mm.Code, Context);
                                        }
                                    }
                                };

                                Action PropertyBody = delegate
                                {
                                    Property(m.GetMethod, Keywords.get);
                                    Property(m.SetMethod, Keywords.set);
                                };

                                Action <Action> PropertyIndent = Body => File.Indent(this, Body);

                                if (m.IsAutoProperty)
                                {
                                    PropertyBody();
                                    File.WriteSpace();
                                }
                                else
                                {
                                    File.Indent(this, PropertyBody);
                                    File.WriteIndent();
                                }


                                File.WriteLine("}");
                            }
                            #endregion

                            if (Type.Properties.Any())
                            {
                                File.WriteLine();
                            }

                            foreach (var item in Type.Methods.ToArray())
                            {
                                if (item.DeclaringType == null)
                                {
                                    item.DeclaringType = Type;
                                }

                                this.WriteMethod(
                                    File,
                                    item,
                                    Context
                                    );

                                File.WriteLine();
                            }
                        }
                                    );

                        File.WriteIndent().WriteLine("}");
                    }
                        );
                }
                               );
            }
                );
        }
        public override void WriteNamespace(SolutionFile File, string Namespace, Action Body)
        {
            var RootlessNamespace = Namespace.SkipUntilOrEmpty(".");

            if (string.IsNullOrEmpty(RootlessNamespace))
            {
                Body();
                return;
            }

            File.Write(Keywords.Namespace);
            File.WriteSpace();
            File.Write(Namespace);
            File.WriteLine();

            File.Indent(this, Body);

            File.Write(Keywords.End);
            File.WriteSpace();
            File.Write(Keywords.Namespace);
        }
        public override void WritePseudoExpression(SolutionFile File, object Parameter, SolutionBuilder Context)
        {
            var Code = Parameter as string;
            if (Code != null)
            {
                File.Write(Code);
                return;
            }

            var Argument = Parameter as SolutionProjectLanguageArgument;
            if (Argument != null)
            {
                File.Write(Argument.Name);
                return;
            }

            {
                var Constant = Parameter as PseudoStringConstantExpression;
                if (Constant != null)
                {
                    var Value = (string)Constant.Value;
                    File.Write(SolutionFileTextFragment.String,
                        // jsc escape string
                        "@\"" + Value.Replace("\"", "\"\"") + "\""
                    );
                    return;
                }
            }

            {
                var Constant = Parameter as PseudoInt32ConstantExpression;
                if (Constant != null)
                {
                    File.Write("" + Constant.Value);
                    return;
                }
            }

            {
                var Constant = Parameter as PseudoDoubleConstantExpression;
                if (Constant != null)
                {
                    var Value = "" + Constant.Value;
                    if (!Value.Contains("."))
                        Value += ".0";

                    File.Write(Value);
                    return;
                }
            }
            var Call = Parameter as PseudoCallExpression;
            if (Call != null)
            {
                WritePseudoCallExpression(File, Call, Context);
                return;
            }

            var This = Parameter as PseudoThisExpression;
            if (This != null)
            {
                File.Write(Keywords.@this);
                return;
            }

            var Base = Parameter as PseudoBaseExpression;
            if (Base != null)
            {
                File.Write(Keywords.@base);
                return;
            }


            var Type = Parameter as SolutionProjectLanguageType;
            if (Type != null)
            {
                File.Write(Keywords.@typeof);
                File.Write("(");
                WriteTypeName(File, Type);
                File.Write(")");
                return;
            }

            var XElement = Parameter as XElement;
            if (XElement != null)
            {
                WritePseudoCallExpression(File, XElement.ToPseudoCallExpression(), Context);
                return;
            }

            var Method = Parameter as SolutionProjectLanguageMethod;
            if (Method != null)
            {
                WriteMethod(File, Method, Context);
                return;
            }

            // F# match would be awesome here? :)
            var Field = Parameter as SolutionProjectLanguageField;
            if (Field != null)
            {
                // DeclaringType Object?
                File.Write(Field.Name);
            }


            #region PseudoArrayExpression
            var Array = Parameter as PseudoArrayExpression;
            if (Array != null)
            {
                File.Indent(this,
                    delegate
                    {
                        File.WriteLine();
                        File.WriteIndent();

                        File.Write(Keywords.@new);
                        File.WriteSpace();

                        WriteTypeName(File, Array.ElementType);
                        File.Write("[]");

                        File.WriteSpace();
                        File.Write("{");

                        File.Indent(this,
                            delegate
                            {
                                File.WriteLine();
                                File.WriteIndent();

                                Func<object, Action> AtWritePseudoExpression = k => () => WritePseudoExpression(File, k, Context);

                                Action WriteSeparator =
                                    delegate
                                    {
                                        File.Write(",");
                                        File.WriteLine();
                                        File.WriteIndent();
                                    };

                                Array.Items.ToArray().Select(AtWritePseudoExpression).SelectWithSeparator(WriteSeparator).Invoke();

                            }
                        );

                        File.WriteLine();
                        File.WriteIndent();

                        File.Write("}");

                    }
                );

                File.WriteLine();
                File.WriteIndent();

                return;
            }
            #endregion

        }
        public override void WriteNamespace(SolutionFile File, string Namespace, Action Body)
        {
            File.Write(Keywords.@namespace);
            File.WriteSpace();
            File.Write(Namespace);
            File.WriteLine();
            File.WriteLine("{");
            File.Indent(this, Body);

            File.WriteLine("}");

        }
        private void InternalWriteParameterList(SolutionFile File, PseudoCallExpression Lambda, SolutionBuilder Context)
        {
            File.Write("(");

            #region HasComplexParameter
            var HasComplexParameter = Lambda.ParameterExpressions.Any(
                k =>
                {
                    if (k is XElement)
                        return true;

                    // anonymous method!
                    if (k is SolutionProjectLanguageMethod)
                        return true;


                    var Call = k as PseudoCallExpression;
                    if (Call != null)
                    {
                        // what? :) 
                        if (Call.XLinq != null)
                            return true;
                    }

                    
                    return false;
                }
            );
            #endregion

            Action Body =
                delegate
                {
                    var Parameters = Lambda.ParameterExpressions.ToArray();

                    var FirstParameter = 0;

                    if (IsExtensionMethod(Lambda))
                        FirstParameter = 1;

                    for (int i = FirstParameter; i < Parameters.Length; i++)
                    {
                        if (i > FirstParameter)
                        {
                            if (HasComplexParameter)
                            {
                                File.WriteLine(",");
                                File.WriteIndent();
                            }
                            else
                            {
                                File.WriteSpace(",");
                            }
                        }

                        var Parameter = Parameters[i];

                        WritePseudoExpression(File, Parameter, Context);
                    }
                };

            if (HasComplexParameter)
            {
                File.WriteLine();
                File.Indent(this,
                    delegate
                    {
                        if (Lambda.ParameterExpressions.FirstOrDefault() is XElement)
                        {
                            // xlinq has no indent...
                        }
                        else
                        {
                            File.WriteIndent();
                        }

                        Body();

                        //File.WriteLine();
                    }
                );
                File.WriteIndent();
            }
            else
            {
                Body();
            }

            File.Write(")");
        }
        public override void WriteMethodBody(SolutionFile File, SolutionProjectLanguageCode Code, SolutionBuilder Context)
        {
            // should this be an extension method to all languages?

            Action WriteCodeStatements =
                delegate
                {
                    var History = Code.History.ToArray();

                    for (int i = 0; i < History.Length; i++)
                    {
                        var IsReturnStatement = false;

                        Code.OwnerMethod.With(
                            m =>
                            {
                                if (m.ReturnType == null)
                                    return;

                                if (m.IsConstructor)
                                    return;

                                IsReturnStatement = i == History.Length - 1;
                            }
                        );


                        var item = History[i];

                        {
                            var Comment = item as string;
                            if (Comment != null)
                            {
                                File.WriteIndent();
                                this.WriteCommentLine(File, Comment);
                            }
                        }

                        {
                            var Comment = item as SolutionFileComment;
                            if (Comment != null)
                            {
                                Comment.WriteTo(File, this, Context);
                                return;
                            }
                        }

                        var If = item as PseudoIfExpression;

                        if (If != null)
                        {
                            if (If.IsConditionalCompilationDirective)
                            {

                                this.WriteConditionalCompilation(File, If, Context);

                            }
                            else
                            {

                                File.WriteIndent().WriteSpace(Keywords.@if);
                                File.Write("(");
                                WritePseudoExpression(File, If.Expression, Context);
                                File.Write(")");
                                File.WriteLine();

                                WriteMethodBody(File, If.TrueCase, Context);
                                File.WriteLine();

                                if (If.FalseCase != null)
                                {
                                    File.WriteIndent().WriteLine(Keywords.@else);

                                    WriteMethodBody(File, If.FalseCase, Context);
                                }
                            }

                            return;
                        }

                        var Lambda = item as PseudoCallExpression;

                        if (Lambda != null)
                        {
                            if (Code.IsLambdaExpression)
                            {
                                WritePseudoCallExpression(File, Lambda, Context);
                            }
                            else
                            {
                                if (Lambda.Comment != null)
                                    Lambda.Comment.WriteTo(File, this, Context);

                                if (Lambda.Method != null)
                                {
                                    File.WriteIndent();

                                    if (IsReturnStatement)
                                    {
                                        File.WriteSpace(Keywords.@return);
                                    }

                                    WritePseudoCallExpression(File, Lambda, Context);
                                    File.WriteLine(";");
                                }
                            }
                        }
                    }
                };

            Action WriteCodeStatementsAsBlock =
                delegate
                {
                    File.WriteIndent().WriteLine("{");
                    File.Indent(this, WriteCodeStatements);
                    File.WriteIndent().Write("}");
                };

            Code.OwnerIfExpression.With(n => n.IsConditionalCompilationDirective, n => WriteCodeStatementsAsBlock = WriteCodeStatements);

            if (Code.IsLambdaExpression)
                WriteCodeStatementsAsBlock = WriteCodeStatements;

            WriteCodeStatementsAsBlock();
        }
        public override void WriteMethod(SolutionFile File, SolutionProjectLanguageMethod Method, SolutionBuilder Context)
        {
            #region WriteMethodBody
            Action WriteMethodBody =
                delegate
                {
                    this.WriteMethodBody(File, Method.Code, Context);

                    if (!Method.IsConstructor)
                    {
                        File.WriteIndent();

                        // empty?
                        var IsStatic = Method.IsStatic;

                        if (Method.DeclaringType != null)
                            if (Method.DeclaringType.IsStatic)
                                IsStatic = true;

                        if (IsStatic)
                        {
                            File.Write("0");
                        }
                        else
                        {
                            if (Method.ReturnType == null)
                                File.Write("()");
                        }

                        File.WriteLine();
                    }
                };
            #endregion


            if (Method.IsLambda)
            {
                var Parameters = Method.Parameters.ToQueue();

                var rec = default(Action<bool>);

                rec = WriteIndent =>
                {
                    if (WriteIndent)
                        File.WriteIndent();

                    File.WriteSpace(Keywords.fun);

                    if (Parameters.Count == 0)
                    {
                        File.Write("(").Write(")").WriteSpace();
                    }
                    else
                    {
                        InternalWriteParameters(File, Method, Parameters.Dequeue());
                    }

                    File.WriteSpaces("->").WriteLine();

                    File.Indent(this,
                        delegate
                        {
                            if (Parameters.Count == 0)
                                WriteMethodBody();
                            else
                                rec(true);
                        }
                    );

                };

                rec(false);

            }
            else
            {
                this.WriteSummary(File, Method.Summary, Method.Parameters.ToArray());


                File.WriteIndent();

                if (Method.Name == "Main")
                {
                    File.Write("[<Microsoft.FSharp.Core.EntryPoint>]");
                    File.WriteLine();
                    File.WriteIndent();
                }

                if (Method.DeclaringType.IsStatic)
                {
                    File.WriteSpace(Keywords.let);
                }
                else
                {
                    if (Method.IsOverride)
                        File.WriteSpace(Keywords.@override);
                    else
                        File.WriteSpace(Keywords.member);

                    File.Write("this").Write(".");
                }
                File.Write(Method.Name);
                File.Write("(");
                InternalWriteParameters(File, Method, Method.Parameters.ToArray());
                File.Write(")");
                File.WriteSpace().WriteLine("=");
                File.Indent(this, WriteMethodBody);
            }


        }
        public override void WriteType(SolutionFile File, SolutionProjectLanguageType Type, SolutionBuilder Context)
        {
            // http://msdn.microsoft.com/en-us/library/dd233205.aspx

            File.Write(this, Context, Type.Comments);

            File.Region(
                delegate
                {
                    WriteNamespace(File, Type.Namespace,
                        delegate
                        {
                            File.WriteUsingNamespaceList(this, Type);

                            File.WriteLine();

                            this.WriteSummary(
                                File,
                                Type.Summary
                            );

                            File.Region(
                                delegate
                                {
                                    File.WriteIndent();

                                    var Constructor = Type.Methods.SingleOrDefault(k => k.IsConstructor);


                                    if (Type.IsStatic)
                                    {
                                        File.WriteSpace(Keywords.@module);
                                        WriteTypeName(File, Type);
                                        File.WriteSpace();
                                        File.Write("=");

                                        File.WriteLine();

                                    }
                                    else
                                    {
                                        File.Write("[<Sealed>]");
                                        File.WriteLine();
                                        File.WriteIndent();

                                        File.WriteSpace(Keywords.type);

                                        if (Type.IsInternal)
                                        {
                                            File.WriteSpace(Keywords.@internal);
                                        }

                                        WriteTypeName(File, Type);
                                        File.Write("(");

                                        if (Constructor != null)
                                            this.InternalWriteParameters(File, Constructor, Constructor.Parameters.ToArray());

                                        File.WriteSpace(")");

                                        File.WriteSpace(Keywords.@as);
                                        File.WriteSpace("me");

                                        File.WriteSpace("=");
                                        File.WriteLine();

                                        File.Indent(this,
                                            delegate
                                            {
                                                if (Type.BaseType != null)
                                                {
                                                    File.WriteIndent();
                                                    File.WriteSpace(Keywords.@inherit);

                                                    WriteTypeName(File, Type.BaseType);
                                                    File.Write("(");
                                                    File.WriteSpace(")");
                                                    File.WriteLine();
                                                }

                                                // only need this if there are any members beyond ctor?
                                                File.WriteIndent();
                                                File.WriteSpace(Keywords.@let);
                                                File.Write("this");
                                                File.WriteSpaces("=");
                                                File.Write("me");
                                                File.WriteLine();

                                                File.WriteLine();

                                                File.WriteIndent();
                                                File.WriteSpace(Keywords.@do);
                                                File.Write("()");
                                                File.WriteLine();

                                                File.WriteLine();
                                            }
                                        );


                                    }

                                    // .ctor !

                                    File.Indent(this,
                                        delegate
                                        {
                                            if (!Type.IsStatic)
                                            {
                                                #region Fields with FieldConstructor
                                                Type.Fields.WithEach(
                                                    Field =>
                                                    {
                                                        // http://msdn.microsoft.com/en-us/library/dd469494.aspx




                                                        if (Field.FieldConstructor != null)
                                                        {
                                                            File.WriteIndent().WriteSpace(Keywords.let).Write(Field.Name).WriteSpaces("=");
                                                            this.WritePseudoCallExpression(File, Field.FieldConstructor, Context);
                                                        }
                                                        else
                                                        {
                                                            // first asignment shall do a let
                                                            if (Field.IsReadOnly)
                                                                return;

                                                            File.WriteIndent().WriteSpace(Keywords.let).WriteSpace(Keywords.mutable);
                                                            File.Write(Field.Name).WriteSpaces(":");
                                                            WriteTypeName(File, Field.FieldType);

                                                            File.WriteSpaces("=").Write(Keywords.@null);
                                                        }

                                                        File.WriteLine();
                                                    }
                                                );
                                                #endregion


                                                if (Constructor != null)
                                                {
                                                    this.WriteMethodBody(
                                                        File, Constructor.Code, Context
                                                    );
                                                }

                                                File.WriteLine();
                                                File.WriteLine();
                                            }

                                            foreach (var item in (from m in Type.Methods where !m.IsConstructor select m).ToArray())
                                            {
                                                if (item.DeclaringType == null)
                                                    item.DeclaringType = Type;

                                                this.WriteMethod(
                                                    File,
                                                    item,
                                                    Context
                                                );

                                                File.WriteLine();
                                            }



                                        }
                                    );
                                }
                            );
                        }
                    );
                }
            );

        }
        public override void WriteType(SolutionFile File, SolutionProjectLanguageType Type, SolutionBuilder Context)
        {
            File.Write(this, Context, Type.Comments);




            // should the namespaces be clickable?


            File.WriteUsingNamespaceList(this, Type);

            File.WriteLine();

            File.Region(
                delegate
                {


                    WriteNamespace(File, Type.Namespace,
                        delegate
                        {


                            this.WriteSummary(
                                    File,

                                    Type.Summary
                                );


                            File.Region(
                                delegate
                                {
                                    File.WriteIndent();

                                    if (Type.IsPartial)
                                        File.WriteSpace(Keywords.Partial);

                                    File.WriteSpace(Keywords.Public);

                                    if (Type.IsSealed)
                                    {
                                        File.WriteSpace(Keywords.NotInheritable);
                                    }

                                    if (!Type.IsStatic)
                                    {
                                        File.WriteSpace(Keywords.Class);
                                    }
                                    else
                                    {
                                        File.WriteSpace(Keywords.Module);
                                    }

                                    File.Write(Type);
                                    File.WriteLine();

                                    File.Indent(this,
                                        delegate
                                        {
                                            Type.BaseType.With(
                                                BaseType =>
                                                {
                                                    File.WriteIndent().WriteSpace(Keywords.Inherits);
                                                    WriteTypeName(File, BaseType);
                                                    File.WriteLine();
                                                }
                                            );

                                            #region Fields
                                            Type.Fields.WithEach(
                                                Field =>
                                                {
                                                    this.WriteSummary(File, Field.Summary);

                                                    File.WriteIndent();

                                                    if (Field.IsPrivate)
                                                    {
                                                        File.WriteSpace(Keywords.Private);
                                                    }
                                                    else
                                                    {
                                                        File.WriteSpace(Keywords.Public);
                                                    }

                                                    if (Field.IsReadOnly)
                                                    {
                                                        File.WriteSpace(Keywords.ReadOnly);
                                                    }

                                                    File.WriteSpace(Field.Name);
                                                    File.WriteSpace(Keywords.As);

                                                    if (Field.FieldConstructor == null)
                                                    {
                                                        WriteTypeName(File, Field.FieldType);
                                                    }
                                                    else
                                                    {
                                                        WritePseudoCallExpression(File, Field.FieldConstructor, Context);
                                                    }

                                                    File.WriteLine();

                                                    File.WriteLine();
                                                }
                                            );


                                            #endregion

                                            #region Methods
                                            foreach (var item in Type.Methods.ToArray())
                                            {
                                                if (item.DeclaringType == null)
                                                    item.DeclaringType = Type;

                                                this.WriteMethod(
                                                    File,
                                                    item,
                                                    Context
                                                );


                                                File.WriteLine();
                                            }
                                            #endregion



                                            File.WriteLine();
                                        }
                                    );

                                    File.WriteIndent();
                                    File.Write(Keywords.End);
                                    File.WriteSpace();
                                    if (!Type.IsStatic)
                                    {
                                        File.Write(Keywords.Class);
                                    }
                                    else
                                    {
                                        File.Write(Keywords.Module);
                                    }
                                }
                            );
                            File.WriteLine();

                        }
                    );


                }
            );
            File.WriteLine();

        }
        public override void WriteMethodBody(SolutionFile File, SolutionProjectLanguageCode Code, SolutionBuilder Context)
        {
            // should this be an extension method to all languages?

            Action WriteCodeStatements =
                delegate
            {
                var History = Code.History.ToArray();

                for (int i = 0; i < History.Length; i++)
                {
                    var IsReturnStatement = false;

                    Code.OwnerMethod.With(
                        m =>
                    {
                        if (m.ReturnType == null)
                        {
                            return;
                        }

                        if (m.IsConstructor)
                        {
                            return;
                        }

                        IsReturnStatement = i == History.Length - 1;
                    }
                        );


                    var item = History[i];

                    {
                        var Comment = item as string;
                        if (Comment != null)
                        {
                            File.WriteIndent();
                            this.WriteCommentLine(File, Comment);
                        }
                    }

                    {
                        var Comment = item as SolutionFileComment;
                        if (Comment != null)
                        {
                            Comment.WriteTo(File, this, Context);
                            return;
                        }
                    }

                    var If = item as PseudoIfExpression;

                    if (If != null)
                    {
                        if (If.IsConditionalCompilationDirective)
                        {
                            this.WriteConditionalCompilation(File, If, Context);
                        }
                        else
                        {
                            File.WriteIndent().WriteSpace(Keywords.@if);
                            File.Write("(");
                            WritePseudoExpression(File, If.Expression, Context);
                            File.Write(")");
                            File.WriteLine();

                            WriteMethodBody(File, If.TrueCase, Context);
                            File.WriteLine();

                            if (If.FalseCase != null)
                            {
                                File.WriteIndent().WriteLine(Keywords.@else);

                                WriteMethodBody(File, If.FalseCase, Context);
                            }
                        }

                        return;
                    }

                    var Lambda = item as PseudoCallExpression;

                    if (Lambda != null)
                    {
                        if (Code.IsLambdaExpression)
                        {
                            WritePseudoCallExpression(File, Lambda, Context);
                        }
                        else
                        {
                            if (Lambda.Comment != null)
                            {
                                Lambda.Comment.WriteTo(File, this, Context);
                            }

                            if (Lambda.Method != null)
                            {
                                File.WriteIndent();

                                if (IsReturnStatement)
                                {
                                    File.WriteSpace(Keywords.@return);
                                }

                                WritePseudoCallExpression(File, Lambda, Context);
                                File.WriteLine(";");
                            }
                        }
                    }
                }
            };

            Action WriteCodeStatementsAsBlock =
                delegate
            {
                File.WriteIndent().WriteLine("{");
                File.Indent(this, WriteCodeStatements);
                File.WriteIndent().Write("}");
            };

            Code.OwnerIfExpression.With(n => n.IsConditionalCompilationDirective, n => WriteCodeStatementsAsBlock = WriteCodeStatements);

            if (Code.IsLambdaExpression)
            {
                WriteCodeStatementsAsBlock = WriteCodeStatements;
            }

            WriteCodeStatementsAsBlock();
        }
        public override void WriteType(SolutionFile File, SolutionProjectLanguageType Type, SolutionBuilder Context)
        {
            File.Write(this, Context, Type.Comments);

            File.WriteUsingNamespaceList(this, Type);


            File.WriteLine();

            File.Region(
                delegate
                {
                    WriteNamespace(File, Type.Namespace,
                        delegate
                        {

                            if (Type.Summary != null)
                                this.WriteSummary(
                                    File,
                                    Type.Summary
                                );

                            File.Region(
                                delegate
                                {
                                    File.WriteIndent();

                                    if (Type.IsInternal)
                                    {
                                        File.WriteSpace(Keywords.@internal);
                                    }
                                    else
                                    {
                                        File.WriteSpace(Keywords.@public);
                                    }

                                    if (Type.IsStatic)
                                    {
                                        File.WriteSpace(Keywords.@static);
                                    }


                                    if (Type.IsSealed)
                                    {
                                        File.WriteSpace(Keywords.@sealed);
                                    }

                                    if (Type.IsPartial)
                                    {
                                        File.WriteSpace(Keywords.@partial);
                                    }


                                    if (Type.IsInterface)
                                    {
                                        File.WriteSpace(Keywords.@interface);
                                    }
                                    else
                                    {
                                        File.WriteSpace(Keywords.@class);
                                    }

                                    File.Write(Type);

                                    if (Type.BaseType != null)
                                    {
                                        File.WriteSpaces(":");
                                        WriteTypeName(File, Type.BaseType);
                                    }

                                    File.WriteLine();

                                    File.WriteIndent();
                                    File.WriteLine("{");
                                    File.Indent(this,
                                        delegate
                                        {
                                            #region Fields
                                            Type.Fields.WithEach(
                                                Field =>
                                                {
                                                    this.WriteSummary(File, Field.Summary);

                                                    File.WriteIndent();

                                                    if (Field.IsPrivate)
                                                    {
                                                        File.WriteSpace(Keywords.@private);
                                                    }
                                                    else
                                                    {
                                                        File.WriteSpace(Keywords.@public);
                                                    }

                                                    if (Field.IsReadOnly)
                                                    {
                                                        File.WriteSpace(Keywords.@readonly);
                                                    }

                                                    WriteTypeName(File, Field.FieldType);
                                                    File.WriteSpace().Write(Field.Name);

                                                    if (Field.FieldConstructor != null)
                                                    {
                                                        File.WriteSpaces("=");
                                                        this.WritePseudoCallExpression(File, Field.FieldConstructor, Context);
                                                    }

                                                    File.WriteLine(";");

                                                    File.WriteLine();
                                                }
                                            );


                                            #endregion


                                            #region Properties
                                            foreach (var m in Type.Properties.ToArray())
                                            {
                                                File.WriteIndent();

                                                if (Type.IsInterface)
                                                {

                                                }
                                                else
                                                {
                                                    File.Write(Keywords.@public);
                                                    File.WriteSpace();

                                                    if (m.IsStatic)
                                                    {
                                                        File.Write(Keywords.@static);
                                                        File.WriteSpace();
                                                    }
                                                }

                                                WriteTypeName(File, m.PropertyType);
                                                File.WriteSpace();
                                                File.Write(m.Name);

                                                if (m.IsAutoProperty)
                                                {
                                                    File.WriteSpace();
                                                    File.Write("{");
                                                }
                                                else
                                                {
                                                    File.WriteLine();
                                                    File.WriteIndent();
                                                    File.WriteLine("{");
                                                }


                                                Action<SolutionProjectLanguageMethod, Keyword> Property = (mm, kk) =>
                                                {
                                                    if (mm != null)
                                                    {
                                                        if (m.IsAutoProperty)
                                                        {
                                                            File.WriteSpace();
                                                        }
                                                        else
                                                        {
                                                            File.WriteIndent();
                                                        }
                                                        File.Write(kk);
                                                        if (mm.Code == null)
                                                        {
                                                            File.Write(";");
                                                            if (m.IsAutoProperty)
                                                            {
                                                            }
                                                            else
                                                            {
                                                                File.WriteLine();
                                                            }
                                                        }
                                                        else
                                                        {
                                                            File.WriteLine();
                                                            this.WriteMethodBody(File, mm.Code, Context);
                                                        }
                                                    }
                                                };

                                                Action PropertyBody = delegate
                                                {
                                                    Property(m.GetMethod, Keywords.get);
                                                    Property(m.SetMethod, Keywords.set);
                                                };

                                                Action<Action> PropertyIndent = Body => File.Indent(this, Body);

                                                if (m.IsAutoProperty)
                                                {
                                                    PropertyBody();
                                                    File.WriteSpace();
                                                }
                                                else
                                                {
                                                    File.Indent(this, PropertyBody);
                                                    File.WriteIndent();
                                                }


                                                File.WriteLine("}");
                                            }
                                            #endregion

                                            if (Type.Properties.Any())
                                                File.WriteLine();

                                            foreach (var item in Type.Methods.ToArray())
                                            {
                                                if (item.DeclaringType == null)
                                                    item.DeclaringType = Type;

                                                this.WriteMethod(
                                                    File,
                                                    item,
                                                    Context
                                                );

                                                File.WriteLine();
                                            }


                                        }
                                    );

                                    File.WriteIndent().WriteLine("}");
                                }
                            );
                        }
                    );


                }
            );

        }
        public override void WritePseudoExpression(SolutionFile File, object Parameter, SolutionBuilder Context)
        {
            var Code = Parameter as string;

            if (Code != null)
            {
                File.Write(Code);
                return;
            }

            var Argument = Parameter as SolutionProjectLanguageArgument;

            if (Argument != null)
            {
                File.Write(Argument.Name);
                return;
            }

            {
                var Constant = Parameter as PseudoStringConstantExpression;
                if (Constant != null)
                {
                    var Value = (string)Constant.Value;
                    File.Write(SolutionFileTextFragment.String,
                               // jsc escape string
                               "@\"" + Value.Replace("\"", "\"\"") + "\""
                               );
                    return;
                }
            }

            {
                var Constant = Parameter as PseudoInt32ConstantExpression;
                if (Constant != null)
                {
                    File.Write("" + Constant.Value);
                    return;
                }
            }

            {
                var Constant = Parameter as PseudoDoubleConstantExpression;
                if (Constant != null)
                {
                    var Value = "" + Constant.Value;
                    if (!Value.Contains("."))
                    {
                        Value += ".0";
                    }

                    File.Write(Value);
                    return;
                }
            }
            var Call = Parameter as PseudoCallExpression;

            if (Call != null)
            {
                WritePseudoCallExpression(File, Call, Context);
                return;
            }

            var This = Parameter as PseudoThisExpression;

            if (This != null)
            {
                File.Write(Keywords.@this);
                return;
            }

            var Base = Parameter as PseudoBaseExpression;

            if (Base != null)
            {
                File.Write(Keywords.@base);
                return;
            }


            var Type = Parameter as SolutionProjectLanguageType;

            if (Type != null)
            {
                File.Write(Keywords.@typeof);
                File.Write("(");
                WriteTypeName(File, Type);
                File.Write(")");
                return;
            }

            var XElement = Parameter as XElement;

            if (XElement != null)
            {
                WritePseudoCallExpression(File, XElement.ToPseudoCallExpression(), Context);
                return;
            }

            var Method = Parameter as SolutionProjectLanguageMethod;

            if (Method != null)
            {
                WriteMethod(File, Method, Context);
                return;
            }

            // F# match would be awesome here? :)
            var Field = Parameter as SolutionProjectLanguageField;

            if (Field != null)
            {
                // DeclaringType Object?
                File.Write(Field.Name);
            }


            #region PseudoArrayExpression
            var Array = Parameter as PseudoArrayExpression;
            if (Array != null)
            {
                File.Indent(this,
                            delegate
                {
                    File.WriteLine();
                    File.WriteIndent();

                    File.Write(Keywords.@new);
                    File.WriteSpace();

                    WriteTypeName(File, Array.ElementType);
                    File.Write("[]");

                    File.WriteSpace();
                    File.Write("{");

                    File.Indent(this,
                                delegate
                    {
                        File.WriteLine();
                        File.WriteIndent();

                        Func <object, Action> AtWritePseudoExpression = k => () => WritePseudoExpression(File, k, Context);

                        Action WriteSeparator =
                            delegate
                        {
                            File.Write(",");
                            File.WriteLine();
                            File.WriteIndent();
                        };

                        Array.Items.ToArray().Select(AtWritePseudoExpression).SelectWithSeparator(WriteSeparator).Invoke();
                    }
                                );

                    File.WriteLine();
                    File.WriteIndent();

                    File.Write("}");
                }
                            );

                File.WriteLine();
                File.WriteIndent();

                return;
            }
            #endregion
        }
        public override void WriteMethodBody(SolutionFile File, SolutionProjectLanguageCode Code, SolutionBuilder Context)
        {
            // should this be an extension method to all languages?

            Action WriteCodeStatements =
                delegate
            {
                var History = Code.History.ToArray();

                for (int i = 0; i < History.Length; i++)
                {
                    var IsReturnStatement = false;

                    Code.OwnerMethod.With(
                        m =>
                    {
                        if (m.ReturnType == null)
                        {
                            return;
                        }

                        if (m.IsConstructor)
                        {
                            return;
                        }

                        IsReturnStatement = i == History.Length - 1;
                    }
                        );


                    var item = History[i];


                    #region Comment
                    {
                        var Comment = item as string;
                        if (Comment != null)
                        {
                            File.WriteIndent();
                            this.WriteCommentLine(File, Comment);
                        }
                    }

                    {
                        var Comment = item as SolutionFileComment;
                        if (Comment != null)
                        {
                            Comment.WriteTo(File, this, Context);
                            return;
                        }
                    }
                    #endregion


                    #region If
                    var If = item as PseudoIfExpression;

                    if (If != null)
                    {
                        Func <SolutionFile> WriteDirectiveOrIndent = File.WriteIndent;


                        if (If.IsConditionalCompilationDirective)
                        {
                            WriteDirectiveOrIndent = File.WriteDirective;
                        }

                        WriteDirectiveOrIndent().WriteSpace(Keywords.If);
                        WritePseudoExpression(File, If.Expression, Context);
                        File.WriteSpace();
                        File.WriteLine(Keywords.Then);

                        WriteMethodBody(File, If.TrueCase, Context);

                        if (If.FalseCase != null)
                        {
                            WriteDirectiveOrIndent().WriteLine(Keywords.Else);

                            WriteMethodBody(File, If.FalseCase, Context);
                        }

                        WriteDirectiveOrIndent().WriteSpace(Keywords.End).WriteLine(Keywords.@If);

                        return;
                    }
                    #endregion


                    #region Lambda
                    var Lambda = item as PseudoCallExpression;

                    if (Lambda != null)
                    {
                        if (Code.IsLambdaExpression)
                        {
                            WritePseudoCallExpression(File, Lambda, Context);
                        }
                        else
                        {
                            if (Lambda.Comment != null)
                            {
                                Lambda.Comment.WriteTo(File, this, Context);
                            }

                            if (Lambda.Method != null)
                            {
                                File.WriteIndent();

                                if (IsReturnStatement)
                                {
                                    File.WriteSpace(Keywords.@Return);
                                }


                                WritePseudoCallExpression(File, Lambda, Context);
                                File.WriteLine();
                            }
                        }
                    }
                    #endregion
                }
            };

            if (Code.IsConditionalCompilationDirectiveCode)
            {
                WriteCodeStatements();
            }
            else
            {
                File.Indent(this, WriteCodeStatements);
            }
        }
Ejemplo n.º 19
0
        private void InternalWriteParameterList(SolutionFile File, PseudoCallExpression Lambda, SolutionBuilder Context)
        {
            File.Write("(");

            #region HasComplexParameter
            var HasComplexParameter = Lambda.ParameterExpressions.Any(
                k =>
            {
                if (k is XElement)
                {
                    return(true);
                }

                // anonymous method!
                if (k is SolutionProjectLanguageMethod)
                {
                    return(true);
                }


                var Call = k as PseudoCallExpression;
                if (Call != null)
                {
                    // what? :)
                    if (Call.XLinq != null)
                    {
                        return(true);
                    }
                }


                return(false);
            }
                );
            #endregion

            Action Body =
                delegate
            {
                var Parameters = Lambda.ParameterExpressions.ToArray();

                var FirstParameter = 0;

                if (IsExtensionMethod(Lambda))
                {
                    FirstParameter = 1;
                }

                for (int i = FirstParameter; i < Parameters.Length; i++)
                {
                    if (i > FirstParameter)
                    {
                        if (HasComplexParameter)
                        {
                            File.WriteLine(",");
                            File.WriteIndent();
                        }
                        else
                        {
                            File.WriteSpace(",");
                        }
                    }

                    var Parameter = Parameters[i];

                    WritePseudoExpression(File, Parameter, Context);
                }
            };

            if (HasComplexParameter)
            {
                File.WriteLine();
                File.Indent(this,
                            delegate
                {
                    if (Lambda.ParameterExpressions.FirstOrDefault() is XElement)
                    {
                        // xlinq has no indent...
                    }
                    else
                    {
                        File.WriteIndent();
                    }

                    Body();

                    //File.WriteLine();
                }
                            );
                File.WriteIndent();
            }
            else
            {
                Body();
            }

            File.Write(")");
        }
        public override void WriteMethodBody(SolutionFile File, SolutionProjectLanguageCode Code, SolutionBuilder Context)
        {
            // should this be an extension method to all languages?

            Action WriteCodeStatements =
             delegate
             {

                 var History = Code.History.ToArray();

                 for (int i = 0; i < History.Length; i++)
                 {
                     var IsReturnStatement = false;

                     Code.OwnerMethod.With(
                          m =>
                          {
                              if (m.ReturnType == null)
                                  return;

                              if (m.IsConstructor)
                                  return;

                              IsReturnStatement = i == History.Length - 1;
                          }
                     );


                     var item = History[i];


                     #region Comment
                     {
                         var Comment = item as string;
                         if (Comment != null)
                         {
                             File.WriteIndent();
                             this.WriteCommentLine(File, Comment);
                         }
                     }

                     {
                         var Comment = item as SolutionFileComment;
                         if (Comment != null)
                         {
                             Comment.WriteTo(File, this, Context);
                             return;
                         }
                     }
                     #endregion


                     #region If
                     var If = item as PseudoIfExpression;

                     if (If != null)
                     {
                         Func<SolutionFile> WriteDirectiveOrIndent = File.WriteIndent;


                         if (If.IsConditionalCompilationDirective)
                         {
                             WriteDirectiveOrIndent = File.WriteDirective;
                         }

                         WriteDirectiveOrIndent().WriteSpace(Keywords.If);
                         WritePseudoExpression(File, If.Expression, Context);
                         File.WriteSpace();
                         File.WriteLine(Keywords.Then);

                         WriteMethodBody(File, If.TrueCase, Context);

                         if (If.FalseCase != null)
                         {
                             WriteDirectiveOrIndent().WriteLine(Keywords.Else);

                             WriteMethodBody(File, If.FalseCase, Context);
                         }

                         WriteDirectiveOrIndent().WriteSpace(Keywords.End).WriteLine(Keywords.@If);

                         return;
                     }
                     #endregion


                     #region Lambda
                     var Lambda = item as PseudoCallExpression;

                     if (Lambda != null)
                     {
                         if (Code.IsLambdaExpression)
                         {
                             WritePseudoCallExpression(File, Lambda, Context);
                         }
                         else
                         {

                             if (Lambda.Comment != null)
                                 Lambda.Comment.WriteTo(File, this, Context);

                             if (Lambda.Method != null)
                             {
                                 File.WriteIndent();

                                 if (IsReturnStatement)
                                 {
                                     File.WriteSpace(Keywords.@Return);
                                 }


                                 WritePseudoCallExpression(File, Lambda, Context);
                                 File.WriteLine();
                             }
                         }
                     }
                     #endregion

                 }

             };

            if (Code.IsConditionalCompilationDirectiveCode)
                WriteCodeStatements();
            else
                File.Indent(this, WriteCodeStatements);


        }