Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

An XML Schema Definition (XSD) Editor and Strongly-Typed Configuration Class Generator

, 20 Jul 2009 CPOL
An editor capable of producing commmon XSD documents and generating strongly-typed configuration class corresponding to the XML schema (XSD) file
ConfigClassGen_demo.zip
ConfigClassGen_demo
VS2005
ConfigClassGenDemo
ConfigClassGenDemo
bin
Debug
ConfigClassGen.exe
ConfigClassGenDemo.csproj.user
Properties
VS2008
ConfigClassGenDemo
ConfigClassGenDemo
bin
Debug
ConfigClassGen.exe
ConfigClassGenDemo.csproj.user
Properties
ConfigClassGen_exe.zip
ConfigClassGen_exe
DotNet2.0
ConfigClassGen
ConfigClassGen.exe
ConfigClassGenDemo
ConfigClassGenDemo.exe
DotNet3.5
ConfigClassGen
ConfigClassGen.exe
ConfigClassGenDemo
ConfigClassGenDemo.exe
ConfigClassGen_src.zip
ConfigClassGen_src
VS2005
ConfigClassGen
ConfigClassGen
Properties
Settings.settings
VS2008
ConfigClassGen
ConfigClassGen
Properties
Settings.settings
/*
 * XML Schema Editor
 * This code may be freely modified and distributed.
 * 
 * History:
 * 
 * Version 1.0
 *	First release, Marc Clifton
*/
/*
 * Version 1.0
 * 
 * Quirks:
 *	1. Clicking on node A while in the middle of editing node B results in the name being changed for node A (mouse down event handler sets the current node!)
 *	2. After editing the schema in the text edit box, you MUST compile otherwise changes will be lost!
 *	3. If the tree node doesn't match the schema object, there are blank lines in the XSD file which are causing synchronization problems.  Select "Schema/Compile" from menu.
 * 
 * Bugs:
 *   1. Editing the name of a complex type adds a "name" to the CT, not the parent element
 * 
 * Features:
 *	dynamically adjusts for global and local types
 *	dynamically creates complex types from elements
 *	selecting a tree node highlights the corresponding XML text
 *	compiler error window
 *	xml can be edited directly instead of using the tree
 *	creates and manages global types list as types are added and removed
 *	keyboard shortcuts:
 *		F2-edit node label
 *		Ctrl-A : add to schema at current node
 *		Ctrl-T : go to top of schema
 *		Ctrl-P : got to parent of current node
 * 
 * Notes:
 * 
 * Need to do:
 * 
 * Missing features:
 *	Auto-scroll edit box to show selected node
 *	Remember selected node when compiling schema
 *	Implement XmlSchemaElement minOccurs and maxOccurs with GUI to enter values
 *	Implement XmlSchemaAttribute fixed and use with GUI to enter values
 *	Implement XmlSchemaGroup
 *	...others?
 * 
 */

/*
 * XML Schema Editor and Strongly-Typed Configuration Class Generator
 * This code may be freely modified and distributed.
 * 
 * History:
 * 
 * Version 1.0
 *	First release, Song Gao
*/
/*
 * Version 1.0
 * 
 * Features:
 *  This is an extension to Marc Clifton's XML Schema Editor. 
 *  In addition to the existing XML schema editing function, 
 *  it can generate strongly-typed configuration class based on an XML schema.
 *  
 *  There're two ways to generate the strongly-typed configuration class:
 *  1. Run this application to edit an XML schema and generate the corresponding 
 *     strongly-typed configuration class from the interface.
 *  2. Integrate into your VS project to generate the strongly-typed configuration class transparently 
 *     behind the scene. This is done by calling this application through command line.
 *  
 * Need to do:
 *	1. it supports string, int and long type only, need to add support to other types such as bool and datetime
 *	2. it can generate C# code only, need to add support to other languages such as VB.net
 *	3. need to enhance exception handling code in the generated class to deliver more detailed error messages
 */

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Schema;
using System.Text;

using System.CodeDom;
using System.CodeDom.Compiler;

namespace ConfigClassGen
{
    public class SchemaEditor : System.Windows.Forms.Form
    {
        #region data
        private System.Windows.Forms.TreeView tvSchema;
        private System.Windows.Forms.ContextMenu tvcmSchema;
        private System.Windows.Forms.MenuItem mnuAddElement;
        private System.ComponentModel.IContainer components;
        private System.Windows.Forms.TextBox edSchema;
        private System.Windows.Forms.MenuItem mnuAddSimpleType;
        private System.Windows.Forms.MenuItem mnuAddComplexType;
        private System.Windows.Forms.MainMenu mainMenu;
        private System.Windows.Forms.MenuItem mnuFile;
        private System.Windows.Forms.MenuItem mnuNew;
        private System.Windows.Forms.MenuItem mnuOpen;
        private System.Windows.Forms.MenuItem mnuSave;
        private System.Windows.Forms.MenuItem mnuSaveAs;
        private System.Windows.Forms.MenuItem mnuExit;
        private System.Windows.Forms.MenuItem menuItem2;
        private System.Windows.Forms.MenuItem menuItem3;
        private System.Windows.Forms.MenuItem mnuAbout;
        private System.Windows.Forms.OpenFileDialog openSchemaDialog;
        private System.Windows.Forms.ImageList tvImageList;
        private System.Windows.Forms.MenuItem mnuAddAnnotation;
        private System.Windows.Forms.MenuItem mnuAddAttribute;
        private System.Windows.Forms.TextBox edSchemaErrors;
        private System.Windows.Forms.MenuItem menuItem1;
        private System.Windows.Forms.MenuItem mnuCompile;
        private System.Windows.Forms.GroupBox gbSelectType;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.MenuItem menuItem4;
        private System.Windows.Forms.MenuItem mnuRemoveNode;
        private System.Windows.Forms.MenuItem menuItem6;
        private System.Windows.Forms.MenuItem menuItem7;
        private System.Windows.Forms.MenuItem menuItem5;
        private System.Windows.Forms.MenuItem menuItem9;
        private System.Windows.Forms.ComboBox cbGlobalTypes;
        private System.Windows.Forms.ComboBox cbSimpleTypes;
        private XmlSchema schema;
        private System.Windows.Forms.MenuItem mnuFacetEnumeration;
        private System.Windows.Forms.MenuItem mnuFacetMaxExclusive;
        private System.Windows.Forms.MenuItem mnuFacetMaxInclusive;
        private System.Windows.Forms.MenuItem mnuFacetMinExclusive;
        private System.Windows.Forms.MenuItem mnuFacetMinInclusive;
        private System.Windows.Forms.MenuItem mnuFacetNumeric;
        private System.Windows.Forms.MenuItem mnuFacetPattern;
        private System.Windows.Forms.MenuItem mnuFacetWhiteSpace;
        private System.Windows.Forms.MenuItem mnuFacetFractionDigits;
        private System.Windows.Forms.MenuItem mnuFacetLength;
        private System.Windows.Forms.MenuItem mnuFacetMaxLength;
        private System.Windows.Forms.MenuItem mnuFacetMinLength;
        private System.Windows.Forms.MenuItem mnuFacetTotalDigits;
        private System.Windows.Forms.MenuItem mnuAddDocumentation;
        private System.Windows.Forms.MenuItem mnuAddAppInfo;
        private string prevLabel;
        private System.Windows.Forms.SaveFileDialog saveAsSchemaDialog;
        private System.Windows.Forms.MenuItem menuItem8;
        private string fileName = null;
        enum TreeViewImages { Schema, Element, SimpleType, ComplexType, Annotation, Documentation, AppInfo, Attribute, Facet };
        #endregion

        private string outputFileName = null;
        private string outputNamespace = null;
        private StringBuilder sbOutput = new StringBuilder();
        private StringBuilder sbField = new StringBuilder();
        private StringBuilder sbProperty = new StringBuilder();
        private StringBuilder sbLoadValue = new StringBuilder();
        private CodeMemberMethod loadAppValuesMethod;

        private CodeCompileUnit targetUnit;
        private MenuItem menuItem10;
        private bool flagTopElement = true;

        #region GlobalElementType
        public class GlobalElementType
        {
            public GlobalElementType(string name, XmlSchemaObject type)
            {
                this.name = name;
                this.type = type;
            }

            public override string ToString()
            {
                return name;
            }

            public string Get()
            {
                return name;
            }

            public void Set(string name)
            {
                this.name = name;
            }

            public string name;
            public XmlSchemaObject type;
        }
        #endregion

        #region SchemaEditor Class
        public SchemaEditor(string _InputFileName, string _OutputFileName, string _outputNamespace)
            : this()
        {
            fileName = _InputFileName;
            outputFileName = _OutputFileName;
            outputNamespace = _outputNamespace;
        }

        public SchemaEditor(string _InputFileName, string _OutputFileName)
            : this()
        {
            fileName = _InputFileName;
            outputFileName = _OutputFileName;
        }

        public SchemaEditor(string _InputFileName)
            : this()
        {
            fileName = _InputFileName;
        }

        public SchemaEditor()
        {
            InitializeComponent();
            CreateRootNode();
            tvSchema.LabelEdit = true;
            tvSchema.KeyUp += new KeyEventHandler(EventTreeViewKeyUp);
            tvSchema.BeforeLabelEdit += new NodeLabelEditEventHandler(PreEventLabelChanged);
            tvSchema.AfterLabelEdit += new NodeLabelEditEventHandler(EventLabelChanged);
            tvSchema.MouseDown += new MouseEventHandler(EventMouseDown);
            edSchema.LostFocus += new EventHandler(EventSchemaTextBoxLostFocus);
            schema = new XmlSchema();
            CompileSchema();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }


        [STAThread]
        static void Main(string[] args)
        {
            if (args.Length >= 3)
                Application.Run(new SchemaEditor(args[0], args[1], args[2]));
            else if (args.Length >= 2)
                Application.Run(new SchemaEditor(args[0], args[1]));
            else if (args.Length >= 1)
                Application.Run(new SchemaEditor(args[0]));
            else
                Application.Run(new SchemaEditor());

        }

        #endregion

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SchemaEditor));
            this.tvSchema = new System.Windows.Forms.TreeView();
            this.tvcmSchema = new System.Windows.Forms.ContextMenu();
            this.mnuAddElement = new System.Windows.Forms.MenuItem();
            this.mnuAddSimpleType = new System.Windows.Forms.MenuItem();
            this.mnuAddComplexType = new System.Windows.Forms.MenuItem();
            this.mnuAddAttribute = new System.Windows.Forms.MenuItem();
            this.menuItem9 = new System.Windows.Forms.MenuItem();
            this.menuItem5 = new System.Windows.Forms.MenuItem();
            this.mnuAddAnnotation = new System.Windows.Forms.MenuItem();
            this.mnuAddDocumentation = new System.Windows.Forms.MenuItem();
            this.mnuAddAppInfo = new System.Windows.Forms.MenuItem();
            this.menuItem4 = new System.Windows.Forms.MenuItem();
            this.menuItem7 = new System.Windows.Forms.MenuItem();
            this.mnuFacetEnumeration = new System.Windows.Forms.MenuItem();
            this.mnuFacetMaxExclusive = new System.Windows.Forms.MenuItem();
            this.mnuFacetMaxInclusive = new System.Windows.Forms.MenuItem();
            this.mnuFacetMinExclusive = new System.Windows.Forms.MenuItem();
            this.mnuFacetMinInclusive = new System.Windows.Forms.MenuItem();
            this.mnuFacetNumeric = new System.Windows.Forms.MenuItem();
            this.mnuFacetFractionDigits = new System.Windows.Forms.MenuItem();
            this.mnuFacetLength = new System.Windows.Forms.MenuItem();
            this.mnuFacetMaxLength = new System.Windows.Forms.MenuItem();
            this.mnuFacetMinLength = new System.Windows.Forms.MenuItem();
            this.mnuFacetTotalDigits = new System.Windows.Forms.MenuItem();
            this.mnuFacetPattern = new System.Windows.Forms.MenuItem();
            this.mnuFacetWhiteSpace = new System.Windows.Forms.MenuItem();
            this.menuItem6 = new System.Windows.Forms.MenuItem();
            this.mnuRemoveNode = new System.Windows.Forms.MenuItem();
            this.tvImageList = new System.Windows.Forms.ImageList(this.components);
            this.edSchema = new System.Windows.Forms.TextBox();
            this.mainMenu = new System.Windows.Forms.MainMenu(this.components);
            this.mnuFile = new System.Windows.Forms.MenuItem();
            this.mnuNew = new System.Windows.Forms.MenuItem();
            this.mnuOpen = new System.Windows.Forms.MenuItem();
            this.menuItem3 = new System.Windows.Forms.MenuItem();
            this.mnuSave = new System.Windows.Forms.MenuItem();
            this.mnuSaveAs = new System.Windows.Forms.MenuItem();
            this.menuItem2 = new System.Windows.Forms.MenuItem();
            this.mnuExit = new System.Windows.Forms.MenuItem();
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.mnuCompile = new System.Windows.Forms.MenuItem();
            this.menuItem8 = new System.Windows.Forms.MenuItem();
            this.menuItem10 = new System.Windows.Forms.MenuItem();
            this.mnuAbout = new System.Windows.Forms.MenuItem();
            this.openSchemaDialog = new System.Windows.Forms.OpenFileDialog();
            this.edSchemaErrors = new System.Windows.Forms.TextBox();
            this.gbSelectType = new System.Windows.Forms.GroupBox();
            this.cbGlobalTypes = new System.Windows.Forms.ComboBox();
            this.cbSimpleTypes = new System.Windows.Forms.ComboBox();
            this.label2 = new System.Windows.Forms.Label();
            this.label1 = new System.Windows.Forms.Label();
            this.saveAsSchemaDialog = new System.Windows.Forms.SaveFileDialog();
            this.gbSelectType.SuspendLayout();
            this.SuspendLayout();
            // 
            // tvSchema
            // 
            this.tvSchema.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)));
            this.tvSchema.ContextMenu = this.tvcmSchema;
            this.tvSchema.FullRowSelect = true;
            this.tvSchema.HideSelection = false;
            this.tvSchema.ImageIndex = 0;
            this.tvSchema.ImageList = this.tvImageList;
            this.tvSchema.Location = new System.Drawing.Point(8, 8);
            this.tvSchema.Name = "tvSchema";
            this.tvSchema.SelectedImageIndex = 0;
            this.tvSchema.Size = new System.Drawing.Size(280, 432);
            this.tvSchema.TabIndex = 0;
            this.tvSchema.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvSchema_AfterSelect);
            // 
            // tvcmSchema
            // 
            this.tvcmSchema.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuAddElement,
            this.mnuAddSimpleType,
            this.mnuAddComplexType,
            this.mnuAddAttribute,
            this.menuItem9,
            this.menuItem5,
            this.menuItem4,
            this.menuItem7,
            this.menuItem6,
            this.mnuRemoveNode});
            // 
            // mnuAddElement
            // 
            this.mnuAddElement.Index = 0;
            this.mnuAddElement.Text = "Element";
            this.mnuAddElement.Click += new System.EventHandler(this.mnuAddElement_Click);
            // 
            // mnuAddSimpleType
            // 
            this.mnuAddSimpleType.Index = 1;
            this.mnuAddSimpleType.Text = "Simple Type";
            this.mnuAddSimpleType.Click += new System.EventHandler(this.mnuAddSimpleType_Click);
            // 
            // mnuAddComplexType
            // 
            this.mnuAddComplexType.Index = 2;
            this.mnuAddComplexType.Text = "Complex Type";
            this.mnuAddComplexType.Click += new System.EventHandler(this.mnuAddComplexType_Click);
            // 
            // mnuAddAttribute
            // 
            this.mnuAddAttribute.Index = 3;
            this.mnuAddAttribute.Text = "Attribute";
            this.mnuAddAttribute.Click += new System.EventHandler(this.mnuAddAttribute_Click);
            // 
            // menuItem9
            // 
            this.menuItem9.Index = 4;
            this.menuItem9.Text = "-";
            // 
            // menuItem5
            // 
            this.menuItem5.Index = 5;
            this.menuItem5.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuAddAnnotation,
            this.mnuAddDocumentation,
            this.mnuAddAppInfo});
            this.menuItem5.Text = "Annotation";
            // 
            // mnuAddAnnotation
            // 
            this.mnuAddAnnotation.Index = 0;
            this.mnuAddAnnotation.Text = "Annotation";
            this.mnuAddAnnotation.Click += new System.EventHandler(this.mnuAddAnnotation_Click);
            // 
            // mnuAddDocumentation
            // 
            this.mnuAddDocumentation.Index = 1;
            this.mnuAddDocumentation.Text = "Documentation";
            this.mnuAddDocumentation.Click += new System.EventHandler(this.mnuAddDocumentation_Click);
            // 
            // mnuAddAppInfo
            // 
            this.mnuAddAppInfo.Index = 2;
            this.mnuAddAppInfo.Text = "App Info";
            this.mnuAddAppInfo.Click += new System.EventHandler(this.mnuAddAppInfo_Click);
            // 
            // menuItem4
            // 
            this.menuItem4.Index = 6;
            this.menuItem4.Text = "-";
            // 
            // menuItem7
            // 
            this.menuItem7.Index = 7;
            this.menuItem7.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuFacetEnumeration,
            this.mnuFacetMaxExclusive,
            this.mnuFacetMaxInclusive,
            this.mnuFacetMinExclusive,
            this.mnuFacetMinInclusive,
            this.mnuFacetNumeric,
            this.mnuFacetPattern,
            this.mnuFacetWhiteSpace});
            this.menuItem7.Text = "Facet";
            // 
            // mnuFacetEnumeration
            // 
            this.mnuFacetEnumeration.Index = 0;
            this.mnuFacetEnumeration.Text = "Enumeration";
            this.mnuFacetEnumeration.Click += new System.EventHandler(this.mnuFacetEnumeration_Click);
            // 
            // mnuFacetMaxExclusive
            // 
            this.mnuFacetMaxExclusive.Index = 1;
            this.mnuFacetMaxExclusive.Text = "Max Exclusive";
            this.mnuFacetMaxExclusive.Click += new System.EventHandler(this.mnuFacetMaxExclusive_Click);
            // 
            // mnuFacetMaxInclusive
            // 
            this.mnuFacetMaxInclusive.Index = 2;
            this.mnuFacetMaxInclusive.Text = "Max Inclusive";
            this.mnuFacetMaxInclusive.Click += new System.EventHandler(this.mnuFacetMaxInclusive_Click);
            // 
            // mnuFacetMinExclusive
            // 
            this.mnuFacetMinExclusive.Index = 3;
            this.mnuFacetMinExclusive.Text = "Min Exclusive";
            this.mnuFacetMinExclusive.Click += new System.EventHandler(this.mnuFacetMinExclusive_Click);
            // 
            // mnuFacetMinInclusive
            // 
            this.mnuFacetMinInclusive.Index = 4;
            this.mnuFacetMinInclusive.Text = "Min Inclusive";
            this.mnuFacetMinInclusive.Click += new System.EventHandler(this.mnuFacetMinInclusive_Click);
            // 
            // mnuFacetNumeric
            // 
            this.mnuFacetNumeric.Index = 5;
            this.mnuFacetNumeric.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuFacetFractionDigits,
            this.mnuFacetLength,
            this.mnuFacetMaxLength,
            this.mnuFacetMinLength,
            this.mnuFacetTotalDigits});
            this.mnuFacetNumeric.Text = "Numeric";
            // 
            // mnuFacetFractionDigits
            // 
            this.mnuFacetFractionDigits.Index = 0;
            this.mnuFacetFractionDigits.Text = "Fraction Digits";
            this.mnuFacetFractionDigits.Click += new System.EventHandler(this.mnuFacetFractionDigits_Click);
            // 
            // mnuFacetLength
            // 
            this.mnuFacetLength.Index = 1;
            this.mnuFacetLength.Text = "Length";
            this.mnuFacetLength.Click += new System.EventHandler(this.mnuFacetLength_Click);
            // 
            // mnuFacetMaxLength
            // 
            this.mnuFacetMaxLength.Index = 2;
            this.mnuFacetMaxLength.Text = "Max Length";
            this.mnuFacetMaxLength.Click += new System.EventHandler(this.mnuFacetMaxLength_Click);
            // 
            // mnuFacetMinLength
            // 
            this.mnuFacetMinLength.Index = 3;
            this.mnuFacetMinLength.Text = "Min Length";
            this.mnuFacetMinLength.Click += new System.EventHandler(this.mnuFacetMinLength_Click);
            // 
            // mnuFacetTotalDigits
            // 
            this.mnuFacetTotalDigits.Index = 4;
            this.mnuFacetTotalDigits.Text = "Total Digits";
            this.mnuFacetTotalDigits.Click += new System.EventHandler(this.mnuFacetTotalDigits_Click);
            // 
            // mnuFacetPattern
            // 
            this.mnuFacetPattern.Index = 6;
            this.mnuFacetPattern.Text = "Pattern";
            this.mnuFacetPattern.Click += new System.EventHandler(this.mnuFacetPattern_Click);
            // 
            // mnuFacetWhiteSpace
            // 
            this.mnuFacetWhiteSpace.Index = 7;
            this.mnuFacetWhiteSpace.Text = "White Space";
            this.mnuFacetWhiteSpace.Click += new System.EventHandler(this.mnuFacetWhiteSpace_Click);
            // 
            // menuItem6
            // 
            this.menuItem6.Index = 8;
            this.menuItem6.Text = "-";
            // 
            // mnuRemoveNode
            // 
            this.mnuRemoveNode.Index = 9;
            this.mnuRemoveNode.Text = "Remove";
            this.mnuRemoveNode.Click += new System.EventHandler(this.mnuRemoveNode_Click);
            // 
            // tvImageList
            // 
            this.tvImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("tvImageList.ImageStream")));
            this.tvImageList.TransparentColor = System.Drawing.Color.Transparent;
            this.tvImageList.Images.SetKeyName(0, "");
            this.tvImageList.Images.SetKeyName(1, "");
            this.tvImageList.Images.SetKeyName(2, "");
            this.tvImageList.Images.SetKeyName(3, "");
            this.tvImageList.Images.SetKeyName(4, "");
            this.tvImageList.Images.SetKeyName(5, "");
            this.tvImageList.Images.SetKeyName(6, "");
            this.tvImageList.Images.SetKeyName(7, "");
            this.tvImageList.Images.SetKeyName(8, "");
            // 
            // edSchema
            // 
            this.edSchema.AcceptsReturn = true;
            this.edSchema.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.edSchema.HideSelection = false;
            this.edSchema.Location = new System.Drawing.Point(296, 8);
            this.edSchema.Multiline = true;
            this.edSchema.Name = "edSchema";
            this.edSchema.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.edSchema.Size = new System.Drawing.Size(640, 432);
            this.edSchema.TabIndex = 1;
            this.edSchema.WordWrap = false;
            // 
            // mainMenu
            // 
            this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuFile,
            this.menuItem1,
            this.mnuAbout});
            // 
            // mnuFile
            // 
            this.mnuFile.Index = 0;
            this.mnuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuNew,
            this.mnuOpen,
            this.menuItem3,
            this.mnuSave,
            this.mnuSaveAs,
            this.menuItem2,
            this.mnuExit});
            this.mnuFile.Text = "&File";
            // 
            // mnuNew
            // 
            this.mnuNew.Index = 0;
            this.mnuNew.Text = "&New";
            this.mnuNew.Click += new System.EventHandler(this.mnuNew_Click);
            // 
            // mnuOpen
            // 
            this.mnuOpen.Index = 1;
            this.mnuOpen.Text = "&Open";
            this.mnuOpen.Click += new System.EventHandler(this.mnuOpen_Click);
            // 
            // menuItem3
            // 
            this.menuItem3.Index = 2;
            this.menuItem3.Text = "-";
            // 
            // mnuSave
            // 
            this.mnuSave.Index = 3;
            this.mnuSave.Text = "&Save";
            this.mnuSave.Click += new System.EventHandler(this.mnuSave_Click);
            // 
            // mnuSaveAs
            // 
            this.mnuSaveAs.Index = 4;
            this.mnuSaveAs.Text = "Save &As";
            this.mnuSaveAs.Click += new System.EventHandler(this.mnuSaveAs_Click);
            // 
            // menuItem2
            // 
            this.menuItem2.Index = 5;
            this.menuItem2.Text = "-";
            // 
            // mnuExit
            // 
            this.mnuExit.Index = 6;
            this.mnuExit.Text = "E&xit";
            this.mnuExit.Click += new System.EventHandler(this.mnuExit_Click);
            // 
            // menuItem1
            // 
            this.menuItem1.Index = 1;
            this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.mnuCompile,
            this.menuItem8,
            this.menuItem10});
            this.menuItem1.Text = "&Schema";
            // 
            // mnuCompile
            // 
            this.mnuCompile.Index = 0;
            this.mnuCompile.Text = "&Compile";
            this.mnuCompile.Click += new System.EventHandler(this.mnuCompile_Click);
            // 
            // menuItem8
            // 
            this.menuItem8.Index = 1;
            this.menuItem8.Text = "Generate Code";
            this.menuItem8.Click += new System.EventHandler(this.menuItem8_Click);
            // 
            // menuItem10
            // 
            this.menuItem10.Index = 2;
            this.menuItem10.Text = "Config Class Namespace...";
            this.menuItem10.Click += new System.EventHandler(this.menuItem10_Click);
            // 
            // mnuAbout
            // 
            this.mnuAbout.Index = 2;
            this.mnuAbout.Text = "&About";
            this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click);
            // 
            // edSchemaErrors
            // 
            this.edSchemaErrors.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.edSchemaErrors.HideSelection = false;
            this.edSchemaErrors.Location = new System.Drawing.Point(296, 448);
            this.edSchemaErrors.Multiline = true;
            this.edSchemaErrors.Name = "edSchemaErrors";
            this.edSchemaErrors.ReadOnly = true;
            this.edSchemaErrors.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.edSchemaErrors.Size = new System.Drawing.Size(640, 88);
            this.edSchemaErrors.TabIndex = 2;
            // 
            // gbSelectType
            // 
            this.gbSelectType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.gbSelectType.Controls.Add(this.cbGlobalTypes);
            this.gbSelectType.Controls.Add(this.cbSimpleTypes);
            this.gbSelectType.Controls.Add(this.label2);
            this.gbSelectType.Controls.Add(this.label1);
            this.gbSelectType.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.gbSelectType.Location = new System.Drawing.Point(8, 440);
            this.gbSelectType.Name = "gbSelectType";
            this.gbSelectType.Size = new System.Drawing.Size(280, 96);
            this.gbSelectType.TabIndex = 3;
            this.gbSelectType.TabStop = false;
            this.gbSelectType.Text = "Select Type";
            // 
            // cbGlobalTypes
            // 
            this.cbGlobalTypes.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.cbGlobalTypes.Location = new System.Drawing.Point(88, 56);
            this.cbGlobalTypes.Name = "cbGlobalTypes";
            this.cbGlobalTypes.Size = new System.Drawing.Size(168, 21);
            this.cbGlobalTypes.Sorted = true;
            this.cbGlobalTypes.TabIndex = 3;
            this.cbGlobalTypes.SelectedIndexChanged += new System.EventHandler(this.cbGlobalTypes_SelectedIndexChanged);
            // 
            // cbSimpleTypes
            // 
            this.cbSimpleTypes.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.cbSimpleTypes.Items.AddRange(new object[] {
            "anyURI",
            "base64Binary",
            "boolean",
            "byte",
            "date",
            "dateTime",
            "decimal",
            "double",
            "duration",
            "ENTITIY",
            "float",
            "gDay",
            "gMonth",
            "gMonthDay",
            "gYear",
            "gYearMonth",
            "hexBinary",
            "ID",
            "IDREF",
            "imteger",
            "int",
            "language",
            "long",
            "Name",
            "NCName",
            "negativeInteger",
            "NMTOKEN",
            "nonNegativeInteger",
            "nonPositiveInteger",
            "normalizedString",
            "NOTATION",
            "positiveInteger",
            "QName",
            "short",
            "string",
            "time",
            "token",
            "unsignedByte",
            "unsignedInt",
            "unsignedLong",
            "unsignedShort"});
            this.cbSimpleTypes.Location = new System.Drawing.Point(88, 24);
            this.cbSimpleTypes.Name = "cbSimpleTypes";
            this.cbSimpleTypes.Size = new System.Drawing.Size(168, 21);
            this.cbSimpleTypes.Sorted = true;
            this.cbSimpleTypes.TabIndex = 2;
            this.cbSimpleTypes.SelectedIndexChanged += new System.EventHandler(this.cbSimpleTypes_SelectedIndexChanged);
            // 
            // label2
            // 
            this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label2.Location = new System.Drawing.Point(8, 58);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(80, 16);
            this.label2.TabIndex = 1;
            this.label2.Text = "Global Types:";
            // 
            // label1
            // 
            this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label1.Location = new System.Drawing.Point(8, 26);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(80, 16);
            this.label1.TabIndex = 0;
            this.label1.Text = "Simple Types:";
            // 
            // saveAsSchemaDialog
            // 
            this.saveAsSchemaDialog.DefaultExt = "xsd";
            // 
            // SchemaEditor
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(944, 553);
            this.Controls.Add(this.gbSelectType);
            this.Controls.Add(this.edSchemaErrors);
            this.Controls.Add(this.edSchema);
            this.Controls.Add(this.tvSchema);
            this.Menu = this.mainMenu;
            this.Name = "SchemaEditor";
            this.Text = "XML Schema Editor and Configuration Class Generator";
            this.Load += new System.EventHandler(this.SchemaEditor_Load);
            this.gbSelectType.ResumeLayout(false);
            this.ResumeLayout(false);
            this.PerformLayout();

        }
        #endregion


        #region Menu Commands

        #region Add Facets
        // There are several types of facets that can be added to a simple type.
        // This code adds a facet and specifies a default value (completely arbitrary)

        private void mnuFacetEnumeration_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaEnumerationFacet(), "1", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }

        private void mnuFacetMaxExclusive_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaMaxExclusiveFacet(), "101", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }

        private void mnuFacetMaxInclusive_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaMaxInclusiveFacet(), "100", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }

        private void mnuFacetMinExclusive_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaMinExclusiveFacet(), "0", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }

        private void mnuFacetMinInclusive_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaMinInclusiveFacet(), "1", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }

        private void mnuFacetFractionDigits_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaFractionDigitsFacet(), "2", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }

        private void mnuFacetLength_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaLengthFacet(), "16", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }

        private void mnuFacetMaxLength_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaMaxLengthFacet(), "16", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }

        private void mnuFacetMinLength_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaMinLengthFacet(), "1", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }

        private void mnuFacetTotalDigits_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaTotalDigitsFacet(), "8", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }


        private void mnuFacetPattern_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaPatternFacet(), "[0-9]", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }

        private void mnuFacetWhiteSpace_Click(object sender, System.EventArgs e)
        {
            bool ret = AddFacet(new XmlSchemaWhiteSpaceFacet(), "collapse", TreeViewImages.Facet);
            if (!ret)
            {
                MessageBox.Show("Cannot add an element to this item.");
            }
        }
        #endregion

        #region Add Annotation, Documentation, and AppInfo
        // create an annotation for the schema or for an annotatable object
        private void mnuAddAnnotation_Click(object sender, System.EventArgs e)
        {
            XmlSchemaAnnotation annot = new XmlSchemaAnnotation();
            TreeNode newNode = CreateNode("--annotation--");

            // if adding at the schema root level...
            if (newNode.Parent == tvSchema.Nodes[0])
            {
                AddToCollection(schema.Items, annot, newNode, TreeViewImages.Annotation);
            }
            else
            {
                // otherwise, get the object as an XmlSchemaAnnotated type
                XmlSchemaAnnotated obj = newNode.Parent.Tag as XmlSchemaAnnotated;
                if (obj != null)
                {
                    // if it exists, add the annotation
                    obj.Annotation = annot;
                    newNode.Tag = annot;
                    newNode.ImageIndex = (int)TreeViewImages.Annotation;
                    newNode.SelectedImageIndex = (int)TreeViewImages.Annotation;
                    CompileSchema();
                }
                else
                {
                    // otherwise, tell the user annotation cannot be added to this type.
                    newNode.Parent.Nodes.Remove(newNode);
                    MessageBox.Show("Cannot create an annotation for this item.");
                }
            }
        }

        private void mnuAddDocumentation_Click(object sender, System.EventArgs e)
        {
            bool success = false;
            XmlSchemaAnnotation annot = tvSchema.SelectedNode.Tag as XmlSchemaAnnotation;
            // if the parent node is an annotation type...
            if (annot != null)
            {
                // ...then add the documentation type
                TreeNode newNode = CreateNode("--documentation--");
                XmlSchemaDocumentation doc = new XmlSchemaDocumentation();
                doc.Markup = TextToNodeArray("Documentation");
                annot.Items.Add(doc);
                newNode.Tag = doc;
                newNode.ImageIndex = (int)TreeViewImages.Annotation;
                newNode.SelectedImageIndex = (int)TreeViewImages.Annotation;
                CompileSchema();
                success = true;
            }
            if (!success)
            {
                // otherwise create the annotation type first
                mnuAddAnnotation_Click(sender, e);
                annot = tvSchema.SelectedNode.Tag as XmlSchemaAnnotation;
                // if successful in adding the annotation type, add the documentation type now
                if (annot != null)
                {
                    mnuAddDocumentation_Click(sender, e);
                }
            }
        }

        private void mnuAddAppInfo_Click(object sender, System.EventArgs e)
        {
            bool success = false;
            XmlSchemaAnnotation annot = tvSchema.SelectedNode.Tag as XmlSchemaAnnotation;
            // if the parent node is an annotation type...
            if (annot != null)
            {
                // ...then add the AppInfo type
                TreeNode newNode = CreateNode("--app info--");
                XmlSchemaAppInfo doc = new XmlSchemaAppInfo();
                doc.Markup = TextToNodeArray("Application Information");
                annot.Items.Add(doc);
                newNode.Tag = doc;
                newNode.ImageIndex = (int)TreeViewImages.Annotation;
                newNode.SelectedImageIndex = (int)TreeViewImages.Annotation;
                CompileSchema();
                success = true;
            }
            if (!success)
            {
                // otherwise create the annotation type first
                mnuAddAnnotation_Click(sender, e);
                annot = tvSchema.SelectedNode.Tag as XmlSchemaAnnotation;
                // if successful in creating the annotation type, add the AppInfo type now
                if (annot != null)
                {
                    mnuAddAppInfo_Click(sender, e);
                }
            }
        }

        #endregion

        #region Add Attribute
        // Can only be added to schema root as a global or complex type.
        // For complex types, the attribute can reference a global type.
        // An optional type can be specified referring to a simple type.
        // If the type isn't used, the attribute must define a simple type.
        private void mnuAddAttribute_Click(object sender, System.EventArgs e)
        {
            TreeNode newNode = CreateNode("Attribute");
            XmlSchemaAttribute attrib = new XmlSchemaAttribute();
            attrib.Name = "Attribute";
            attrib.SchemaTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");

            // root node?
            if (newNode.Parent == tvSchema.Nodes[0])
            {
                // add to root of schema.  An global attribute cannot reference a global type
                AddToCollection(schema.Items, attrib, newNode, TreeViewImages.Attribute);
                cbGlobalTypes.Items.Add(new GlobalElementType(attrib.Name, attrib));
                cbGlobalTypes.Enabled = false;
                cbSimpleTypes.SelectedItem = -1;
                cbSimpleTypes.Enabled = true;
                cbSimpleTypes.SelectedItem = "string";
            }
            else
            {
                // an attribute can only be added to a complex type
                XmlSchemaComplexType ct = newNode.Parent.Tag as XmlSchemaComplexType;
                if (ct != null)
                {
                    // and can reference a global attribute, so enable the global combobox
                    AddToCollection(ct.Attributes, attrib, newNode, TreeViewImages.Attribute);
                    cbGlobalTypes.SelectedItem = -1;
                    cbGlobalTypes.Enabled = true;
                    cbSimpleTypes.SelectedItem = "string";
                    cbSimpleTypes.Enabled = true;
                }
                else
                {
                    newNode.Parent.Nodes.Remove(newNode);
                    MessageBox.Show("Cannot create an attribute for this item.");
                }
            }
        }
        #endregion

        #region Add Element
        // An element can be added to the schema or to a complex type.
        // If adding to an element, convert the element to a complex type.
        // An element can be added to a global complex type or to a local complex type.
        private void mnuAddElement_Click(object sender, System.EventArgs e)
        {
            TreeNode newNode = CreateNode("Element");
            XmlSchemaElement element = new XmlSchemaElement();
            element.Name = "Element";
            element.SchemaTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");

            // root node?
            if (newNode.Parent == tvSchema.Nodes[0])
            {
                // add to root of schema.  A global element can reference another global type
                AddToCollection(schema.Items, element, newNode, TreeViewImages.Element);
                cbGlobalTypes.Items.Add(new GlobalElementType(element.Name, element));
                cbGlobalTypes.Enabled = true;
                cbSimpleTypes.SelectedItem = -1;
                cbSimpleTypes.Enabled = true;
                cbSimpleTypes.SelectedItem = "string";
            }
            else
            {
                // otherwise, an element must be part of a complex type
                bool ret = AddToComplexType(newNode.Parent.Tag, element, newNode, TreeViewImages.Element);
                if (!ret)
                {
                    // not successful
                    newNode.Parent.Nodes.Remove(newNode);
                    MessageBox.Show("Cannot add an element to this item.");
                }
                else
                {
                    // successful
                    cbGlobalTypes.SelectedItem = -1;
                    cbGlobalTypes.Enabled = true;
                    cbSimpleTypes.SelectedItem = "string";
                    cbSimpleTypes.Enabled = true;
                }
            }
        }
        #endregion

        #region Add Simple Type
        // A simple type can be added as a global type or as a local member of a complex type.
        // A simple type cannot contain elements or attributes.
        // Simple types are derived from basic types or other simple types.
        // The complex type can either be a global definition or a local complex type.
        // When adding to a complex type, the simple type must be wrapped in an element.
        private void mnuAddSimpleType_Click(object sender, System.EventArgs e)
        {
            TreeNode newNode = CreateNode("SimpleType");

            XmlSchemaSimpleType simpleType = new XmlSchemaSimpleType();
            simpleType.Name = "SimpleType";
            XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction();
            restriction.BaseTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema");
            simpleType.Content = restriction;

            // root node?
            if (newNode.Parent == tvSchema.Nodes[0])
            {
                // add to root of schema.  A global simple type cannot reference another global
                AddToCollection(schema.Items, simpleType, newNode, TreeViewImages.SimpleType);
                cbGlobalTypes.Items.Add(new GlobalElementType(simpleType.Name, simpleType));
                cbGlobalTypes.Enabled = false;
                cbSimpleTypes.SelectedItem = -1;
                cbSimpleTypes.Enabled = true;
                cbSimpleTypes.SelectedItem = "string";
            }
            else
            {
                // if not a root node, then it must be created as an element of simple type...
                XmlSchemaElement el = new XmlSchemaElement();
                el.Name = "SimpleType";
                el.SchemaType = simpleType;
                simpleType.Name = null;
                // ...as a subnode to a complex type
                bool ret = AddToComplexType(newNode.Parent.Tag, el, newNode, TreeViewImages.SimpleType);
                if (!ret)
                {
                    // failure
                    newNode.Parent.Nodes.Remove(newNode);
                    MessageBox.Show("Cannot add a simple type to this item.");
                }
                else
                {
                    // success.  Can reference a global simple type
                    cbGlobalTypes.SelectedItem = -1;
                    cbGlobalTypes.Enabled = true;
                    cbSimpleTypes.SelectedItem = "string";
                    cbSimpleTypes.Enabled = true;
                }
            }
        }
        #endregion

        #region Add Complex Type
        // A complex type can be added as a global type to the schema or as a complex element.
        // If adding to an element, change the element to a complex type.
        // When adding to a complex type, the complex type must be wrapped in an element.
        private void mnuAddComplexType_Click(object sender, System.EventArgs e)
        {
            TreeNode newNode = CreateNode("ComplexType");

            XmlSchemaComplexType complexType = new XmlSchemaComplexType();
            XmlSchemaSequence sequence = new XmlSchemaSequence();
            complexType.Particle = sequence;
            complexType.Name = "ComplexType";

            // root node?
            if (newNode.Parent == tvSchema.Nodes[0])
            {
                // add to root.  A complex type has no type reference information.
                AddToCollection(schema.Items, complexType, newNode, TreeViewImages.ComplexType);
                cbGlobalTypes.Items.Add(new GlobalElementType(complexType.Name, complexType));
                cbSimpleTypes.SelectedItem = -1;
                cbGlobalTypes.SelectedItem = -1;
                cbSimpleTypes.Enabled = false;
                cbGlobalTypes.Enabled = false;
            }
            else
            {
                // if not at root, create an element of complex type...
                XmlSchemaElement el = new XmlSchemaElement();
                el.Name = "ComplexType";
                el.SchemaType = complexType;
                complexType.Name = null;
                // ...that is added as a subnode to a complex type.
                bool ret = AddToComplexType(newNode.Parent.Tag, el, newNode, TreeViewImages.ComplexType);
                if (!ret)
                {
                    // failure
                    newNode.Parent.Nodes.Remove(newNode);
                    MessageBox.Show("Cannot add a complex type to this item.");
                }
                else
                {
                    // success.  No type is referenced.
                    cbSimpleTypes.SelectedItem = -1;
                    cbGlobalTypes.SelectedItem = -1;
                    cbSimpleTypes.Enabled = false;
                    cbGlobalTypes.Enabled = false;
                }
            }
        }
        #endregion

        #region New
        private void mnuNew_Click(object sender, System.EventArgs e)
        {
            CreateRootNode();		// create a new treeview root node
            schema = new XmlSchema();	// create a new schema
            CompileSchema();		// compile and show it
            fileName = null;			// no filename
        }
        #endregion

        #region Open
        // open an existing XSD file
        private void mnuOpen_Click(object sender, System.EventArgs e)
        {
            openSchemaDialog.DefaultExt = "xsd";
            openSchemaDialog.CheckFileExists = true;
            openSchemaDialog.Filter = "XSD Files (*.xsd)|*.xsd|All Files (*.*)|*.*";
            DialogResult res = openSchemaDialog.ShowDialog();
            if (res == DialogResult.OK)
            {
                try
                {
                    StreamReader tr = new StreamReader(openSchemaDialog.FileName);
                    schema = XmlSchema.Read(tr, new ValidationEventHandler(SchemaValidationHandler));
                    tr.Close();
                    CompileSchema();
                    CreateRootNode();
                    DecodeSchema(schema, tvSchema.Nodes[0]);
                    tvSchema.ExpandAll();
                    fileName = openSchemaDialog.FileName;
                }
                catch (Exception err)
                {
                    edSchemaErrors.Text = err.ToString();
                }
            }
        }
        #endregion

        #region Save, Save As, Exit, About
        // save the current XSD
        private void mnuSave_Click(object sender, System.EventArgs e)
        {
            if (fileName == null)
            {
                mnuSaveAs_Click(sender, e);
            }
            else
            {
                CompileSchema();
                StreamWriter sw = new StreamWriter(fileName, false, System.Text.Encoding.UTF8);
                sw.Write(edSchema.Text);
                sw.Flush();
                sw.Close();
            }
        }

        // save the current XSD as...
        private void mnuSaveAs_Click(object sender, System.EventArgs e)
        {
            DialogResult res = saveAsSchemaDialog.ShowDialog();
            if (res == DialogResult.OK)
            {
                fileName = saveAsSchemaDialog.FileName;
                CompileSchema();
                StreamWriter sw = new StreamWriter(fileName, false, System.Text.Encoding.UTF8);
                sw.Write(edSchema.Text);
                sw.Flush();
                sw.Close();

            }
        }

        private void mnuExit_Click(object sender, System.EventArgs e)
        {
            Close();		// signal form to close
        }

        // info
        private void mnuAbout_Click(object sender, System.EventArgs e)
        {
            MessageBox.Show("XML Schema Editor\r\n\r\nversion 1.0\r\n\r\n(c)2003 Marc Clifton\r\n\r\nThis program may be freely distributed.");
        }
        #endregion

        #region Compile
        private void mnuCompile_Click(object sender, System.EventArgs e)
        {
            // 1. read the XSD from the edit box into a schema
            // 2. compile it
            // 3. create a new tree view
            // 4. decode the schema into the tree view
            // 5. show the tree
            try
            {
                StringReader sr = new StringReader(edSchema.Text);
                schema = XmlSchema.Read(sr, new ValidationEventHandler(SchemaValidationHandler));
                CompileSchema();
                CreateRootNode();
                DecodeSchema(schema, tvSchema.Nodes[0]);
                tvSchema.ExpandAll();
            }
            catch (Exception err)
            {
                edSchemaErrors.Text = err.ToString();
            }
        }
        #endregion

        #region Remove Node
        // The parent type determines from what list the selected item must be removed.
        // Use the image index in the tree view to figure out the parent type.
        private void mnuRemoveNode_Click(object sender, System.EventArgs e)
        {
            TreeNode tnParent = tvSchema.SelectedNode.Parent;
            XmlSchemaObject obj = tvSchema.SelectedNode.Tag as XmlSchemaObject;
            bool success = false;
            // if the node to remove has a parent and is of an XmlSchemaObject type...
            if ((tnParent != null) && (obj != null))
            {
                // look at the tree node image index to figure out what the parent is!
                switch ((TreeViewImages)tnParent.ImageIndex)
                {
                    // if the parent is the schema root:
                    case TreeViewImages.Schema:
                        {
                            // remove the object from the schema and from the global list
                            schema.Items.Remove(obj);
                            int idx = cbGlobalTypes.FindStringExact(tvSchema.SelectedNode.Text);
                            if (idx != -1)
                            {
                                cbGlobalTypes.Items.RemoveAt(idx);
                            }
                            success = true;
                            break;
                        }

                    // if the parent is an annotation type
                    case TreeViewImages.Annotation:
                        {
                            XmlSchemaAnnotation annot = tnParent.Tag as XmlSchemaAnnotation;
                            if (annot != null)
                            {
                                annot.Items.Remove(obj);
                                success = true;
                            }
                            break;
                        }

                    // if the parent is a simple type
                    case TreeViewImages.SimpleType:
                        {
                            // a simple type can have an annotation or a facet type as children
                            XmlSchemaSimpleType st = tnParent.Tag as XmlSchemaSimpleType;
                            if (obj is XmlSchemaAnnotation)
                            {
                                // remove from annotation list if it's an annotation type
                                st.Annotation.Items.Remove(obj);
                                success = true;
                            }
                            else if (obj is XmlSchemaFacet)
                            {
                                XmlSchemaSimpleTypeRestriction rest = st.Content as XmlSchemaSimpleTypeRestriction;
                                if (rest != null)
                                {
                                    // remove from facet list if it's a facet type
                                    rest.Facets.Remove(obj);
                                    success = true;
                                }
                            }
                            break;
                        }

                    // if the parent is a complex type...
                    case TreeViewImages.ComplexType:
                        {
                            XmlSchemaComplexType ct = tnParent.Tag as XmlSchemaComplexType;
                            if (ct != null)
                            {
                                // then we are removing an attribute
                                if (obj is XmlSchemaAttribute)
                                {
                                    ct.Attributes.Remove(obj);
                                    success = true;
                                }
                                // or an annotation
                                else if (obj is XmlSchemaAnnotation)
                                {
                                    ct.Annotation.Items.Remove(obj);
                                    success = true;
                                }
                                // or an element type
                                else
                                {
                                    XmlSchemaSequence seq = ct.Particle as XmlSchemaSequence;
                                    if (seq != null)
                                    {
                                        seq.Items.Remove(obj);
                                        success = true;
                                    }
                                }
                            }
                            break;
                        }
                }
            }
            // if successful, remove the node from the tree view
            if (success)
            {
                tnParent.Nodes.Remove(tvSchema.SelectedNode);
                CompileSchema();
            }
            else
            {
                MessageBox.Show("Unable to remove this node");
            }
        }
        #endregion

        #endregion

        #region Schema Validation Handler
        // report any errors to the schema error edit box
        private void SchemaValidationHandler(object sender, ValidationEventArgs args)
        {
            Console.WriteLine(args.Message);
            edSchemaErrors.Text += args.Message + "\r\n";
        }
        #endregion

        #region Events

        #region TreeView PreEventLabelChanged and EventLabelChanged
        // exclude certain tree nodes from being editable
        private void PreEventLabelChanged(object sender, NodeLabelEditEventArgs e)
        {
            prevLabel = tvSchema.SelectedNode.Text;
            if ((e.Node.Tag is XmlSchemaFacet) ||
                (e.Node.Tag is XmlSchemaAnnotation) ||
                (e.Node.Tag is XmlSchemaDocumentation) ||
                (e.Node.Tag is XmlSchemaAppInfo))
            {
                e.Node.EndEdit(false);
            }
        }

        private void EventLabelChanged(object sender, NodeLabelEditEventArgs e)
        {
            // if a node is selected...
            if (e.Node != null)
            {
                // and a label has been changed... (e.Label==null if ESC key pressed)
                if (e.Label != null)
                {
                    // then change the name of the type in the schema
                    UpdateTypeAndName(null, e.Label, null);

                    // if this is a root node...
                    if (e.Node.Parent == tvSchema.Nodes[0])
                    {
                        // ...then also change the name in the global list
                        // (this is not case sensitive!)
                        int idx = cbGlobalTypes.FindStringExact(prevLabel);
                        if (idx != -1)
                        {
                            cbGlobalTypes.Items[idx] = new GlobalElementType(e.Label, ((GlobalElementType)cbGlobalTypes.Items[idx]).type);
                        }
                    }
                }
            }
        }
        #endregion

        #region EventTreeViewKeyPress
        // shortcuts:
        // F2 - edit tree node label
        // Ctrl+A - bring up popup menu to Add a subnode
        // Ctrl+T - go to Top of tree
        // Ctrl+P - go to Parent of currently selected node
        private void EventTreeViewKeyUp(object sender, KeyEventArgs e)
        {
            e.Handled = false;
            // F2
            if (e.KeyCode == Keys.F2)
            {
                if (tvSchema.SelectedNode != tvSchema.Nodes[0])
                {
                    tvSchema.SelectedNode.BeginEdit();
                    e.Handled = true;
                }
            }
            // Ctrl+A
            else if ((e.KeyCode == Keys.A) && (e.Modifiers == Keys.Control))
            {
                e.Handled = true;
                tvcmSchema.Show(this, tvSchema.Location + new Size(50, 50));
            }
            // Ctrl+T
            else if ((e.KeyCode == Keys.T) && (e.Modifiers == Keys.Control))
            {
                e.Handled = true;
                tvSchema.SelectedNode = tvSchema.Nodes[0];
            }
            // Ctrl+P
            else if ((e.KeyCode == Keys.P) && (e.Modifiers == Keys.Control))
            {
                e.Handled = true;
                TreeNode node = tvSchema.SelectedNode.Parent;
                if (node != null)
                {
                    tvSchema.SelectedNode = node;
                }
            }
        }
        #endregion

        #region Schema Text Box Lost Focus
        private void EventSchemaTextBoxLostFocus(object sender, EventArgs e)
        {
            mnuCompile_Click(sender, e);
        }
        #endregion

        #region TreeView MouseDown
        // On a mouse down, we want to select the node on which the mouse clicked.
        // This way we know what node the user right-clicked on when adding sub-nodes
        private void EventMouseDown(object sender, MouseEventArgs e)
        {
            TreeNode tn = tvSchema.GetNodeAt(e.X, e.Y);
            if (tn != null)
            {
                tvSchema.SelectedNode = tn;
            }
        }
        #endregion

        #region TreeView AfterSelect
        // After selecting a node, we want to:
        // 1. highlight the line in the schema that corresponds to the tree node
        // 2. update the simple and global type combo boxes to show what the type is for the selected node.
        private void tvSchema_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
        {
            XmlSchemaObject obj = e.Node.Tag as XmlSchemaObject;
            // if this is a schema object...
            if (obj != null)
            {
                // find the corresponding line in the XSD source and highlight it
                if ((obj.LineNumber != 0) && (obj.LineNumber < edSchema.Lines.Length))
                {
                    int length = 0;
                    for (int i = 0; i < obj.LineNumber - 1; i++)
                    {
                        // get the length of the line including CRLF
                        length += edSchema.Lines[i].Length + 2;
                    }
                    // highlight the line
                    edSchema.Select(length, edSchema.Lines[obj.LineNumber - 1].Length);
                }

                // Update simple and global type combo boxes.
                // Get the name of the element type so that we can find it in the simple or global type list
                XmlQualifiedName name = null;		// assume failure
                if (obj is XmlSchemaAttribute)
                {
                    // this is easy.
                    name = ((XmlSchemaAttribute)obj).SchemaTypeName;
                }
                else if (obj is XmlSchemaSimpleType)
                {
                    // if it's a simple type, get the restriction type, if it exists
                    XmlSchemaSimpleTypeRestriction restriction = ((XmlSchemaSimpleType)obj).Content as XmlSchemaSimpleTypeRestriction;
                    if (restriction != null)
                    {
                        name = restriction.BaseTypeName;
                    }
                }
                else if (obj is XmlSchemaElement)
                {
                    // if it's an element, determine if it's a simple type subnode of a complex type...
                    // and then get the restriction type, if it exists
                    XmlSchemaElement el = obj as XmlSchemaElement;
                    if (el.SchemaType is XmlSchemaSimpleType)
                    {
                        XmlSchemaSimpleType st = el.SchemaType as XmlSchemaSimpleType;
                        XmlSchemaSimpleTypeRestriction rest = st.Content as XmlSchemaSimpleTypeRestriction;
                        if (rest != null)
                        {
                            name = rest.BaseTypeName;
                        }
                    }
                    else
                    {
                        // otherwise get the element name
                        name = el.SchemaTypeName;

                        // if the name is null, then there must be a reference instead
                        if (name.Name == "")
                        {
                            name = el.RefName;
                        }
                    }
                }

                // select the name from either the simple type list or the global element type list
                if (name != null)
                {
                    // see if the name exists in the simple type list
                    int idx = cbSimpleTypes.FindStringExact(name.Name);
                    cbSimpleTypes.SelectedIndex = idx;
                    cbSimpleTypes.Enabled = true;

                    // see if the name exists in the complex type list
                    idx = cbGlobalTypes.FindStringExact(name.Name);
                    cbGlobalTypes.SelectedIndex = idx;
                    cbGlobalTypes.Enabled = true;
                }
                else
                {
                    // if there is no name, then disable the comboboxes
                    cbSimpleTypes.SelectedIndex = -1;
                    cbGlobalTypes.SelectedIndex = -1;
                    cbSimpleTypes.Enabled = false;
                    cbGlobalTypes.Enabled = false;
                }
            }
            else
            {
                // if this isn't a schema object, then disable the comboboxes
                cbSimpleTypes.SelectedIndex = -1;
                cbGlobalTypes.SelectedIndex = -1;
                cbSimpleTypes.Enabled = false;
                cbGlobalTypes.Enabled = false;
            }
        }
        #endregion

        #region cbSimpleTypes Index Changed
        // the user has selected a simple type.  Select it and clear the global type combo box.
        private void cbSimpleTypes_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (cbSimpleTypes.SelectedIndex != -1)
            {
                UpdateTypeAndName(cbSimpleTypes.SelectedItem.ToString(), null, "http://www.w3.org/2001/XMLSchema");
                cbGlobalTypes.SelectedIndex = -1;
            }
        }
        #endregion

        #region cbGlobalTypes Index Changed
        // the user has selected a global type.  Select it and clear the simple type combo box.
        private void cbGlobalTypes_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (cbGlobalTypes.SelectedIndex != -1)
            {
                UpdateTypeAndName(cbGlobalTypes.SelectedItem.ToString(), null, null);
                cbSimpleTypes.SelectedIndex = -1;
            }
        }
        #endregion


        #endregion

        #region Misc. Helpers

        #region CreateRootNode
        // This helper function destroys the existing tree and creates a new tree.
        // It also clears the global type list, since there are no global types defined
        //	with a blank tree.
        private void CreateRootNode()
        {
            tvSchema.Nodes.Clear();
            TreeNode rootNode = new TreeNode("Schema:");
            tvSchema.Nodes.Add(rootNode);
            rootNode.ImageIndex = (int)TreeViewImages.Schema;
            rootNode.SelectedImageIndex = (int)TreeViewImages.Schema;
            cbGlobalTypes.Items.Clear();
        }
        #endregion

        #region CompileSchema
        // Compile the schema as it exists in the XmlSchema structure, displaying any
        // errors in the schema error edit box and displaying the schema itself in
        // the schema edit box.
        private void CompileSchema()
        {
            edSchemaErrors.Text = "";
            schema.Compile(new ValidationEventHandler(SchemaValidationHandler));
            StringWriter sw = new StringWriter();
            schema.Write(sw);
            edSchema.Text = sw.ToString();
        }
        #endregion

        #region CreateNode
        // This helper function creates a subnode off of the selected node and requests
        // that the node label be immediately editable.
        private TreeNode CreateNode(string name)
        {
            TreeNode tn = tvSchema.SelectedNode;
            TreeNode newNode = new TreeNode(name);
            tn.Nodes.Add(newNode);
            tn.Expand();
            tvSchema.SelectedNode = newNode;
            newNode.BeginEdit();
            return newNode;
        }
        #endregion

        #region AddToCollection
        // Add a schema type to the specified schema object collection.
        // The tree node references the schema type being added.
        // The image indices are set.
        // The schema is recompiled, which shows any errors and updates the schema display.
        void AddToCollection(XmlSchemaObjectCollection coll, XmlSchemaObject obj, TreeNode node, TreeViewImages imgIdx)
        {
            coll.Add(obj);
            node.Tag = obj;
            node.ImageIndex = (int)imgIdx;
            node.SelectedImageIndex = (int)imgIdx;
            CompileSchema();
        }
        #endregion

        #region ChangeElementToComplexType
        // When adding a subnode to an element or a simple type, the node must be changed to a complex type.
        private XmlSchemaComplexType ChangeElementToComplexType(XmlSchemaElement el, TreeNode tn)
        {
            // if the element is currently a reference, we need to remove the reference
            // and set the name to something, which in this case is the old ref name.
            if (el.RefName != null)
            {
                el.Name = el.RefName.Name;
                el.RefName = null;
            }
            // creat the complex type.
            XmlSchemaComplexType ct = new XmlSchemaComplexType();
            el.SchemaType = ct;
            // a complex type cannot have a type name
            el.SchemaTypeName = null;
            // create the sequence
            XmlSchemaSequence sequence = new XmlSchemaSequence();
            ct.Particle = sequence;

            // update the image indices
            tn.ImageIndex = (int)TreeViewImages.ComplexType;
            tn.SelectedImageIndex = (int)TreeViewImages.ComplexType;

            return ct;
        }
        #endregion

        #region AddToComplexType
        // add a type to a complex type
        private bool AddToComplexType(object obj, XmlSchemaObject item, TreeNode newNode, TreeViewImages imgIdx)
        {
            bool success = true;
            XmlSchemaElement el = obj as XmlSchemaElement;
            XmlSchemaComplexType complexType = obj as XmlSchemaComplexType;

            // is it an element...
            if (el != null)
            {
                // of complex type (so we know it's a local complex type, not a global one!)
                XmlSchemaComplexType ct = el.SchemaType as XmlSchemaComplexType;
                if (ct != null)
                {
                    // does it have a sequence?
                    XmlSchemaSequence seq = ct.Particle as XmlSchemaSequence;
                    if (seq != null)
                    {
                        // yes--add it to the sequence collection
                        AddToCollection(seq.Items, item, newNode, imgIdx);
                    }
                    else
                    {
                        // no--we can't add it.
                        MessageBox.Show("Complex type is missing sequence!");
                        success = false;
                    }
                }
                else
                {
                    // change the basic element to a complex type by adding a sequence and then
                    // add the sub-element
                    ct = ChangeElementToComplexType(el, newNode.Parent);
                    AddToCollection(((XmlSchemaSequence)ct.Particle).Items, item, newNode, imgIdx);
                }
            }
            // or is it a global complex type...
            else if (complexType != null)
            {
                XmlSchemaSequence seq = complexType.Particle as XmlSchemaSequence;
                // which should have a sequence!
                if (seq != null)
                {
                    // yes--add it to the collection
                    AddToCollection(seq.Items, item, newNode, imgIdx);
                }
                else
                {
                    // no--we can't add it.
                    MessageBox.Show("Complex type is missing sequence!");
                    success = false;
                }
            }
            else
            {
                // failure--current node is not an element and not a complex type
                success = false;
            }
            return success;
        }
        #endregion

        #region UpdateTypeAndName
        // This is a dual purpose function that updates either the type or the name.
        // It can also update both at once, but isn't used in that way in this program.
        // Pass in a null for typeName if only changing the name.
        // Pass in a null for name if only changing the typeName.
        // Pass in a null for the nameSpace if the typeName is a global type.
        private void UpdateTypeAndName(string typeName, string name, string nameSpace)
        {
            // Is the type referenced by the tree node an XmlSchemaObject?
            XmlSchemaObject obj = tvSchema.SelectedNode.Tag as XmlSchemaObject;
            if (obj != null)
            {
                // is it an attribute?
                if (obj is XmlSchemaAttribute)
                {
                    XmlSchemaAttribute attrib = obj as XmlSchemaAttribute;
                    // if we're changing the name:
                    if (name != null)
                    {
                        attrib.Name = name;
                        CompileSchema();
                    }
                    // if we're changing the type:
                    if (typeName != null)
                    {
                        // if the name refers to a global attribute, then use ref instead of type
                        int idx = cbGlobalTypes.FindStringExact(typeName);
                        GlobalElementType glet = null;
                        if (idx != -1)
                        {
                            glet = cbGlobalTypes.Items[idx] as GlobalElementType;
                        }
                        // if a global exists of this type...
                        if ((glet != null) && (glet.type is XmlSchemaAttribute))
                        {
                            // then get rid of the type name and use a ref instead
                            attrib.SchemaTypeName = null;
                            attrib.RefName = new XmlQualifiedName(typeName, nameSpace);
                            // can't have a name
                            attrib.Name = null;
                        }
                        else
                        {
                            // otherwise, use a type name and get rid of the ref
                            attrib.SchemaTypeName = new XmlQualifiedName(typeName, nameSpace);
                            attrib.RefName = null;
                            if (attrib.Name == null)
                            {
                                // if changing from ref to type, we need some sort of default name
                                attrib.Name = tvSchema.SelectedNode.Text;
                            }
                        }
                        CompileSchema();
                        // update the tree node name
                        tvSchema.SelectedNode.Text = attrib.QualifiedName.Name;
                    }
                }
                // is it an element?
                else if (obj is XmlSchemaElement)
                {
                    XmlSchemaElement el = obj as XmlSchemaElement;
                    // if we're changing the name:
                    if (name != null)
                    {
                        el.Name = name;
                        CompileSchema();
                    }

                    // if we're changing the type:
                    if (typeName != null)
                    {
                        if (el.SchemaType is XmlSchemaSimpleType)
                        {
                            XmlSchemaSimpleType st = el.SchemaType as XmlSchemaSimpleType;
                            XmlSchemaSimpleTypeRestriction rest = st.Content as XmlSchemaSimpleTypeRestriction;
                            if (rest != null)
                            {
                                rest.BaseTypeName = new XmlQualifiedName(typeName, nameSpace);
                                CompileSchema();
                            }
                        }
                        else
                        {
                            // if the name refers to a global element, then use ref instead of type
                            // Same deal as for changing the element type name.
                            // Since the SchemaTypeName and RefName are not part of any base class shared
                            // between the SchemaXmlAttribute and SchemaXmlElement, we need separate code.
                            int idx = cbGlobalTypes.FindStringExact(typeName);
                            GlobalElementType glet = null;
                            if (idx != -1)
                            {
                                glet = cbGlobalTypes.Items[idx] as GlobalElementType;
                            }
                            if ((glet != null) && (glet.type is XmlSchemaElement))
                            {
                                el.SchemaTypeName = null;
                                el.RefName = new XmlQualifiedName(typeName, nameSpace);
                                el.Name = null;
                            }
                            else
                            {
                                el.SchemaTypeName = new XmlQualifiedName(typeName, nameSpace);
                                el.RefName = null;
                                if (el.Name == null)
                                {
                                    el.Name = tvSchema.SelectedNode.Text;
                                }
                            }
                            CompileSchema();
                            tvSchema.SelectedNode.Text = el.QualifiedName.Name;
                        }
                    }
                }
                // is it a simple type?
                else if (obj is XmlSchemaSimpleType)
                {
                    XmlSchemaSimpleType st = obj as XmlSchemaSimpleType;
                    // if we're changing the name:
                    if (name != null)
                    {
                        st.Name = name;
                        CompileSchema();
                    }

                    // if we're changing the type name:
                    if (typeName != null)
                    {
                        // this must be done in the Restriction object
                        XmlSchemaSimpleTypeRestriction restriction = st.Content as XmlSchemaSimpleTypeRestriction;
                        if (restriction != null)
                        {
                            restriction.BaseTypeName = new XmlQualifiedName(typeName, nameSpace);
                            CompileSchema();
                            cbGlobalTypes.SelectedIndex = -1;
                        }
                    }
                }
                // is it a complex type?
                else if (obj is XmlSchemaComplexType)
                {
                    // if we're changing the name:
                    if (name != null)
                    {
                        ((XmlSchemaComplexType)obj).Name = name;
                        CompileSchema();
                    }
                    // there is no such thing as changing the type of a complex type
                }
            }
        }
        #endregion

        #region Add Facet
        // Add a facet to a simple type.
        bool AddFacet(XmlSchemaFacet facet, string val, TreeViewImages imgIdx)
        {
            // get the simple type.
            XmlSchemaSimpleType st = tvSchema.SelectedNode.Tag as XmlSchemaSimpleType;

            // assume failure
            XmlSchemaSimpleTypeRestriction rs = null;
            bool success = false;

            // if the simple type exists, get the restriction type
            if (st != null)
            {
                rs = st.Content as XmlSchemaSimpleTypeRestriction;
            }

            // if the restriction type exists...
            if (rs != null)
            {
                // create the node and add it to the facet collection
                TreeNode newNode = CreateNode(facet.ToString());
                facet.Value = val;
                rs.Facets.Add(facet);
                CompileSchema();
                success = true;
            }
            return success;
        }
        #endregion

        #region TextToNodeArray
        // a helper to create some default documentation text.
        public static XmlNode[] TextToNodeArray(string text)
        {
            XmlDocument doc = new XmlDocument();
            return new XmlNode[1] { doc.CreateTextNode(text) };
        }
        #endregion

        #endregion

        #region DecodeSchema

        // stub that wraps the actual decoding in a try block so we can display errors
        private void DecodeSchema(XmlSchema schema, TreeNode node)
        {
            try
            {
                DecodeSchema2(schema, node);
            }
            catch (Exception err)
            {
                edSchemaErrors.Text = err.ToString();
            }
        }

        // recursive decoder
        private TreeNode DecodeSchema2(XmlSchemaObject obj, TreeNode node)
        {
            TreeNode newNode = node;

            // convert the object to all types and then check what type actually exists
            XmlSchemaAnnotation annot = obj as XmlSchemaAnnotation;
            XmlSchemaAttribute attrib = obj as XmlSchemaAttribute;
            XmlSchemaFacet facet = obj as XmlSchemaFacet;
            XmlSchemaDocumentation doc = obj as XmlSchemaDocumentation;
            XmlSchemaAppInfo appInfo = obj as XmlSchemaAppInfo;
            XmlSchemaElement element = obj as XmlSchemaElement;
            XmlSchemaSimpleType simpleType = obj as XmlSchemaSimpleType;
            XmlSchemaComplexType complexType = obj as XmlSchemaComplexType;

            // If the current node is the root node of the tree, then we are
            // possibly adding a global attribute, element, simple type, or complex type.
            if (node == tvSchema.Nodes[0])
            {
                if (attrib != null)
                {
                    if (attrib.Name != null)
                    {
                        // add to global list
                        cbGlobalTypes.Items.Add(new GlobalElementType(attrib.Name, attrib));
                    }
                }
                else if (element != null)
                {
                    if (element.Name != null)
                    {
                        // add to global list
                        cbGlobalTypes.Items.Add(new GlobalElementType(element.Name, element));
                    }
                }
                else if (simpleType != null)
                {
                    if (simpleType.Name != null)
                    {
                        // add to global list
                        cbGlobalTypes.Items.Add(new GlobalElementType(simpleType.Name, simpleType));
                    }
                }
                else if (complexType != null)
                {
                    if (complexType.Name != null)
                    {
                        // add to global list
                        cbGlobalTypes.Items.Add(new GlobalElementType(complexType.Name, complexType));
                    }
                }
            }

            // if annotation, add a tree node and recurse for documentation and app info
            if (annot != null)
            {
                newNode = new TreeNode("--annotation--");
                newNode.Tag = annot;
                newNode.ImageIndex = 4;
                newNode.SelectedImageIndex = 4;
                node.Nodes.Add(newNode);
                foreach (XmlSchemaObject schemaObject in annot.Items)
                {
                    DecodeSchema2(schemaObject, newNode);
                }
            }
            else
                // if attribute, add a tree node
                if (attrib != null)
                {
                    newNode = new TreeNode(attrib.QualifiedName.Name);
                    newNode.Tag = attrib;
                    newNode.ImageIndex = 7;
                    newNode.SelectedImageIndex = 7;
                    node.Nodes.Add(newNode);
                }
                else
                    // if facet, add a tree node
                    if (facet != null)
                    {
                        newNode = new TreeNode(facet.ToString());
                        newNode.Tag = facet;
                        newNode.ImageIndex = 8;
                        newNode.SelectedImageIndex = 8;
                        node.Nodes.Add(newNode);
                    }
                    else
                        // if documentation, add a tree node
                        if (doc != null)
                        {
                            newNode = new TreeNode("--documentation--");
                            newNode.Tag = doc;
                            newNode.ImageIndex = 5;
                            newNode.SelectedImageIndex = 5;
                            node.Nodes.Add(newNode);
                        }
                        else
                            // if app info, add a tree node
                            if (appInfo != null)
                            {
                                newNode = new TreeNode("--app info--");
                                newNode.Tag = annot;
                                newNode.ImageIndex = 6;
                                newNode.SelectedImageIndex = 6;
                                node.Nodes.Add(newNode);
                            }
                            else
                                // if an element, determine whether the element is a simple type or a complex type
                                if (element != null)
                                {
                                    XmlSchemaSimpleType st = element.SchemaType as XmlSchemaSimpleType;
                                    XmlSchemaComplexType ct = element.SchemaType as XmlSchemaComplexType;

                                    if (st != null)
                                    {
                                        // this is a simple type element.  Recurse.
                                        TreeNode node2 = DecodeSchema2(st, newNode);
                                        node2.Text = element.Name;
                                    }
                                    else if (ct != null)
                                    {
                                        // this is a complex type element.  Recurse.
                                        TreeNode node2 = DecodeSchema2(ct, newNode);
                                        node2.Text = element.Name;
                                    }
                                    else
                                    {
                                        // This is a plain ol' fashioned element.
                                        newNode = new TreeNode(element.QualifiedName.Name);
                                        newNode.Tag = element;
                                        newNode.ImageIndex = 1;
                                        newNode.SelectedImageIndex = 1;
                                        node.Nodes.Add(newNode);
                                    }
                                }
                                else
                                    // if a simple type, then add a tree node and recurse facets
                                    if (simpleType != null)
                                    {
                                        newNode = new TreeNode(simpleType.QualifiedName.Name);
                                        newNode.Tag = simpleType;
                                        newNode.ImageIndex = 2;
                                        newNode.SelectedImageIndex = 2;
                                        node.Nodes.Add(newNode);
                                        XmlSchemaSimpleTypeRestriction rest = simpleType.Content as XmlSchemaSimpleTypeRestriction;
                                        if (rest != null)
                                        {
                                            foreach (XmlSchemaFacet schemaObject in rest.Facets)
                                            {
                                                DecodeSchema2(schemaObject, newNode);
                                            }
                                        }
                                    }
                                    else
                                        // if a complex type, add a tree node and recurse its sequence
                                        if (complexType != null)
                                        {
                                            newNode = new TreeNode(complexType.Name);
                                            newNode.Tag = complexType;
                                            newNode.ImageIndex = 3;
                                            newNode.SelectedImageIndex = 3;
                                            node.Nodes.Add(newNode);

                                            XmlSchemaSequence seq = complexType.Particle as XmlSchemaSequence;
                                            if (seq != null)
                                            {
                                                foreach (XmlSchemaObject schemaObject in seq.Items)
                                                {
                                                    DecodeSchema2(schemaObject, newNode);
                                                }
                                            }
                                        }

            // now recurse any object collection of the type.
            foreach (PropertyInfo property in obj.GetType().GetProperties())
            {
                if (property.PropertyType.FullName == "System.Xml.Schema.XmlSchemaObjectCollection")
                {
                    XmlSchemaObjectCollection childObjectCollection = (XmlSchemaObjectCollection)property.GetValue(obj, null);
                    foreach (XmlSchemaObject schemaObject in childObjectCollection)
                    {
                        DecodeSchema2(schemaObject, newNode);
                    }
                }
            }
            return newNode;
        }
        #endregion

        private void Process()
        {
            try
            {
                if (fileName == null)
                    return;

                StreamReader tr = new StreamReader(fileName);
                schema = XmlSchema.Read(tr, new ValidationEventHandler(SchemaValidationHandler));
                tr.Close();
                CompileSchema();
                CreateRootNode();
                DecodeSchema(schema, tvSchema.Nodes[0]);
                tvSchema.ExpandAll();

                if (outputFileName == null)
                    return;

                GenerateCode();
                Application.Exit();
            }
            catch (Exception err)
            {
                edSchemaErrors.Text = err.ToString();
            }
        }

        private void menuItem8_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (fileName == null)
                {
                    MessageBox.Show("You need to load an XML Schema first before you can generate code.", "Cannot generate code");
                    return;
                }

                openSchemaDialog.DefaultExt = "cs";
                openSchemaDialog.CheckFileExists = false;
                openSchemaDialog.FileName = "AppConfig";
                openSchemaDialog.Filter = "CS Files (*.cs)|*.cs|All Files (*.*)|*.*";
                DialogResult res = openSchemaDialog.ShowDialog();
                if (res == DialogResult.OK)
                {
                    outputFileName = openSchemaDialog.FileName;

                    GenerateCode();
                }
            }
            catch (Exception err)
            {
                throw err;
            }
        }

        private void GenerateCode()
        {
            if (outputNamespace == null)
                menuItem10_Click(null, null);

            if ((outputNamespace == null) || (outputNamespace.Length <= 0))
            {
                MessageBox.Show("You must provide a namespace in order to generate the configuration class", "Namespace");
                return;
            }

            // init variables
            sbOutput.Length = 0;
            sbField.Length = 0;
            sbProperty.Length = 0;
            sbLoadValue.Length = 0;
            flagTopElement = true;

            // add reference
            targetUnit = new CodeCompileUnit();
            CodeNamespace targetNamespace = new CodeNamespace(outputNamespace);
            targetNamespace.Imports.AddRange(new CodeNamespaceImport[] {
                    new CodeNamespaceImport("System"),
                    new CodeNamespaceImport("System.Collections"),
                    new CodeNamespaceImport("System.Configuration"),
                    new CodeNamespaceImport("System.Xml"),
                    new CodeNamespaceImport("System.IO"),
                    new CodeNamespaceImport("System.Web")
                });

            // add AppConfigHandler class
            CodeTypeDeclaration targetClass = new CodeTypeDeclaration("AppConfigHandler");
            targetClass.IsClass = true;
            targetClass.TypeAttributes = TypeAttributes.NotPublic;
            targetClass.BaseTypes.Add(new CodeTypeReference("IConfigurationSectionHandler"));

            // add Create method to AppConfigHandler class
            CodeMemberMethod targetMethod = new CodeMemberMethod();
            targetMethod.Name = "Create";
            targetMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            targetMethod.ReturnType = new CodeTypeReference(typeof(object));
            targetMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "parent"));
            targetMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "context"));
            targetMethod.Parameters.Add(new CodeParameterDeclarationExpression("XmlNode", "node"));

            // add statement to Create method
            targetMethod.Statements.Add(new CodeSnippetStatement(@"
			try
			{
				AppConfig _config = new AppConfig();
				_config.LoadValues(node);

				return _config;
			}
			catch(Exception ex)
			{
				throw ex;
			}
"));

            targetClass.Members.Add(targetMethod);
            targetNamespace.Types.Add(targetClass);

            // create AppConfig class
            targetClass = new CodeTypeDeclaration("AppConfig");
            targetClass.IsClass = true;
            targetClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;

            // create LoadAppValues method
            loadAppValuesMethod = new CodeMemberMethod();
            loadAppValuesMethod.Name = "LoadAppValues";
            loadAppValuesMethod.Attributes = MemberAttributes.Family | MemberAttributes.Final;
            loadAppValuesMethod.ReturnType = new CodeTypeReference();
            loadAppValuesMethod.Parameters.Add(new CodeParameterDeclarationExpression("XmlNode", "currentConfigNode"));

            // add statement to LoadAppValues method
            //loadAppValuesMethod.Statements.Add(new CodeCommentStatement("Test comment statement"));

            loadAppValuesMethod.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("XmlNode"), "node"));
            loadAppValuesMethod.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("XmlNodeList"), "nodeList"));

            // prepare AppConfig class from Schema
            OutputSchema(schema, targetClass);

            // create LoadValues method
            targetMethod = new CodeMemberMethod();
            targetMethod.Name = "LoadValues";
            targetMethod.Attributes = MemberAttributes.Assembly | MemberAttributes.Final;
            targetMethod.ReturnType = new CodeTypeReference();
            targetMethod.Parameters.Add(new CodeParameterDeclarationExpression("XmlNode", "node"));

            // add statement to LoadValues method
            targetMethod.Statements.Add(new CodeSnippetStatement(@"
		XmlNode currentConfigNode = null;

		try
		{
			XmlNode appEnvironmentNode = node.SelectSingleNode(""AppEnvironment"");
			if (appEnvironmentNode != null)
			{
				XmlAttribute att = appEnvironmentNode.Attributes[""configSource""];
				if (att == null)
					throw new Exception(""configSource attribute missed."");
				if ((att.Value == null) || (att.Value.Trim().Length == 0))
					throw new Exception(""configSource attribute value missed"");
				string environmentConfig = att.Value;

				// to get the path for the executable file that started the application, without the executable name
				string appPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);

				string xmlFileName = Path.Combine(appPath, environmentConfig);

				if (File.Exists(xmlFileName))
				{
					XmlDocument doc = new XmlDocument();

					doc.Load(xmlFileName);

					if (doc.HasChildNodes)
					{
						XmlNode childNode = doc.SelectSingleNode(""AppConfigSettings"");
						if (childNode != null)
						{
							LoadAppValues(childNode);
						}
					}
					else
					{
						throw new Exception(""Bad file format in config source file: "" + xmlFileName);
					}

				}
				else
				{
					throw new Exception(""Cannot find sustom config file: "" + xmlFileName);
				}
			}
			else
				throw new Exception(""AppEnvironment must be specified."");
		}
		catch (Exception ex)
		{
			throw new Exception(""Configuration error in AppConfig section: "" + ex.Message);
		}	
"));

            targetClass.Members.Add(targetMethod);

            targetClass.Members.Add(loadAppValuesMethod);

            targetNamespace.Types.Add(targetClass);
            targetUnit.Namespaces.Add(targetNamespace);

            string sOut = sbOutput.ToString();

            GenerateCSharpCode(outputFileName);
        }

        #region OutputSchema
        // recursive decoder
        CodeExpression[] ceRef = new CodeExpression[1];

        private void OutputSchema(XmlSchemaObject obj, CodeTypeDeclaration tClass)
        { OutputSchema(obj, tClass, null, null, ref ceRef, null); }

        private void OutputSchema(XmlSchemaObject obj, CodeTypeDeclaration tClass, CodeConstructor tConstructor)
        { OutputSchema(obj, tClass, tConstructor, null, ref ceRef, null); }

        private void OutputSchema(XmlSchemaObject obj, CodeTypeDeclaration tClass, CodeConstructor tConstructor, CodeTypeDeclaration tParentClass, ref CodeExpression[] tParameter, CodeStatementCollection tDeclaration)
        {
            // convert the object to all types and then check what type actually exists
            XmlSchemaAnnotation annot = obj as XmlSchemaAnnotation;
            XmlSchemaAttribute attrib = obj as XmlSchemaAttribute;
            XmlSchemaFacet facet = obj as XmlSchemaFacet;
            XmlSchemaDocumentation doc = obj as XmlSchemaDocumentation;
            XmlSchemaAppInfo appInfo = obj as XmlSchemaAppInfo;
            XmlSchemaElement element = obj as XmlSchemaElement;
            XmlSchemaSimpleType simpleType = obj as XmlSchemaSimpleType;
            XmlSchemaComplexType complexType = obj as XmlSchemaComplexType;

            // if annotation, add a tree node and recurse for documentation and app info
            if (annot != null)
            {
                foreach (XmlSchemaObject schemaObject in annot.Items)
                {
                    OutputSchema(schemaObject, tClass);
                }
            }
            else
                // if attribute, add a tree node
                if (attrib != null)
                {
                    string s = attrib.QualifiedName.Name;
                }
                else
                    // if facet, add a tree node
                    if (facet != null)
                    {
                        string s = facet.ToString();
                    }
                    else
                        // if documentation, add a tree node
                        if (doc != null)
                        {
                            string s = doc.ToString();
                        }
                        else
                            // if app info, add a tree node
                            if (appInfo != null)
                            {
                                string s = annot.ToString();
                            }
                            else
                                // if an element, determine whether the element is a simple type or a complex type
                                if (element != null)
                                {
                                    CodeExpression[] ceP = null;
                                    CodeStatementCollection csD = null;

                                    XmlSchemaSimpleType st = element.SchemaType as XmlSchemaSimpleType;
                                    XmlSchemaComplexType ct = element.SchemaType as XmlSchemaComplexType;

                                    System.Type cmType = null;
                                    string cmTypeString = string.Empty;

                                    if (st != null)
                                    {
                                        // this is a simple type element.  Recurse.
                                        sbOutput.Append("\r\nSimple Element: " + element.Name);
                                        OutputSchema(st, tClass);
                                    }
                                    #region else if (ct != null)
                                    else if (ct != null)
                                    {
                                        // this is a complex type element.  Recurse.

                                        // Declare the field.
                                        CodeMemberField cmField = new CodeMemberField();
                                        cmField.Attributes = MemberAttributes.Private;
                                        cmField.Name = "fld" + element.QualifiedName.Name;

                                        cmField.Type = new CodeTypeReference(element.QualifiedName.Name);

                                        if (tConstructor != null)
                                        {
                                            // constructor
                                            tConstructor.Parameters.Add(new CodeParameterDeclarationExpression(cmField.Type, "_" + cmField.Name));
                                            tConstructor.Statements.Add(
                                                new CodeAssignStatement(new CodeVariableReferenceExpression(cmField.Name),
                                                new CodeVariableReferenceExpression("_" + cmField.Name)));

                                        }

                                        CodeTypeDeclaration collectionClass = null;
                                        CodeTypeDeclaration subClass;
                                        subClass = new CodeTypeDeclaration(element.QualifiedName.Name);
                                        subClass.IsClass = true;
                                        subClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;

                                        #region if (element.MaxOccurs > 1)
                                        if (element.MaxOccurs > 1)
                                        {
                                            CodeMemberField cmCollectionField = new CodeMemberField();
                                            cmCollectionField.Attributes = MemberAttributes.Private;
                                            cmCollectionField.Name = "fld" + element.QualifiedName.Name + "Collection";

                                            //	private ProvinceCollection provinces = new ProvinceCollection();
                                            cmCollectionField.Type = new CodeTypeReference(element.QualifiedName.Name + "Collection");

                                            cmCollectionField.InitExpression =
                                                new CodeObjectCreateExpression(
                                                new CodeTypeReference(element.QualifiedName.Name + "Collection"));

                                            tClass.Members.Add(cmCollectionField);

                                            collectionClass = new CodeTypeDeclaration(element.QualifiedName.Name + "Collection");
                                            collectionClass.IsClass = true;
                                            collectionClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
                                            collectionClass.BaseTypes.Add(new CodeTypeReference("CollectionBase"));

                                            collectionClass.Members.Add(subClass);
                                            tClass.Members.Add(collectionClass);

                                            CodeMemberMethod tMethod = new CodeMemberMethod();
                                            tMethod.Name = "Add";
                                            tMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                                            tMethod.Parameters.Add(new CodeParameterDeclarationExpression(cmField.Type, "_" + element.QualifiedName.Name));

                                            // add statement to Create method
                                            tMethod.Statements.Add(new CodeSnippetStatement("this.List.Add(" + "_" + element.QualifiedName.Name + ");"));
                                            collectionClass.Members.Add(tMethod);

                                            CodeMemberProperty cmProperty = new CodeMemberProperty();
                                            cmProperty.Name = "Item";
                                            cmProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                                            cmProperty.Type = new CodeTypeReference(subClass.Name);
                                            cmProperty.Parameters.Add(new CodeParameterDeclarationExpression(
                                                new CodeTypeReference(typeof(int)), "index"));
                                            cmProperty.GetStatements.Add(new CodeMethodReturnStatement(
                                                new CodeCastExpression(subClass.Name,
                                                new CodeIndexerExpression(new CodeFieldReferenceExpression(
                                                new CodeThisReferenceExpression(), "List"),
                                                new CodeArgumentReferenceExpression("index")))));
                                            cmProperty.SetStatements.Add(new CodeAssignStatement(
                                                new CodeIndexerExpression(new CodeFieldReferenceExpression(
                                                new CodeThisReferenceExpression(), "List"),
                                                new CodeArgumentReferenceExpression("index")),
                                                new CodeArgumentReferenceExpression("value")));
                                            collectionClass.Members.Add(cmProperty);

                                            cmProperty = new CodeMemberProperty();
                                            cmProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                                            cmProperty.Name = element.QualifiedName.Name + "Collections";
                                            cmProperty.HasGet = true;
                                            cmProperty.Type = cmCollectionField.Type;

                                            if (element.MinOccurs > 1)
                                            {
                                            }
                                            else if (element.MinOccurs > 0)
                                            {
                                            }
                                            else
                                            {
                                            }

                                            cmProperty.GetStatements.Add(new CodeMethodReturnStatement(
                                                new CodeFieldReferenceExpression(
                                                new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name + "Collection")));
                                            tClass.Members.Add(cmProperty);

                                        }
                                        #endregion
                                        #region else
                                        else
                                        {
                                            tClass.Members.Add(cmField);

                                            // add properties //
                                            CodeMemberProperty cmProperty = new CodeMemberProperty();
                                            cmProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                                            cmProperty.Name = element.QualifiedName.Name + "Field";
                                            cmProperty.HasGet = true;
                                            cmProperty.HasSet = true;
                                            cmProperty.Type = cmField.Type;

                                            cmProperty.GetStatements.Add(new CodeMethodReturnStatement(
                                                new CodeFieldReferenceExpression(
                                                new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name)));

                                            tClass.Members.Add(cmProperty);

                                            tClass.Members.Add(subClass);
                                        }
                                        #endregion

                                        //cmField.Comments.Add(new CodeCommentStatement(element.QualifiedName.Name + " field"));
                                        ////tClass.Members.Add(subClass);

                                        #region if (flagTopElement)
                                        if (flagTopElement)
                                        {
                                            // add Create method to AppConfigHandler class
                                            CodeMemberMethod tMethod = new CodeMemberMethod();
                                            tMethod.Name = "GetConfig";
                                            tMethod.Attributes = MemberAttributes.Public | MemberAttributes.Static;
                                            tMethod.ReturnType = new CodeTypeReference("AppConfig");
                                            tMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "sectionName"));

                                            // add statement to Create method
                                            tMethod.Statements.Add(new CodeSnippetStatement(@"
		try
		{
			return (AppConfig)ConfigurationSettings.GetConfig(sectionName);
		}
		catch(Exception ex)
		{
			throw ex;
		}
"));
                                            tClass.Members.Add(tMethod);

                                            flagTopElement = false;
                                            OutputSchema(ct, tClass);
                                        }
                                        #endregion
                                        #region else
                                        else
                                        {
                                            sbField.Append(string.Format("private {0} {1} = {2};\r\n", element.SchemaTypeName.Name, element.QualifiedName.Name, element.DefaultValue));

                                            // Declares a constructor that takes arguments
                                            CodeConstructor targetConstructor = new CodeConstructor();
                                            targetConstructor.Attributes = MemberAttributes.Public;


                                            if (element.MaxOccurs > 1)
                                            {
                                                #region LoadAppValues Complex type

                                                ceP = new CodeExpression[1];

                                                csD = new CodeStatementCollection();

                                                CodeIterationStatement codeWhile = new CodeIterationStatement();
                                                codeWhile.TestExpression = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("e" + element.QualifiedName.Name), "MoveNext"));
                                                codeWhile.Statements.Add(new CodeVariableDeclarationStatement("XmlNode", "n" + element.QualifiedName.Name, new CodeCastExpression("XmlNode", new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("e" + element.QualifiedName.Name), "Current"))));
                                                codeWhile.Statements.Add(new CodeSnippetStatement()); // empty line

                                                OutputSchema(ct, subClass, targetConstructor, collectionClass, ref ceP, csD);

                                                codeWhile.Statements.AddRange(csD);

                                                codeWhile.Statements.Add(new CodeVariableDeclarationStatement(element.QualifiedName.Name + "Collection." + element.QualifiedName.Name, "l_" + element.QualifiedName.Name,
                                                    new CodeObjectCreateExpression(element.QualifiedName.Name + "Collection." + element.QualifiedName.Name, ceP)));

                                                codeWhile.Statements.Add(new CodeSnippetStatement()); // empty line
                                                codeWhile.Statements.Add(new CodeCommentStatement("add this " + element.QualifiedName.Name + " object to the collection"));
                                                codeWhile.Statements.Add(
                                                    new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(
                                                    new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name + "Collection"), "Add",
                                                    new CodeVariableReferenceExpression("l_" + element.QualifiedName.Name)));
                                                codeWhile.IncrementStatement = new CodeSnippetStatement("");
                                                codeWhile.InitStatement = new CodeSnippetStatement("");

                                                CodeStatement[] csStatements;
                                                csStatements =
                                                new CodeStatement[] {
                            new CodeSnippetStatement(), // empty line

                            new CodeAssignStatement(new CodeVariableReferenceExpression("nodeList"), 
                                new CodeMethodInvokeExpression(
                                new CodeVariableReferenceExpression("currentConfigNode"), "SelectNodes",
                                new CodePrimitiveExpression(element.QualifiedName.Name))),

                                new CodeConditionStatement(
                                    new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("nodeList"), CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
                                    new CodeStatement[]{
                                        new CodeCommentStatement(""),
                                        new CodeVariableDeclarationStatement("IEnumerator", "e" + element.QualifiedName.Name, new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("nodeList"), "GetEnumerator"))),
                                        codeWhile
                                    })
                        };

                                                if (tDeclaration != null)
                                                    tDeclaration.AddRange(csStatements);
                                                else
                                                    loadAppValuesMethod.Statements.AddRange(csStatements);
                                                #endregion


                                                subClass.Members.Add(targetConstructor);
                                            }
                                            else
                                            {
                                                if ((tParameter.Length != 1) || (tParameter[0] != null))
                                                {
                                                    CodeExpression[] ceTemp1 = new CodeExpression[tParameter.Length + 1];
                                                    tParameter.CopyTo(ceTemp1, 0);
                                                    tParameter = new CodeExpression[tParameter.Length + 1];
                                                    ceTemp1.CopyTo(tParameter, 0);
                                                }

                                                tParameter[tParameter.Length - 1] = new CodeVariableReferenceExpression("l_" + element.QualifiedName.Name);

                                                #region LoadAppValues Complex type

                                                ceP = new CodeExpression[1];
                                                csD = new CodeStatementCollection();

                                                OutputSchema(ct, subClass, targetConstructor, null, ref ceP, csD);

                                                CodeStatementCollection csStatements = new CodeStatementCollection();
                                                csStatements.Add(new CodeSnippetStatement()); // empty line

                                                csStatements.Add(new CodeVariableDeclarationStatement("XmlNode", "n" + element.QualifiedName.Name,
                                                    new CodeMethodInvokeExpression(
                                                    new CodeVariableReferenceExpression(tClass.Name == "AppConfig" ? "currentConfigNode" : "n" + tClass.Name),
                                                    "SelectSingleNode",
                                                    new CodePrimitiveExpression(element.QualifiedName.Name))));

                                                csStatements.AddRange(csD);

                                                if (tClass.Name == "AppConfig")
                                                {
                                                    csStatements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression("fld" + element.QualifiedName.Name),
                                                        new CodeObjectCreateExpression(element.QualifiedName.Name, ceP)));
                                                }
                                                else
                                                {
                                                    csStatements.Add(new CodeVariableDeclarationStatement(tClass.Name + "Collection." + tClass.Name + "." + element.QualifiedName.Name,
                                                        "l_" + element.QualifiedName.Name,
                                                        new CodeObjectCreateExpression(tClass.Name + "Collection." + tClass.Name + "." + element.QualifiedName.Name, ceP)));
                                                }

                                                if (tDeclaration != null)
                                                    tDeclaration.AddRange(csStatements);
                                                else
                                                    loadAppValuesMethod.Statements.AddRange(csStatements);
                                                #endregion

                                                subClass.Members.Add(targetConstructor);
                                            }
                                        }
                                        #endregion

                                    }
                                    #endregion
                                    #region else
                                    else
                                    {
                                        // This is a plain ol' fashioned element.
                                        sbOutput.Append(string.Format("\r\nPlain Element - Type - Default - MinOccur - MaxOccur: {0} - {1} - {2} - {3} - {4}", element.QualifiedName.Name, element.SchemaTypeName.Name, element.DefaultValue, element.MinOccurs, element.MaxOccurs));

                                        // Declare the field.
                                        CodeMemberField cmField = new CodeMemberField();
                                        cmField.Attributes = MemberAttributes.Private;
                                        cmField.Name = "fld" + element.QualifiedName.Name;

                                        if (element.ElementSchemaType.Datatype != null)
                                            cmType = System.Type.GetType(element.ElementSchemaType.Datatype.ValueType.FullName);
                                        else
                                        {
                                            cmType = null;
                                            cmTypeString = element.ElementSchemaType.Name;
                                        }

                                        if (cmType != null)
                                        {
                                            if (element.MaxOccurs > 1)
                                                cmField.Type = new CodeTypeReference(new CodeTypeReference(cmType), 1); // declare array
                                            else
                                                cmField.Type = new CodeTypeReference(cmType);
                                        }
                                        else
                                        {
                                            if (element.MaxOccurs > 1)
                                                cmField.Type = new CodeTypeReference(new CodeTypeReference(cmTypeString), 1); // declare array
                                            else
                                                cmField.Type = new CodeTypeReference(cmTypeString);
                                        }

                                        tClass.Members.Add(cmField);

                                        // add properties //
                                        CodeMemberProperty cmProperty = new CodeMemberProperty();
                                        cmProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                                        cmProperty.Name = element.QualifiedName.Name;
                                        cmProperty.HasGet = true;
                                        cmProperty.Type = cmField.Type;

                                        cmProperty.GetStatements.Add(new CodeMethodReturnStatement(
                                            new CodeFieldReferenceExpression(
                                            new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name)));
                                        tClass.Members.Add(cmProperty);

                                        #region // LoadAppValues //

                                        if (element.MaxOccurs > 1)
                                        {
                                            #region LoadAppValues Simple type
                                            CodeVariableDeclarationStatement casNode;
                                            casNode = new CodeVariableDeclarationStatement("XmlNodeList",
                                                "nodeList" + element.QualifiedName.Name,
                                                new CodeMethodInvokeExpression(
                                                    new CodeVariableReferenceExpression(tClass.Name == "AppConfig" ? "currentConfigNode" : "n" + tClass.Name), "SelectNodes",
                                                    new CodePrimitiveExpression(element.QualifiedName.Name)));

                                            if (element.ElementSchemaType.Datatype != null)
                                                cmType = System.Type.GetType(element.ElementSchemaType.Datatype.ValueType.FullName);
                                            else
                                            {
                                                cmType = null;
                                                cmTypeString = element.ElementSchemaType.Name;
                                            }

                                            if (cmType != null)
                                            {
                                                cmField.Type = new CodeTypeReference(new CodeTypeReference(cmType), 1); // declare array
                                            }
                                            else
                                            {
                                                cmField.Type = new CodeTypeReference(new CodeTypeReference(cmTypeString), 1); // declare array
                                            }

                                            if (tDeclaration != null)
                                            {
                                                if ((tParameter.Length != 1) || (tParameter[0] != null))
                                                {
                                                    CodeExpression[] ceTemp1 = new CodeExpression[tParameter.Length + 1];
                                                    tParameter.CopyTo(ceTemp1, 0);
                                                    tParameter = new CodeExpression[tParameter.Length + 1];
                                                    ceTemp1.CopyTo(tParameter, 0);
                                                }

                                                tParameter[tParameter.Length - 1] = new CodeVariableReferenceExpression("l_fld" + element.QualifiedName.Name);

                                                tDeclaration.Add(new CodeSnippetStatement()); // empty line

                                                tDeclaration.Add(new CodeVariableDeclarationStatement(cmField.Type, "l_fld" + element.QualifiedName.Name, new CodePrimitiveExpression(null)));

                                                tDeclaration.Add(casNode);
                                            }
                                            else
                                            {
                                                loadAppValuesMethod.Statements.Add(new CodeSnippetStatement()); // empty line

                                                loadAppValuesMethod.Statements.Add(new CodeVariableDeclarationStatement(cmField.Type, "l_fld" + element.QualifiedName.Name, new CodePrimitiveExpression(null)));
                                                loadAppValuesMethod.Statements.Add(casNode);
                                            }

                                            CodeBinaryOperatorExpression ifCondition1 = new CodeBinaryOperatorExpression();
                                            ifCondition1.Left = new CodeVariableReferenceExpression("nodeList" + element.QualifiedName.Name);
                                            ifCondition1.Right = new CodePrimitiveExpression(null);
                                            ifCondition1.Operator = CodeBinaryOperatorType.IdentityInequality;

                                            CodeBinaryOperatorExpression ifCondition2 = new CodeBinaryOperatorExpression();
                                            ifCondition2.Left = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText"),
                                                "Trim", null));
                                            ifCondition2.Right = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(string)), "Empty");
                                            ifCondition2.Operator = CodeBinaryOperatorType.IdentityInequality;

                                            CodeStatement[] csStatements;
                                            CodeExpression ceTemp = null;
                                            if (tDeclaration != null)
                                                ceTemp = new CodeVariableReferenceExpression("l_fld" + element.QualifiedName.Name);
                                            else
                                                ceTemp = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name);

                                            if (cmType == typeof(int))
                                            {
                                                csStatements =
                                                new CodeStatement[] { 
                                new CodeTryCatchFinallyStatement(
                                    new CodeStatement[]{
                                new CodeAssignStatement(ceTemp, 
                                new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(int)), "Parse"), 
                                new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
                                new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
                            new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
                                new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be an integer")}))
                            })})};
                                            }
                                            else if (cmType == typeof(bool))
                                            {
                                                csStatements =
                                                new CodeStatement[] { 
                                new CodeTryCatchFinallyStatement(
                                    new CodeStatement[]{
                                new CodeAssignStatement(ceTemp, 
                                new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(bool)), "Parse"), 
                                new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
                                new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
                            new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
                                new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be a boolean")}))
                            })})};
                                            }
                                            else if (cmType == typeof(long))
                                            {
                                                csStatements =
                                                new CodeStatement[] { 
                                new CodeTryCatchFinallyStatement(
                                    new CodeStatement[]{
                                new CodeAssignStatement(ceTemp, 
                                new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(long)), "Parse"), 
                                new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
                                new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
                            new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
                                new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be a long")}))
                            })})};
                                            }
                                            else
                                            {
                                                CodeIterationStatement codeWhile = new CodeIterationStatement();
                                                codeWhile.TestExpression = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("e" + element.QualifiedName.Name), "MoveNext"));
                                                codeWhile.IncrementStatement = new CodeSnippetStatement("");
                                                codeWhile.InitStatement = new CodeSnippetStatement("");
                                                codeWhile.Statements.Add(new CodeVariableDeclarationStatement("XmlNode", "n" + element.QualifiedName.Name, new CodeCastExpression("XmlNode", new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("e" + element.QualifiedName.Name), "Current"))));
                                                codeWhile.Statements.Add(new CodeSnippetStatement()); // empty line

                                                codeWhile.Statements.Add(
                                                    new CodeAssignStatement(
                                                        new CodeArrayIndexerExpression(new CodeVariableReferenceExpression("l_fld" + element.QualifiedName.Name), new CodeVariableReferenceExpression("i++")),
                                                        new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("n" + element.QualifiedName.Name), "InnerText"))
                                                );

                                                if (cmType != null)
                                                {
                                                    csStatements =
                                                    new CodeStatement[] {
                                new CodeAssignStatement(new CodeTypeReferenceExpression("l_fld" + element.QualifiedName.Name),
                                    new CodeArrayCreateExpression(cmType, new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("nodeList" + element.QualifiedName.Name), "Count"))),

                                new CodeVariableDeclarationStatement(typeof(int), "i", new CodePrimitiveExpression(0)),

                                new CodeVariableDeclarationStatement("IEnumerator", "e" + element.QualifiedName.Name, new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("nodeList" + element.QualifiedName.Name), "GetEnumerator"))),

                                codeWhile
                            };
                                                }
                                                else
                                                {
                                                    csStatements =
                                                    new CodeStatement[] {
                                new CodeAssignStatement(new CodeTypeReferenceExpression("l_fld" + element.QualifiedName.Name),
                                    new CodeArrayCreateExpression(cmTypeString, new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("nodeList" + element.QualifiedName.Name), "Count"))),

                                    new CodeVariableDeclarationStatement(typeof(int), "i", new CodePrimitiveExpression(0)),

                                    new CodeVariableDeclarationStatement("IEnumerator", "e" + element.QualifiedName.Name, new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeVariableReferenceExpression("nodeList" + element.QualifiedName.Name), "GetEnumerator"))),

                                    codeWhile
                            };
                                                }
                                            }

                                            CodeConditionStatement conditionalStatement = new CodeConditionStatement(
                                                ifCondition1, // if (nodeList1 != null)
                                                csStatements
                                                );

                                            if (tDeclaration != null)
                                                tDeclaration.AddRange(new CodeStatement[] { conditionalStatement });
                                            else
                                                loadAppValuesMethod.Statements.AddRange(new CodeStatement[] { conditionalStatement });
                                            #endregion
                                        }
                                        else
                                        {
                                            #region LoadAppValues Simple type
                                            CodeAssignStatement casNode;
                                            casNode = new CodeAssignStatement(
                                                new CodeVariableReferenceExpression("node"),
                                                new CodeMethodInvokeExpression(
                                                    new CodeVariableReferenceExpression(tClass.Name == "AppConfig" ? "currentConfigNode" : "n" + tClass.Name), "SelectSingleNode",
                                                    new CodePrimitiveExpression(element.QualifiedName.Name)));

                                            if (element.ElementSchemaType.Datatype != null)
                                                cmType = System.Type.GetType(element.ElementSchemaType.Datatype.ValueType.FullName);
                                            else
                                            {
                                                cmType = null;
                                                cmTypeString = element.ElementSchemaType.Name;
                                            }

                                            if (tDeclaration != null)
                                            {
                                                if ((tParameter.Length != 1) || (tParameter[0] != null))
                                                {
                                                    CodeExpression[] ceTemp1 = new CodeExpression[tParameter.Length + 1];
                                                    tParameter.CopyTo(ceTemp1, 0);
                                                    tParameter = new CodeExpression[tParameter.Length + 1];
                                                    ceTemp1.CopyTo(tParameter, 0);
                                                }

                                                tParameter[tParameter.Length - 1] = new CodeVariableReferenceExpression("l_fld" + tClass.Name + "_" + element.QualifiedName.Name);

                                                tDeclaration.Add(new CodeSnippetStatement()); // empty line

                                                CodeExpression ceInit = null;
                                                if (cmType == typeof(int))
                                                    ceInit = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(cmType), "MinValue");
                                                else if (cmType == typeof(long))
                                                    ceInit = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(cmType), "MinValue");
                                                else
                                                {
                                                    if (cmType != null)
                                                        ceInit = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(cmType), "Empty");
                                                    else
                                                        ceInit = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(cmTypeString), "Empty");
                                                }

                                                if (cmType != null)
                                                    tDeclaration.Add(new CodeVariableDeclarationStatement(cmType, "l_fld" + tClass.Name + "_" + element.QualifiedName.Name, ceInit));
                                                else
                                                    tDeclaration.Add(new CodeVariableDeclarationStatement(cmTypeString, "l_fld" + element.QualifiedName.Name, ceInit));

                                                tDeclaration.Add(casNode);
                                            }
                                            else
                                            {
                                                loadAppValuesMethod.Statements.Add(new CodeSnippetStatement()); // empty line
                                                loadAppValuesMethod.Statements.Add(casNode);
                                            }

                                            CodeBinaryOperatorExpression ifCondition1 = new CodeBinaryOperatorExpression();
                                            ifCondition1.Left = new CodeVariableReferenceExpression("node");
                                            ifCondition1.Right = new CodePrimitiveExpression(null);
                                            ifCondition1.Operator = CodeBinaryOperatorType.IdentityInequality;

                                            CodeBinaryOperatorExpression ifCondition2 = new CodeBinaryOperatorExpression();
                                            ifCondition2.Left = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText"),
                                                "Trim", null));
                                            ifCondition2.Right = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(string)), "Empty");
                                            ifCondition2.Operator = CodeBinaryOperatorType.IdentityInequality;

                                            CodeStatement[] csStatements;
                                            CodeExpression ceTemp = null;
                                            if (tDeclaration != null)
                                                ceTemp = new CodeVariableReferenceExpression("l_fld" + tClass.Name + "_" + element.QualifiedName.Name);
                                            else
                                                ceTemp = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "fld" + element.QualifiedName.Name);

                                            if (cmType == typeof(int))
                                            {
                                                csStatements =
                                                new CodeStatement[] { 
                                new CodeTryCatchFinallyStatement(
                                    new CodeStatement[]{
                                new CodeAssignStatement(ceTemp, 
                                new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(int)), "Parse"), 
                                new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
                                new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
                            new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
                                new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be an integer")}))
                            })})};
                                            }
                                            else if (cmType == typeof(bool))
                                            {
                                                csStatements =
                                                new CodeStatement[] { 
                                new CodeTryCatchFinallyStatement(
                                    new CodeStatement[]{
                                new CodeAssignStatement(ceTemp, 
                                new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(bool)), "Parse"), 
                                new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
                                new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
                            new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
                                new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be a bool")}))
                            })})};
                                            }
                                            else if (cmType == typeof(long))
                                            {
                                                csStatements =
                                                new CodeStatement[] { 
                                new CodeTryCatchFinallyStatement(
                                    new CodeStatement[]{
                                new CodeAssignStatement(ceTemp, 
                                new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(long)), "Parse"), 
                                new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")))},
                                new CodeCatchClause[]{new CodeCatchClause(null, null, new CodeStatement[]{
                            new CodeThrowExceptionStatement(new CodeObjectCreateExpression(
                                new CodeTypeReference("Exception"), new CodeExpression[]{new CodePrimitiveExpression(element.QualifiedName.Name + @" must be a long")}))
                            })})};
                                            }
                                            else
                                            {
                                                csStatements =
                                                new CodeStatement[] {
                                new CodeAssignStatement(ceTemp, 
                                new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("node"), "InnerText")) };
                                            }

                                            CodeConditionStatement conditionalStatement = new CodeConditionStatement(
                                                new CodeBinaryOperatorExpression(ifCondition1, CodeBinaryOperatorType.BooleanAnd, ifCondition2),
                                                csStatements
                                                );

                                            if (tDeclaration != null)
                                                tDeclaration.AddRange(new CodeStatement[] { conditionalStatement });
                                            else
                                                loadAppValuesMethod.Statements.AddRange(new CodeStatement[] { conditionalStatement });
                                            #endregion
                                        }

                                        #endregion
                                        #region if (tConstructor != null)
                                        if (tConstructor != null)
                                        {
                                            // constructor
                                            tConstructor.Parameters.Add(new CodeParameterDeclarationExpression(cmField.Type, "_" + cmField.Name));
                                            tConstructor.Statements.Add(
                                                new CodeAssignStatement(new CodeVariableReferenceExpression(cmField.Name),
                                                new CodeVariableReferenceExpression("_" + cmField.Name)));

                                            if (tParentClass != null)
                                            {
                                                // GetIndexBy...
                                                CodeMemberMethod tMethod = new CodeMemberMethod();
                                                tMethod.Name = "GetIndexBy" + element.QualifiedName.Name;
                                                tMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                                                tMethod.ReturnType = new CodeTypeReference(typeof(int));
                                                tMethod.Parameters.Add(new CodeParameterDeclarationExpression(cmField.Type, "_" + element.QualifiedName.Name));

                                                // add statement to Create method
                                                tMethod.Statements.Add(new CodeSnippetStatement(@"
		for (int i=0; i < List.Count; i++)
		{
			if ( ((" + tClass.Name + @")List[i])." + element.QualifiedName.Name + @" == _" + element.QualifiedName.Name + @")
			{
				return i;
			}
		}

		throw new Exception(""Cannot identify " + element.QualifiedName.Name + @": "" + _" + element.QualifiedName.Name + @");
                "));
                                                tParentClass.Members.Add(tMethod);
                                            }
                                        }
                                        #endregion
                                    }
                                    #endregion
                                }
                                else
                                    // if a simple type, then add a tree node and recurse facets
                                    if (simpleType != null)
                                    {
                                        sbOutput.Append("\r\nSimple Type: " + simpleType.QualifiedName.Name);
                                        XmlSchemaSimpleTypeRestriction rest = simpleType.Content as XmlSchemaSimpleTypeRestriction;
                                        if (rest != null)
                                        {
                                            foreach (XmlSchemaFacet schemaObject in rest.Facets)
                                            {
                                                sbOutput.Append("\r\nSimple Type Facet: " + schemaObject.GetType().FullName);
                                                OutputSchema(schemaObject, tClass);
                                            }
                                        }
                                    }
                                    else
                                        // if a complex type, add a tree node and recurse its sequence
                                        if (complexType != null)
                                        {
                                            XmlSchemaSequence seq = complexType.Particle as XmlSchemaSequence;
                                            if (seq != null)
                                            {
                                                foreach (XmlSchemaObject schemaObject in seq.Items)
                                                {
                                                    OutputSchema(schemaObject, tClass, tConstructor, tParentClass, ref tParameter, tDeclaration);
                                                }
                                            }
                                        }

            // now recurse any object collection of the type.
            foreach (PropertyInfo property in obj.GetType().GetProperties())
            {
                if (property.PropertyType.FullName == "System.Xml.Schema.XmlSchemaObjectCollection")
                {
                    XmlSchemaObjectCollection childObjectCollection = (XmlSchemaObjectCollection)property.GetValue(obj, null);
                    foreach (XmlSchemaObject schemaObject in childObjectCollection)
                    {
                        sbOutput.Append("\r\nCollection: " + schemaObject.GetType().FullName);
                        OutputSchema(schemaObject, tClass);
                    }
                }
            }

        }
        #endregion

        /// <summary>
        /// Generate CSharp source code from the compile unit.
        /// </summary>
        /// <param name="filename">Output file name</param>
        public void GenerateCSharpCode(string fileName)
        {
            CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
            CodeGeneratorOptions options = new CodeGeneratorOptions();
            options.BracingStyle = "C";
            using (StreamWriter sourceWriter = new StreamWriter(fileName))
            {
                provider.GenerateCodeFromCompileUnit(
                    targetUnit, sourceWriter, options);
            }
        }

        private void SchemaEditor_Load(object sender, EventArgs e)
        {
            Process();
        }

        private void menuItem10_Click(object sender, EventArgs e)
        {
            InputBoxDialog ib = new InputBoxDialog();
            ib.FormPrompt = "Input namespace for configuration class";
            ib.FormCaption = "Namespace";
            ib.DefaultValue = "";
            ib.ShowDialog();

            string s = ib.InputResponse;
            ib.Close();
            if (s.Trim().Length > 0)
                outputNamespace = s;
        }
    }
}

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)

Share

About the Author

Song_Gao
Software Developer (Senior) ThinData
Canada Canada
Song is a senior .NET Developer specialized on both Web and Windows applications. He is an MCTS (Microsoft Certified Technology Specialist) for Windows Applications, Web Applications and Distributed Applications.
 
He currently lives in Toronto and likes to travel.
 
You may contact Song through his email: song_gao@hotmail.com

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141220.1 | Last Updated 20 Jul 2009
Article Copyright 2009 by Song_Gao
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid