Click here to Skip to main content
15,894,825 members
Articles / Programming Languages / XML

XML Schema Reader Writer Plugin for VS 2005/2008

Rate me:
Please Sign up or sign in to vote.
4.43/5 (5 votes)
17 Apr 2009CPOL3 min read 32.9K   716   11  
Schema based XML reader writer implemented as .NET COM generator
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Schema;
using System.CodeDom;
using System.CodeDom.Compiler;


using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Visitors;

namespace XmlSchemaWrapperGen
{
    /// <summary>
    /// Generates wrappers class for auto generated
    /// proxy classes made from xsd.exe tool.
    /// </summary>
    public class ImplementationGenerator
    {
        //List of complex schema object types (classes)
        List<string> m_schemaObjectsLst = new List<string>();
        //List of schema enumeration types types (enum)
        List<string> m_schemaEnumLst = new List<string>();
        string m_impNamespaceName = null;
        string m_InterfaceNamespaceName = null;
        string m_proxyNamespaceName = null;

        /// <summary>
        /// Guid for the factory class
        /// </summary>
        Guid m_factoryImpGuid;

        /// <summary>
        /// Generates wrappers COM objects for auto generated
        /// XML proxy classes made from xsd.exe tool.
        /// </summary>
        /// <param name="proxyFileCode">auto generated proxy file content
        /// made from xsd.exe tool
        /// </param>
        /// <param name="language">The code language</param>
        /// <param name="outputFilepath">Path to a file to create that will contain the code</param>
        /// <param name="schema">The XML schema</param>
        /// <param name="factoryGuid">The COM guid to set in the generated factory class </param>
        /// <remarks>
        /// The given proxy file content must be in VB.NET or C# language, and .NET 2.0 compatible
        /// </remarks>
        public void CreateComWrapper(TextReader proxyFileCode, SupportedLanguage language, Guid factoryGuid, string outputFilepath, string schema)
        {
            m_factoryImpGuid = factoryGuid;
            m_schemaObjectsLst.Clear();
            m_schemaEnumLst.Clear();

            if (proxyFileCode == null) throw new ArgumentNullException("proxyFileCode");

            string proxyCode = proxyFileCode.ReadToEnd();
            string rootClassName = GetRootElementClassName(new StringReader(proxyCode));
            if (string.IsNullOrEmpty(rootClassName))
                throw new ArgumentException("Failed locate the class that describes the XML root element in the code file", "proxyFile");

            TextReader reader = new StringReader(proxyCode);
            CodeNamespace ns = Parse(reader, language).Namespaces[0];
            CodeNamespace newNs = TransformToWrapper(ns, schema, rootClassName);
            WriteCode(newNs, language, outputFilepath);
        }

        /// <summary>
        /// Generates wrappers COM objects for auto generated
        /// XML proxy classes made from xsd.exe tool.
        /// </summary>
        /// <param name="proxyFileCode">auto generated proxy file content
        /// made from xsd.exe tool
        /// </param>
        /// <param name="schema">The XML schema</param>
        /// <param name="language">The code language</param>
        /// <param name="factoryGuid">The COM guid to set in the generated factory class </param>
        /// <returns>Namespace contains the wrapper implementation code.</returns>
        /// <remarks>
        /// The given proxy file content must be in VB.NET or C# language, and .NET 2.0 compatible
        /// </remarks>
        public CodeNamespace CreateComWrapper(TextReader proxyFileCode, SupportedLanguage language, Guid factoryGuid, string schema)
        {
            m_factoryImpGuid = factoryGuid;
            m_schemaObjectsLst.Clear();
            m_schemaEnumLst.Clear();

            if (proxyFileCode == null) throw new ArgumentNullException("proxyFileCode");

            string proxyCode = proxyFileCode.ReadToEnd();
            string rootClassName = GetRootElementClassName(new StringReader(proxyCode));
            if (string.IsNullOrEmpty(rootClassName))
                throw new ArgumentException("Failed locate the class that describes the XML root element in the code file", "proxyFile");

            TextReader reader = new StringReader(proxyCode);
            CodeNamespace ns = Parse(reader, language).Namespaces[0];
            return TransformToWrapper(ns, schema, rootClassName);
        }


        /// <summary>
        /// Returns the name of the root element class from
        /// xsd.exe auto generated code.
        /// </summary>
        /// <param name="schemaCodeReader">Reader to xsd.exe auto generated code</param>
        /// <returns>
        /// The name of the root element class, or null if no root alement was detected
        /// </returns>
        private string GetRootElementClassName( TextReader xsdSchemaCodeReader )
        {
            string xsdCode = xsdSchemaCodeReader.ReadToEnd();
            //finding close index to the class that is the owner of "XmlRootAttribute";
            int index = xsdCode.IndexOf("XmlRootAttribute");
            if( index < 0 ) return null;
            index = xsdCode.IndexOf(" class ", index);
            if( index < 0 ) return null;

            string abcStr = "abcdefghijklmnopqrstuvwxyz";

            int nameStartIndex = xsdCode.IndexOfAny(abcStr.ToCharArray(), index + " class ".Length);
            int nameStartIndex2 = xsdCode.IndexOfAny(abcStr.ToUpper().ToCharArray(), index + " class ".Length);
            if( nameStartIndex > 0 && nameStartIndex2 > 0  )
                nameStartIndex = Math.Min(nameStartIndex, nameStartIndex2);
            else 
                nameStartIndex = Math.Max(nameStartIndex, nameStartIndex2);

            char[] stopChars = new char[]{' ',';',':'};
            int nameLastIndex = xsdCode.IndexOfAny(stopChars, nameStartIndex);
            string className = xsdCode.Substring(nameStartIndex, nameLastIndex - nameStartIndex);
            return className;
        }


        /// <summary>
        /// Writes the given code to a file
        /// </summary>
        /// <param name="code">The code to write</param>
        /// <param name="language">The code language</param>
        /// <param name="filePath">The output file path</param>
        private void WriteCode( CodeNamespace code, SupportedLanguage language, string filePath)
        {
            string strLang = language == SupportedLanguage.CSharp ? "CSharp" : "VisualBasic";
            CodeDomProvider cp = CodeDomProvider.CreateProvider(strLang);
            CodeGeneratorOptions opt = new CodeGeneratorOptions();
            opt.BlankLinesBetweenMembers = true;
            opt.ElseOnClosing = false;
            opt.VerbatimOrder = true;

            StringBuilder stringBuilder = new StringBuilder(2000);
            TextWriter sw =  new StringWriter(stringBuilder); //new StreamWriter(filePath);

            try
            {
                cp.GenerateCodeFromNamespace(code, sw, opt);
            }
            finally{
                sw.Close();
            }

            switch (language)
            {
                case SupportedLanguage.CSharp:
                    stringBuilder.Replace("public class", "internal class");
                    stringBuilder.Replace("internal class XmlFactory", "public class XmlFactory");
                    break;
                case SupportedLanguage.VBNet:
                    stringBuilder.Replace("Public Class", "Private Class");
                    stringBuilder.Replace("Private Class XmlFactory", "Public Class XmlFactory");
                    break;
            }


            File.WriteAllText(filePath, stringBuilder.ToString());
            
        }

        public void CompileCSharpCode( List<string> files, string outputFilePath, bool generateXmlDocFile)
        {
            CompilerParameters comparam = new CompilerParameters(new string[] { "mscorlib.dll" });
            comparam.ReferencedAssemblies.Add("System.dll");
            comparam.ReferencedAssemblies.Add("System.Xml.dll");
            //Indicates Whether the compiler has to generate the output in //memory
            comparam.GenerateInMemory = false;
            //Indicates whether the output is an executable.
            comparam.GenerateExecutable = false;
            //provide the path where the generated assembly would be placed 
            comparam.OutputAssembly = outputFilePath;
            comparam.IncludeDebugInformation = false;
            comparam.TreatWarningsAsErrors = false;
            if (generateXmlDocFile)
            {
                string xmlDocFilePath = Path.GetDirectoryName(outputFilePath) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(outputFilePath) + ".xml";
                comparam.CompilerOptions = "/doc:" + '"' + xmlDocFilePath +'"';
            }

            CodeDomProvider cp = CodeDomProvider.CreateProvider("CSharp");
            CompilerResults compres = cp.CompileAssemblyFromFile(comparam, files.ToArray());
            StringBuilder strBuild = new StringBuilder(250);
            if (compres == null || compres.Errors.Count>0)
            {
                for (int i=0; i<compres.Errors.Count;i++)
                    strBuild.AppendLine(compres.Errors[i].ToString());
            } 

        }


        /// <summary>
        /// Attempts to parse a code stream into <see cref="CodeCompileUnit"/>
        /// </summary>
        /// <param name="reader">Reader to read from the code to parse</param>
        /// <param name="language">The programming language that the code is written at</param>
        /// <returns><see cref="CodeCompileUnit"/> that contains the parsed code.</returns>
        /// <exception cref="InvalidDataException">Thrown when parsing the code failed.</exception>
        private CodeCompileUnit Parse(System.IO.TextReader reader, SupportedLanguage language)
        {
            IParser parser = ParserFactory.CreateParser(language, reader);
            parser.Parse();

            if (parser.Errors.Count > 0)
            {
                string errMsg = string.Format("{0} errors detected while parsing the code stream: \r\n{1}", parser.Errors.Count, parser.Errors.ErrorOutput);
                throw new InvalidDataException(errMsg);
            }

            CodeDomVisitor visit = new CodeDomVisitor();
            visit.VisitCompilationUnit(parser.CompilationUnit, null);

            // Remove Unused Namespaces
            for (int i = 0; i < visit.codeCompileUnit.Namespaces.Count; ++i)
            {
                if (visit.codeCompileUnit.Namespaces[i].Types.Count == 0)
                    visit.codeCompileUnit.Namespaces.RemoveAt(i);
            }

            return visit.codeCompileUnit;
        }

        /// <summary>
        /// Accepts XML schema proxy code generated by xsd.exe tool
        /// and returns new code with corresponding class wrappers
        /// </summary>
        /// <param name="proxyNs">XML schema proxy code generated by xsd.exe tool</param>
        /// <param name="rootClassName">
        /// The name of the class in the given code, that represent the root element in XML.
        /// </param>
        /// <param name="schema">The XML schema</param>
        /// <returns>Code with corresponding wrappers</returns>
        private CodeNamespace TransformToWrapper(CodeNamespace proxyNs, string schema, string rootClassName)
        {
            m_proxyNamespaceName = proxyNs.Name;
            m_impNamespaceName = proxyNs.Name + ".ComXml";
            m_InterfaceNamespaceName = proxyNs.Name + ".ComXml.Interfaces";

            CodeNamespace ns = new CodeNamespace(m_impNamespaceName);
            ns.Imports.Add(new CodeNamespaceImport(m_InterfaceNamespaceName));

            CodeTypeDeclaration reader = CreateObjectReader("I" + rootClassName,schema, rootClassName);
            CodeTypeDeclaration writer = CreateObjectWriter("I" + rootClassName, rootClassName);
            CodeTypeDeclaration factory = CreateFactory(reader, writer, "IXmlValidator");
            ns.Types.Add(factory);

            ns.Types.AddRange( new CodeTypeDeclaration[] {reader, writer});
            //storing the names of all the classes and enumerations
            foreach (CodeTypeDeclaration type in proxyNs.Types)
            {
                if(type.IsClass)
                    m_schemaObjectsLst.Add(type.Name); //storing the names of all the classes
                else if( type.IsEnum )
                    m_schemaEnumLst.Add(type.Name);
            }
            //Creating com wrappers
            foreach( CodeTypeDeclaration type in proxyNs.Types )
            {
                if (!type.IsClass) continue;

                 AddXmlObjectExtractMthd(type, writer);

                CodeTypeDeclaration createdwrapper = GenerateComWrapper(type);
                ns.Types.Add(createdwrapper);
                AddFactoryCreationMthd(factory, createdwrapper);
            }            


            return ns;
        }

        /// <summary>
        /// Creates method that converts XmlSchema Wrapper instance into basic Xml Proxy type
        /// </summary>
        /// <param name="mthdOwner">The type to add the method to.</param>
        /// <param name="proxyType">The raw type to create extractor to.</param>
        private void AddXmlObjectExtractMthd( CodeTypeDeclaration proxyType, CodeTypeDeclaration mthdOwner)
        {
            CodeMemberMethod convMethd = new CodeMemberMethod();
            convMethd.Name = "GetProxyClass";
            convMethd.ReturnType = new CodeTypeReference(proxyType.Name);
            convMethd.Attributes = MemberAttributes.Private | MemberAttributes.Static;
            CodeParameterDeclarationExpression mthdParam = new CodeParameterDeclarationExpression( "I" + proxyType.Name, "xmlObject" );
            CodeArgumentReferenceExpression mthdArgRef = new CodeArgumentReferenceExpression(mthdParam.Name);
            convMethd.Parameters.Add(mthdParam);
            
            CodeVariableDeclarationStatement rawObjDecl = 
                             new CodeVariableDeclarationStatement(proxyType.Name, "rawObj",
                                                                  new CodeObjectCreateExpression(proxyType.Name));

            CodeVariableReferenceExpression rawObjRef = new CodeVariableReferenceExpression(rawObjDecl.Name);
            convMethd.Statements.Add(rawObjDecl);

            mthdOwner.Members.Add(convMethd);

            foreach (CodeTypeMember member in proxyType.Members)
            {
                if (member == null ) continue;
                if( !( member is CodeMemberProperty )) continue;
                
                CodeMemberProperty prop = member as CodeMemberProperty;
                CodePropertyReferenceExpression rawPropRef = new CodePropertyReferenceExpression(rawObjRef, prop.Name);
                CodePropertyReferenceExpression propRef = new CodePropertyReferenceExpression(mthdArgRef, prop.Name);

                //If the property is enumeration, transform the enumeration before assignment
                if (m_schemaEnumLst.Contains(prop.Type.BaseType))
                {
                    CodeTypeOfExpression typeofEnumExp = new CodeTypeOfExpression( m_proxyNamespaceName + "." + prop.Type.BaseType);
                    CodeMethodInvokeExpression mthd = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Enum)),
                                                    "Parse", typeofEnumExp,
                                                    new CodeMethodInvokeExpression(propRef, "ToString"));

                    convMethd.Statements.Add(new CodeAssignStatement(rawPropRef, new CodeCastExpression(typeofEnumExp.Type, mthd)));
                    continue;
                }

                //if the property is non complex type just copy the value
                else if( ! m_schemaObjectsLst.Contains(prop.Type.BaseType) )
                {
                   convMethd.Statements.Add( new CodeAssignStatement(rawPropRef,propRef) );
                    continue;
                }

                //by now surly a complex type: 
                if( prop.Type.ArrayRank == 0 )//non array type
                {
                    CodeMethodInvokeExpression extractRawMemberMthd = new CodeMethodInvokeExpression(null, convMethd.Name, propRef);
                    convMethd.Statements.Add( new CodeAssignStatement(rawPropRef,extractRawMemberMthd) );
                    continue;
                }

                //by now surly a complex type array
                 CodeStatement copyStatement = CreateComplexArrayToRawArrayCopyCode(propRef, rawPropRef, prop.Type.BaseType, convMethd.Name);
                convMethd.Statements.Add(copyStatement);
            }
            convMethd.Statements.Add(new CodeMethodReturnStatement(rawObjRef));

        }

        /// <summary>
        /// Generated code that copies array of XmlSchema object wrapper class instances,
        /// into array of raw xml proxy objects
        /// </summary>
        /// <param name="sourceArray">The array to copy from or null</param>
        /// <param name="targetArray">The array to copy to</param>
        /// <param name="arrayType">The type of the array to create</param>
        /// <param name="rawTypeExtractionMthdName">Name of method that converts wrapper types into raw types.</param>
        /// <returns>Collection of code statements</returns>
        private CodeStatement CreateComplexArrayToRawArrayCopyCode( CodeExpression sourceArray, CodeExpression targetArray, string arrayType, string rawTypeExtractionMthdName)
        {
            CodeStatementCollection statements = new CodeStatementCollection();
            CodePrimitiveExpression nullExp = new CodePrimitiveExpression(null);

            CodeAssignStatement nullAsignCode = new CodeAssignStatement(targetArray, nullExp);

            List<CodeStatement> copyingCode = new List<CodeStatement>();
            CodePropertyReferenceExpression srcArrLengthProp = 
                            new CodePropertyReferenceExpression(sourceArray, "Length");

            CodeAssignStatement assignArr = new CodeAssignStatement(targetArray, 
                        new CodeArrayCreateExpression(arrayType,srcArrLengthProp)
                        );
            copyingCode.Add(assignArr);
            CodeIterationStatement loopCode = CreateIterationStatement("i", srcArrLengthProp);
            CodeAssignStatement objAssign = new CodeAssignStatement( 
                        new CodeArrayIndexerExpression( targetArray, new CodeVariableReferenceExpression("i")),
                            new CodeMethodInvokeExpression(null, rawTypeExtractionMthdName,
                                new CodeArrayIndexerExpression(sourceArray,
                                                            new CodeVariableReferenceExpression("i")
                                                                )
                                                            )
                                                );

            loopCode.Statements.Add(objAssign);
            copyingCode.Add( loopCode );

            CodeBinaryOperatorExpression compToNull = 
               new CodeBinaryOperatorExpression (sourceArray,
                                                 CodeBinaryOperatorType.ValueEquality,
                                                    nullExp);

            CodeConditionStatement condState =
                new CodeConditionStatement(compToNull, new CodeStatement[] { nullAsignCode }, copyingCode.ToArray());

            return condState;
        }


        /// <summary>
        /// Creates factory with methods to create XML writer and XML writer
        /// </summary>
        /// <param name="reader">The object reader class</param>
        /// <param name="writer">The object writer class</param>
        /// <param name="validatorInterfactName">The name of the validation interface</param>
        /// <returns>The factory that was created</returns>
        private CodeTypeDeclaration CreateFactory(CodeTypeDeclaration reader, CodeTypeDeclaration writer, string validatorInterfactName)
        {
            CodeTypeDeclaration factory = new CodeTypeDeclaration("XmlFactory");
            factory.IsClass = true;
            factory.Attributes = MemberAttributes.Public;
            factory.BaseTypes.Add("IXmlFactory");
            factory.Comments.Add(new CodeCommentStatement("<summary>Factory class for constructing XML reading and writing objects according to a specific schema.</summary>", true));
            AddComAttributes(factory);

            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "CreateWriter";
            method.ReturnType = new CodeTypeReference( writer.BaseTypes[0].BaseType);
            method.Attributes = MemberAttributes.Public;
            method.Comments.Add(new CodeCommentStatement("<summary>Creates XML objects writer according to a specific schema.</summary>", true));
            method.Comments.Add(new CodeCommentStatement("<returns>The created writer.</returns>", true));
            CodeObjectCreateExpression create = new CodeObjectCreateExpression("XmlWriter");
            method.Statements.Add(new CodeMethodReturnStatement(create));
            factory.Members.Add(method);

            method = new CodeMemberMethod();
            method.Name = "CreateReader";
            method.ReturnType = new CodeTypeReference(reader.BaseTypes[0].BaseType);
            method.Attributes = MemberAttributes.Public;
            method.Comments.Add(new CodeCommentStatement("<summary>Creates XML objects reader according to a specific schema.</summary>", true));
            method.Comments.Add(new CodeCommentStatement("<returns>The created reader.</returns>", true));
            create = new CodeObjectCreateExpression("XmlReader", new CodePrimitiveExpression(null));
            method.Statements.Add(new CodeMethodReturnStatement(create));
            factory.Members.Add(method);

            method = new CodeMemberMethod();
            method.Name = "CreateReader";
            method.ReturnType = new CodeTypeReference(reader.BaseTypes[0].BaseType);
            method.Parameters.Add(new CodeParameterDeclarationExpression(validatorInterfactName, "validationHandler"));
            method.Attributes = MemberAttributes.Public;
            method.Comments.Add(new CodeCommentStatement("<summary>Creates XML objects writer according to a specific schema with validation handler.</summary>", true));
            method.Comments.Add(new CodeCommentStatement("<param name=\"validationHandler\">Validation events handler</param>", true));
            method.Comments.Add(new CodeCommentStatement("<returns>The created reader.</returns>", true));
            create = new CodeObjectCreateExpression("XmlReader", new CodeArgumentReferenceExpression("validationHandler"));
            method.Statements.Add(new CodeMethodReturnStatement(create));
            factory.Members.Add(method);
            return factory;
        }

        /// <summary>
        /// Add object creation method to a factory.
        /// </summary>
        /// <param name="factory">The factory to add the method to</param>
        /// <param name="typeToCreate">The type of object that the method should return.</param>
        private void AddFactoryCreationMthd( CodeTypeDeclaration factory,  CodeTypeDeclaration typeToCreate)
        {
            //Remove the 'Wrapper' postfix from the type name
            string typeName = typeToCreate.Name.Substring(0, typeToCreate.Name.LastIndexOf("Wrapper"));

            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Create" + typeName;
            method.ReturnType = new CodeTypeReference(typeToCreate.BaseTypes[0].BaseType);
            method.Attributes = MemberAttributes.Public;
            method.Comments.Add(new CodeCommentStatement("<summary>Creates and returns " + typeToCreate.Name + "</summary>", true));
            method.Comments.Add(new CodeCommentStatement("<returns>The created "+ typeToCreate.Name +".</returns>", true));
            CodeObjectCreateExpression create = new CodeObjectCreateExpression(typeToCreate.Name);
            method.Statements.Add(new CodeMethodReturnStatement(create));
            factory.Members.Add(method);
        }


        /// <summary>
        /// Creates and returns XML reader objects that reads
        /// objects from XML file or stream.
        /// </summary>
        /// <param name="readingTypeName">The name of the type that the reader should return.</param>
        /// <param name="schmea">The XML schema</param>
        /// <param name="schemaRootClassName">The name of the root element in the schema proxy code</param>
        /// <returns>XML reader objects that reads XML stream according to schema</returns>
        private CodeTypeDeclaration CreateObjectReader( string readingTypeName, string schmea, string schemaRootClassName)
        {
            CodeTypeDeclaration reader = new CodeTypeDeclaration("XmlReader");
            reader.IsClass = true;
            reader.Attributes = MemberAttributes.Public;
            reader.BaseTypes.Add("IXmlReader");
            AddComAttributes(reader);

            //adding private members
            CodeMemberField readerSettingsField = new CodeMemberField(typeof(System.Xml.XmlReaderSettings), "m_xmlReaderSettings");
            readerSettingsField.Attributes = MemberAttributes.Private | MemberAttributes.Static;
            reader.Members.Add(readerSettingsField);

            CodeMemberField serializerField = new CodeMemberField(typeof(System.Xml.Serialization.XmlSerializer), "m_serializer");
            serializerField.Attributes = MemberAttributes.Private | MemberAttributes.Static;
            reader.Members.Add(serializerField);

            CodeMemberField schemaField = new CodeMemberField(typeof(string), "m_schemaStr");
            schemaField.Attributes = MemberAttributes.Private | MemberAttributes.Static;
            schemaField.InitExpression = new CodePrimitiveExpression(schmea);
            reader.Members.Add(schemaField);

            CodeMemberField validatorField = new CodeMemberField("IXmlValidator", "m_validator");
            validatorField.Attributes = MemberAttributes.Private;
            reader.Members.Add(validatorField);

            CodeConstructor ctor = new CodeConstructor();
            ctor.Attributes = MemberAttributes.Assembly;
            CodeParameterDeclarationExpression ctorArg = new CodeParameterDeclarationExpression("IXmlValidator", "validatorHandler");
            ctor.Parameters.Add(ctorArg);

            CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression();
            CodeFieldReferenceExpression validatorFieldRef = new CodeFieldReferenceExpression(thisRef, validatorField.Name);
            CodeFieldReferenceExpression settingFieldRef = new CodeFieldReferenceExpression(null, "m_xmlReaderSettings");
            ctor.Statements.Add(new CodeAssignStatement( validatorFieldRef,new CodeArgumentReferenceExpression(ctorArg.Name) ));

            CodePrimitiveExpression nullExp = new CodePrimitiveExpression(null);
            Type factoryType = typeof(System.Xml.Serialization.XmlSerializerFactory);
            CodeVariableDeclarationStatement factVarDecl = new CodeVariableDeclarationStatement(factoryType, "fact", new CodeObjectCreateExpression(factoryType));
            ctor.Statements.Add(factVarDecl);
            
            CodeFieldReferenceExpression serializerRef = new CodeFieldReferenceExpression(null, serializerField.Name);
            CodeMethodInvokeExpression createSerializerMthd = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression(factVarDecl.Name),"CreateSerializer", new CodeTypeOfExpression(schemaRootClassName));
            ctor.Statements.Add(new CodeAssignStatement(serializerRef, createSerializerMthd));

            CodeDelegateCreateExpression validationDel = new CodeDelegateCreateExpression( new CodeTypeReference(typeof(System.Xml.Schema.ValidationEventHandler)), thisRef,"OnSchemaValidateXmlError" );
            CodeMethodInvokeExpression scheamCreatMthd =
               new CodeMethodInvokeExpression(
                  new CodeVariableReferenceExpression("System.Xml.Schema.XmlSchema"),
                 "Read", new CodeObjectCreateExpression(typeof(StringReader),
                            new CodeFieldReferenceExpression(null, schemaField.Name)), 
                                                              validationDel);


            CodeVariableDeclarationStatement schemVarDecl = new CodeVariableDeclarationStatement(typeof(System.Xml.Schema.XmlSchema), "schema", scheamCreatMthd);
            ctor.Statements.Add(schemVarDecl);

            CodeAssignStatement settingCreate = new CodeAssignStatement(settingFieldRef, new CodeObjectCreateExpression(typeof(System.Xml.XmlReaderSettings)));
            ctor.Statements.Add(settingCreate);
            
            CodeAssignStatement assign = new CodeAssignStatement(new CodePropertyReferenceExpression(settingFieldRef, "ValidationType"), new CodeVariableReferenceExpression("System.Xml.ValidationType.Schema"));
            ctor.Statements.Add(assign);

            CodeAttachEventStatement addDelegate = new CodeAttachEventStatement(settingFieldRef, "ValidationEventHandler", validationDel);
            ctor.Statements.Add(addDelegate);

            CodeMethodInvokeExpression addSchemaMthd = new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(settingFieldRef, "Schemas"), "Add", new CodeVariableReferenceExpression(schemVarDecl.Name));
            ctor.Statements.Add(addSchemaMthd);
            reader.Members.Add(ctor);
           
            //Adding validation method
            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "OnSchemaValidateXmlError";
            method.Attributes = MemberAttributes.Private;
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "sender"));
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(ValidationEventArgs), "e"));

            CodeBinaryOperatorExpression compare = new CodeBinaryOperatorExpression(
                validatorFieldRef, CodeBinaryOperatorType.ValueEquality, nullExp
                );
            method.Statements.Add(new CodeConditionStatement(compare, new CodeMethodReturnStatement()));

            CodeVariableDeclarationStatement sevVarDecl = new CodeVariableDeclarationStatement("ValidationSeverity", "sev", new CodeVariableReferenceExpression("ValidationSeverity.Error"));
            method.Statements.Add(sevVarDecl);

            CodeVariableReferenceExpression sevVarRef = new CodeVariableReferenceExpression(sevVarDecl.Name);
            CodePropertyReferenceExpression sevArgRef = new CodePropertyReferenceExpression( new CodeArgumentReferenceExpression(method.Parameters[1].Name), "Severity");
            assign = new CodeAssignStatement(sevVarRef, new CodeVariableReferenceExpression("ValidationSeverity.Warning"));
             compare = new CodeBinaryOperatorExpression(
                 sevArgRef , CodeBinaryOperatorType.ValueEquality, new CodeVariableReferenceExpression("System.Xml.Schema.XmlSeverityType.Warning")
                );
            method.Statements.Add(new CodeConditionStatement(compare, assign));

            CodePropertyReferenceExpression validateMsgArg = new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression(method.Parameters[1].Name), "Message");
            method.Statements.Add(new CodeMethodInvokeExpression(validatorFieldRef, "OnXmlSchemaValidationError", validateMsgArg, sevVarRef));
            reader.Members.Add(method);

            //Adding file reading method
            method = new CodeMemberMethod();
            method.Name = "ReadFromFile";
            method.Attributes = MemberAttributes.Public;
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "xmlFilePath"));
            method.ReturnType = new CodeTypeReference(readingTypeName);

            CodeMethodInvokeExpression readerCreatMthd = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("System.Xml.XmlReader"), "Create", new CodeArgumentReferenceExpression(method.Parameters[0].Name), settingFieldRef);
            CodeVariableDeclarationStatement readerVarDecl = new CodeVariableDeclarationStatement(typeof(System.Xml.XmlReader), "reader", readerCreatMthd);
            method.Statements.Add(readerVarDecl);

            CodeVariableDeclarationStatement compVarDecl = new CodeVariableDeclarationStatement(schemaRootClassName, "value", nullExp);
            method.Statements.Add(compVarDecl);

            CodeVariableReferenceExpression compVarRef = new CodeVariableReferenceExpression(compVarDecl.Name);
            CodeVariableReferenceExpression readerVarRef = new CodeVariableReferenceExpression(readerVarDecl.Name);
            CodeMethodInvokeExpression readMthd = new CodeMethodInvokeExpression(readerVarRef, "Read");
            CodeMethodInvokeExpression serialMthd = new CodeMethodInvokeExpression(serializerRef, "Deserialize", readerVarRef);
            assign = new CodeAssignStatement(compVarRef, new CodeCastExpression(schemaRootClassName, serialMthd));
            method.Statements.Add(new CodeConditionStatement(readMthd, assign));
            method.Statements.Add(new CodeMethodInvokeExpression(readerVarRef, "Close"));

            method.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(compVarRef, CodeBinaryOperatorType.ValueEquality, nullExp), new CodeMethodReturnStatement(nullExp)));
            method.Statements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression(schemaRootClassName+ "Wrapper" , compVarRef)));
            reader.Members.Add(method);

            //Add stream reading method
            method = new CodeMemberMethod();
            method.Name = "ReadFromStream";
            method.Attributes = MemberAttributes.Public;
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "xmlStream"));
            method.ReturnType = new CodeTypeReference(readingTypeName);

            CodeObjectCreateExpression createStrReader = new CodeObjectCreateExpression(typeof(System.IO.StringReader), new CodeArgumentReferenceExpression(method.Parameters[0].Name));
            readerCreatMthd = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("System.Xml.XmlReader"), "Create",createStrReader , settingFieldRef);
            readerVarDecl = new CodeVariableDeclarationStatement(typeof(System.Xml.XmlReader), "reader", readerCreatMthd);
            method.Statements.Add(readerVarDecl);
            method.Statements.Add(compVarDecl);
            method.Statements.Add(new CodeConditionStatement(readMthd, assign));
            method.Statements.Add(new CodeMethodInvokeExpression(readerVarRef, "Close"));
            method.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(compVarRef, CodeBinaryOperatorType.ValueEquality, nullExp), new CodeMethodReturnStatement(nullExp)));
            method.Statements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression(schemaRootClassName + "Wrapper", compVarRef)));
            reader.Members.Add(method);

            //Adding properties:
            CodeMemberProperty prop = new CodeMemberProperty();
            prop.Name = "HasValidtionHandler";
            prop.Type = new CodeTypeReference(typeof(bool));
            prop.Attributes = MemberAttributes.Public;
            prop.GetStatements.Add(new CodeMethodReturnStatement(new CodeBinaryOperatorExpression(nullExp, CodeBinaryOperatorType.IdentityInequality, validatorFieldRef)));
            reader.Members.Add(prop);

            prop = new CodeMemberProperty();
            prop.Name = "Schema";
            prop.Type = new CodeTypeReference(typeof(string));
            prop.Attributes = MemberAttributes.Public;
            prop.GetStatements.Add( new CodeMethodReturnStatement( new CodeFieldReferenceExpression(null, schemaField.Name)));
            reader.Members.Add(prop);
            return reader;
        }


        /// <summary>
        /// Creates and returns XML writer objects that writes
        /// objects to XML file or stream.
        /// </summary>
        /// <param name="readingTypeName">The name of the type that the writer should return.</param>
        /// <param name="schemaRootClassName">The name of the root element in the schema proxy code</param>
        /// <returns>XML writer objects that writes XML stream according schema</returns>
        private CodeTypeDeclaration CreateObjectWriter(string WritingTypeName, string schemaRootClassName)
        {
            CodeTypeDeclaration writer = new CodeTypeDeclaration("XmlWriter");
            writer.IsInterface = false;
            writer.Attributes = MemberAttributes.Public;
            writer.BaseTypes.Add("IXmlWriter");
            AddComAttributes(writer);

            CodeMemberField serializerField = new CodeMemberField(typeof(System.Xml.Serialization.XmlSerializer), "m_serializer");
            serializerField.Attributes = MemberAttributes.Private | MemberAttributes.Static;
            writer.Members.Add(serializerField);

            CodeConstructor ctor = new CodeConstructor();
            ctor.Attributes = MemberAttributes.Assembly;

            Type factoryType = typeof(System.Xml.Serialization.XmlSerializerFactory);
            CodeVariableDeclarationStatement factVarDecl = new CodeVariableDeclarationStatement(factoryType, "fact", new CodeObjectCreateExpression(factoryType));
            ctor.Statements.Add(factVarDecl);

            CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression();
            CodeFieldReferenceExpression serializerRef = new CodeFieldReferenceExpression(null, serializerField.Name);
            CodeMethodInvokeExpression createSerializerMthd = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression(factVarDecl.Name), "CreateSerializer", new CodeTypeOfExpression(schemaRootClassName));
            ctor.Statements.Add(new CodeAssignStatement(serializerRef, createSerializerMthd));
            writer.Members.Add(ctor);

            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "WriteToFile";
            method.Attributes = MemberAttributes.Public;
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "outXmlFilePath"));
            method.Parameters.Add(new CodeParameterDeclarationExpression( WritingTypeName, "objectToWrite"));

            CodeObjectCreateExpression fileStreamCreate = 
                new CodeObjectCreateExpression(typeof(FileStream),
                new CodeArgumentReferenceExpression(method.Parameters[0].Name),
                new CodeVariableReferenceExpression("System.IO.FileMode.Create"), 
                new CodeVariableReferenceExpression("System.IO.FileAccess.Write")
                );
            CodeVariableDeclarationStatement streamVarDecl = new CodeVariableDeclarationStatement(typeof(Stream),
                                                                 "stream", fileStreamCreate);
            CodeVariableReferenceExpression streamVarRef = new CodeVariableReferenceExpression(streamVarDecl.Name);
            method.Statements.Add(streamVarDecl);

            CodeMethodInvokeExpression callRawObjMthd = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(writer.Name), "GetProxyClass", new CodeArgumentReferenceExpression(method.Parameters[1].Name));
            CodeVariableDeclarationStatement rawObjVarDecl = new CodeVariableDeclarationStatement(schemaRootClassName, "rawObj", callRawObjMthd);
            method.Statements.Add(rawObjVarDecl);
            CodeMethodInvokeExpression serialMthd = new CodeMethodInvokeExpression(serializerRef, "Serialize", streamVarRef, new CodeVariableReferenceExpression(rawObjVarDecl.Name));
            method.Statements.Add(serialMthd);
            method.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression(streamVarDecl.Name), "Close"));
            writer.Members.Add(method);

            method = new CodeMemberMethod();
            method.Name = "WriteToStream";
            method.Attributes = MemberAttributes.Public;
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "outXmlStream"));
            method.Parameters[0].Direction = FieldDirection.Out;
            method.Parameters.Add(new CodeParameterDeclarationExpression(WritingTypeName, "objectToWrite"));

            CodeObjectCreateExpression strBuildCreate= new CodeObjectCreateExpression(typeof(StringBuilder), new CodePrimitiveExpression(2000) );
            CodeVariableDeclarationStatement strBuildVarDecl = new CodeVariableDeclarationStatement(typeof(StringBuilder), "str", strBuildCreate);
            CodeVariableReferenceExpression  strBuildVarRef = new CodeVariableReferenceExpression(strBuildVarDecl.Name);
            method.Statements.Add(strBuildVarDecl);

            CodeObjectCreateExpression writerCreate = new CodeObjectCreateExpression(typeof(StringWriter), strBuildVarRef);
            CodeVariableDeclarationStatement writerVarDecl = new CodeVariableDeclarationStatement(typeof(StringWriter), "writer", writerCreate);
            CodeVariableReferenceExpression  writerVarRef = new CodeVariableReferenceExpression(writerVarDecl.Name);
            method.Statements.Add(writerVarDecl);

            callRawObjMthd = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(writer.Name), "GetProxyClass", new CodeArgumentReferenceExpression(method.Parameters[1].Name));
            rawObjVarDecl = new CodeVariableDeclarationStatement(schemaRootClassName, "rawObj", callRawObjMthd);
            method.Statements.Add(rawObjVarDecl);

            serialMthd = new CodeMethodInvokeExpression(serializerRef, "Serialize", writerVarRef, new CodeVariableReferenceExpression(rawObjVarDecl.Name));
            method.Statements.Add(serialMthd);
            method.Statements.Add(new CodeMethodInvokeExpression(writerVarRef, "Close"));
            method.Statements.Add(new CodeAssignStatement(
                                    new CodeArgumentReferenceExpression(method.Parameters[0].Name),
                                    new CodeMethodInvokeExpression(strBuildVarRef, "ToString"))
                                    );

            writer.Members.Add(method);       
            return writer;
        }


        /// <summary>
        /// Generates COM wrapper type form the given class type.
        /// </summary>
        /// <param name="classType">
        /// XML schema proxy class type generated by xsd.exe tool
        /// </param>
        /// <returns>Interface type</returns>
        /// <remarks>
        /// This method assumes that the type given is generated from xsd.exe tool
        /// thus, have a public get & set property for each data member 
        /// </remarks>
        private CodeTypeDeclaration GenerateComWrapper(CodeTypeDeclaration classType)
        {
            CodeTypeDeclaration wrapperType = new CodeTypeDeclaration( classType.Name + "Wrapper");
            wrapperType.IsClass = true;
            wrapperType.Attributes = MemberAttributes.Public;
            wrapperType.BaseTypes.Add("I" + classType.Name);
            AddComAttributes(wrapperType);

            //Creating c'tors
            CodeConstructor ctor = new CodeConstructor();//parameterless
            ctor.Attributes = MemberAttributes.Assembly;
            wrapperType.Members.Add(ctor); 

            //collecting snippets of code for other c'tors
            CodeStatementCollection codeStatements = new CodeStatementCollection();

            //Duplicate the properties & fields
            foreach (CodeTypeMember member in classType.Members)
            {
                if (member == null ) continue;
                if( member is CodeMemberField  )
                {
                    CodeMemberField field = member as CodeMemberField;
                    if (m_schemaObjectsLst.Contains(field.Type.BaseType))
                    {
                        CodeTypeReference typeRef = field.Type;
                        field.Type = new CodeTypeReference(typeRef.BaseType + "Wrapper");
                        field.Type.ArrayRank = typeRef.ArrayRank;
                        field.Type.Options = typeRef.Options;
                    }
                }
                else if( member is CodeMemberProperty )
                {
                    CodeMemberProperty prop = member as CodeMemberProperty;
                    CodeArgumentReferenceExpression arg = new CodeArgumentReferenceExpression("wrappedObject");//C'tor argument reference
                    CodePropertyReferenceExpression argProp =  new CodePropertyReferenceExpression(arg,prop.Name);
                    CodePropertyReferenceExpression localProp = new CodePropertyReferenceExpression( new CodeThisReferenceExpression(), prop.Name);
                    if (m_schemaObjectsLst.Contains(prop.Type.BaseType))//none primitive type( wrapper is needed )
                    {
                        CodeTypeReference orgType = prop.Type;
                        prop.Type = new CodeTypeReference("I" + orgType.BaseType );
                        prop.Type.ArrayRank = orgType.ArrayRank;
                        if (orgType.ArrayRank < 1)
                        {// non array
                            CodeAssignStatement setCode = prop.SetStatements[0] as CodeAssignStatement;
                            setCode.Right = new CodeObjectCreateExpression(orgType.BaseType + "Wrapper", new CodeVariableReferenceExpression("value"));
                            codeStatements.Add(new CodeAssignStatement(localProp, new CodeObjectCreateExpression(orgType.BaseType + "Wrapper", argProp)));                        
                        }
                        else{//array of complex type
                            CodeAssignStatement orgSetCode = prop.SetStatements[0] as CodeAssignStatement;
                            prop.SetStatements.Clear();
                            prop.SetStatements.AddRange(

                                CreateArrayCopyCode(orgSetCode.Right, orgSetCode.Left, new CodeTypeReference(orgType.BaseType + "Wrapper"))
                                );

                            //The ctor will need copying as well:
                           codeStatements.AddRange(
                               CreateArrayCopyCode(new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("wrappedObject"), prop.Name), orgSetCode.Left, new CodeTypeReference(orgType.BaseType + "Wrapper"))
                            );
                        }
                    }
                    else if(m_schemaEnumLst.Contains(prop.Type.BaseType))//is enumeration type
                    {
                        CodeTypeOfExpression typeofEnumExp = new CodeTypeOfExpression(prop.Type);
                        CodeMethodInvokeExpression mthd = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(Enum)),
                                                    "Parse", typeofEnumExp,
                                                    new CodeMethodInvokeExpression(argProp, "ToString"));

                        codeStatements.Add(new CodeAssignStatement(localProp, new CodeCastExpression(typeofEnumExp.Type, mthd)));
                     }
                    else
                        codeStatements.Add( new CodeAssignStatement(localProp, argProp));
                }
                wrapperType.Members.Add( member);
            }

            //C'tor with Interface as parameter
            ctor = new CodeConstructor();
            ctor.Attributes = MemberAttributes.Assembly;
            ctor.Parameters.Add(new CodeParameterDeclarationExpression("I" + classType.Name, "wrappedObject"));
            ctor.Statements.AddRange(codeStatements);
            wrapperType.Members.Add(ctor);

            //C'tor with raw schema object as parameter
            ctor = new CodeConstructor();
            ctor.Attributes = MemberAttributes.Assembly;
            ctor.Parameters.Add(new CodeParameterDeclarationExpression(classType.Name, "wrappedObject"));
            ctor.Statements.AddRange(codeStatements);
            wrapperType.Members.Add(ctor);
            
            return wrapperType;
        }

        

        /// <summary>
        /// Adds COM attributes to the given code type(Class or Interface)
        /// </summary>
        /// <param name="type">The class or interface to add COM attributes to</param>
        private void AddComAttributes(CodeTypeDeclaration type)
        {
            if (!type.IsInterface && !type.IsClass)
                throw new ArgumentException("Cannot add COM attributes to non class or interface", "type");

            CodeAttributeDeclaration guidAttr = new CodeAttributeDeclaration(
                new CodeTypeReference(typeof(System.Runtime.InteropServices.GuidAttribute))
                );

            CodeExpression exp = null;
            if (type.BaseTypes[0].BaseType != "IXmlFactory")
               exp = new CodePrimitiveExpression(Guid.NewGuid().ToString().ToUpper());
            else
               exp = new CodePrimitiveExpression(m_factoryImpGuid.ToString());

            guidAttr.Arguments.Add(new CodeAttributeArgument(exp));
            type.CustomAttributes.Add(guidAttr);

            CodeAttributeDeclaration comVisibleAttr = new CodeAttributeDeclaration(
                new CodeTypeReference(typeof(System.Runtime.InteropServices.ComVisibleAttribute))
                );

            if (type.BaseTypes[0].BaseType == "IXmlFactory") 
                exp = new CodePrimitiveExpression(true);
            else
                exp = new CodePrimitiveExpression(false);

            comVisibleAttr.Arguments.Add(new CodeAttributeArgument(exp));
            type.CustomAttributes.Add(comVisibleAttr);

            if (type.IsInterface)
            {
                CodeAttributeDeclaration comInterfaceTypeAttr = new CodeAttributeDeclaration(
                     new CodeTypeReference(typeof(System.Runtime.InteropServices.InterfaceTypeAttribute))
                    );

                CodePropertyReferenceExpression enumRef = new CodePropertyReferenceExpression(
                        new CodeVariableReferenceExpression("System.Runtime.InteropServices.ComInterfaceType"), "InterfaceIsIUnknown"
                        );

                comInterfaceTypeAttr.Arguments.Add(new CodeAttributeArgument(enumRef));
                type.CustomAttributes.Add(comInterfaceTypeAttr);
            }            
        }

        /// <summary>
        /// Generated array copying code
        /// </summary>
        /// <param name="sourceArray">The array to copy from or null</param>
        /// <param name="targetArray">The array to copy to</param>
        /// <param name="arrayType">The type elements in the target array</param>
        /// <returns>Collection of code statements</returns>
        private CodeStatementCollection CreateArrayCopyCode( CodeExpression sourceArray, CodeExpression targetArray, CodeTypeReference arrayType)
        {
            CodeStatementCollection statements = new CodeStatementCollection();
            CodePrimitiveExpression nullExp = new CodePrimitiveExpression(null);

            CodeAssignStatement nullAsignCode = new CodeAssignStatement(targetArray, nullExp);

            List<CodeStatement> copyingCode = new List<CodeStatement>();
            CodePropertyReferenceExpression srcArrLengthProp = 
                            new CodePropertyReferenceExpression(sourceArray, "Length");

            CodeAssignStatement assignArr = new CodeAssignStatement(targetArray, 
                        new CodeArrayCreateExpression(arrayType,srcArrLengthProp)
                        );
            copyingCode.Add(assignArr);
            CodeIterationStatement loopCode = CreateIterationStatement("i", srcArrLengthProp);
            CodeAssignStatement objAssign = new CodeAssignStatement( 
                        new CodeArrayIndexerExpression( targetArray, new CodeVariableReferenceExpression("i")),
                            new CodeObjectCreateExpression(arrayType,
                                new CodeArrayIndexerExpression(sourceArray,
                                                            new CodeVariableReferenceExpression("i")
                                                                )
                                                            )
                                                );

            loopCode.Statements.Add(objAssign);
            copyingCode.Add( loopCode );

            CodeBinaryOperatorExpression compToNull = 
               new CodeBinaryOperatorExpression (sourceArray,
                                                 CodeBinaryOperatorType.ValueEquality,
                                                    nullExp);

            CodeConditionStatement condState =
                new CodeConditionStatement(compToNull, new CodeStatement[] { nullAsignCode }, copyingCode.ToArray());

            return new CodeStatementCollection(new CodeStatement[] { condState });           
        }

        /// <summary>
        /// Creates loop code expression with integer indexer with the given name that will iterate specific amount of times.
        /// </summary>
        /// <param name="interatorIndexVarName">The name of the iteration integer variable(will be set to zero)</param>
        /// <param name="iterationCount">Code expression that specifies the number of iteration</param>
        /// <remarks>The iterator is zero based indexer.</remarks>
        /// <returns>Iteration code with no inner statements.</returns>
        private CodeIterationStatement CreateIterationStatement(string interatorIndexVarName, CodeExpression iterationCount)
        {
            CodeVariableDeclarationStatement iterVar = new CodeVariableDeclarationStatement(typeof(int), interatorIndexVarName, new CodePrimitiveExpression(0));
            return new CodeIterationStatement(
                //new CodeAssignStatement(new CodeVariableReferenceExpression("testInt"), new CodePrimitiveExpression(1)),
                iterVar,
                new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression(interatorIndexVarName),
                    CodeBinaryOperatorType.LessThan, iterationCount),
                new CodeAssignStatement(new CodeVariableReferenceExpression(interatorIndexVarName), new CodeBinaryOperatorExpression(
                    new CodeVariableReferenceExpression(interatorIndexVarName), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))
                    ));
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
Israel Israel
Born and raised in Israel, caught the programming virus at the age of 15.
Since than I can't stop coding.

Comments and Discussions