##|TYPE Template
##|UNIQUEID ce9c6b98-62fe-4a36-9a31-cd33b283f574
##|TITLE CSLA Business Objects
##|NAMESPACE CSLA_21
##|SOURCE_TYPE Source
##|OUTPUT_LANGUAGE C#
##|GUI_ENGINE .Net Script
##|GUI_LANGUAGE C#
##|GUI_BEGIN
<%#NAMESPACE System, System.Text, System.Collections, Zeus, Zeus.UserInterface, Zeus.DotNetScript %>
public class GeneratedGui : DotNetScriptGui
{
	public GeneratedGui( ZeusGuiContext context ) : base( context ) {}
	private bool bInitializing=false;
	public override void Setup()
	{
		bInitializing = true;
		if ( !input.Contains( "chooseTables" ) || !input.Contains( "txtPath" ) ||
				( !input.Contains( "chkClass" ) && !input.Contains( "chkNaming" ) ) )
		{
			if(context.Objects.ContainsKey("DnpUtils"))DnpUtils.ReadInputFromCache(context);
			ui.Title = "CSLA Object Mapping";
			ui.Width = 600;
			ui.Height = 660;
	
			// Grab default output path
			string sOutputPath = "";
			
			if( input.Contains( "defaultOutputPath" ) ) 
			{
				sOutputPath = input["defaultOutputPath"].ToString();
			}
			//int top=0;
			// Setup Folder selection input control.
			GuiLabel label1 = ui.AddLabel( "label1", "Select the output path:", "Select the output path in the field below." );
			label1.Width = 200;
			GuiTextBox outputPath = ui.AddTextBox( "outputPath", sOutputPath, "Select the Output Path." );
			outputPath.Width = 450;
			GuiFilePicker selectPath = ui.AddFilePicker( "selectPath", "Select Path", "Select the Output Path.", "outputPath", true );
			selectPath.Top = outputPath.Top;
			selectPath.Width = 100;
			selectPath.Left = outputPath.Left + outputPath.Width + 20;
			
			// Setup Database selection combobox.
			GuiLabel label4 = ui.AddLabel( "label4", "Select a database:", "Select a database in the dropdown below." );
			label4.Width = 250;
			GuiComboBox chooseDatabase = ui.AddComboBox( "chooseDatabase", "Select a database." );
			chooseDatabase.Width = 250;
			// Namespace
			GuiLabel label2 = ui.AddLabel( "label2", "Namespace: ",  "Provide your objects namespace." );
			label2.Width = 280;
			GuiTextBox classNamespace = ui.AddTextBox( "classNamespace", "VEPROMS.CSLA.Library", "Provide your objects namespace." );				
			classNamespace.Width = 280;
			
						GuiLabel label3 = ui.AddLabel( "label3", "Member prefix: ", "Provide your Prefix." );
			label3.Width = 100;
			label3.Top = label2.Top;
			label3.Left = label2.Width + 20;
			GuiTextBox memberPrefix = ui.AddTextBox( "memberPrefix", "_", "" );
			memberPrefix.Width = 100;
			memberPrefix.Top = classNamespace.Top;
			memberPrefix.Left = classNamespace.Width + 20;
					 
			GuiLabel label3A = ui.AddLabel( "label3A", "dbConnection: ", "Provide a Connection." );
			label3A.Width = 150;
			label3A.Top = label3.Top;
			label3A.Left = label3.Left+label3.Width + 10;
			GuiTextBox dbConnection = ui.AddTextBox( "dbConnection", "VEPROMS", "" );
			dbConnection.Width = 150;
			dbConnection.Top = memberPrefix.Top;
			dbConnection.Left = memberPrefix.Left + memberPrefix.Width + 10;
			GuiCheckBox chkGenerateMain = MakeGuiCheckBox( "chkGenerateMain", "Main", true, "Create Main Object",100 );
			GuiCheckBox chkFKList = MakeGuiCheckBox( "chkFKList", "FK List", true, "Create FK List Object" ,70,chkGenerateMain,100,0);
			GuiCheckBox chkFKItem = MakeGuiCheckBox( "chkFKItem", "FK Item", true, "Create FK Item Object" ,70,chkFKList,0,-1);
			GuiCheckBox chkInfoList = MakeGuiCheckBox( "chkInfoList", "Info List", true, "Create FK Info List Object" ,70,chkFKItem,0,-1);
			GuiCheckBox chkInfo = MakeGuiCheckBox( "chkInfo", "Info", true, "Create Info Object" ,70,chkInfoList,0,-1);
			GuiCheckBox chkPartBM = MakeGuiCheckBox("chkPartBM","Business Methods",true,"Create Business Methods",130,chkGenerateMain,170,0);
			GuiCheckBox chkPartDA = MakeGuiCheckBox("chkPartDA","Data Access",true,"Create Data Access",130,chkGenerateMain,300,0);
			GuiCheckBox chkPartVR = MakeGuiCheckBox("chkPartVR","Validation Rules",true,"Create Validation Rules",130,chkPartBM,0,-1);
			GuiCheckBox chkPartEX = MakeGuiCheckBox("chkPartEX","Exists",true,"Create Exists",130,chkPartDA,0,-1);
			GuiCheckBox chkPartAR = MakeGuiCheckBox("chkPartAR","Authorization Rules",true,"Create Authorization Rules",130,chkPartVR,0,-1);
			GuiCheckBox chkPartDF = MakeGuiCheckBox("chkPartDF","Defaults",true,"Create Defaults",130,chkPartEX,0,-1);
			GuiCheckBox chkPartFM = MakeGuiCheckBox("chkPartFM","Factory Methods",true,"Create Factory Methods",130,chkPartAR,0,-1);
			GuiCheckBox chkPartCM = MakeGuiCheckBox("chkPartCM","Component Model",true,"Create Component Model Interface",130,chkGenerateMain,430,0);
			GuiCheckBox chkPartL4N = MakeGuiCheckBox("chkPartL4N","Log4Net",true,"Create Log4Net Code",130,chkPartCM,0,-1);
			GuiCheckBox chkVolian = MakeGuiCheckBox("chkVolian","Volian Header",true,"Add Header",130,chkPartL4N,0,-1);
			GuiCheckBox chkDatabase = MakeGuiCheckBox("chkDatabase","Database.cs",true,"Create Database Object",130,chkGenerateMain,0,50);
			GuiCheckBox chkPartEXT = MakeGuiCheckBox("chkPartEXT","Extension Sample",true,"Create Extensions",130,chkPartDF,0,-1);
			GuiCheckBox chkCreateFiles = MakeGuiCheckBox( "chkCreateFiles", "Create Code Files", true, "Create Code Files" ,150);
			GuiCheckBox chkDebug = MakeGuiCheckBox("chkDebug","Debug Output",true,"Add Debug",130,chkCreateFiles,150,0);
			chkDebug.Checked = false;
			GuiTextBox tbDebug = ui.AddTextBox( "tbDebug", "", "Start Date" );
			tbDebug.Top = chkDebug.Top;
			tbDebug.Width = 150;
			tbDebug.Left = chkDebug.Left + 150;
			GuiLabel label7 = ui.AddLabel( "label7", "Select tables:", "Select tables from the listbox below." );
			//label7.Top = chkEqualsHashCode.Top + 20;
			GuiListBox chooseTables = ui.AddListBox( "chooseTables", "Select tables." );
			chooseTables.Height = 120;
	
			// Setup Views selection multi-select listbox.
			GuiLabel label8 = ui.AddLabel( "label8", "Select views:", "Select views from the listbox below." );
			GuiListBox chooseViews = ui.AddListBox( "chooseViews", "Select views." );
			chooseViews.Height = 120;
			
			// Attach the onchange event to the cmbDatabases control.
			setupDatabaseDropdown( chooseDatabase );
			chooseDatabase.AttachEvent( "onchange", "chooseDatabase_onchange" );
	
			ui.ShowGui = true;
		}
		else 
		{
			ui.ShowGui = false;
		}
		bInitializing = false;
	}
	public void setupDatabaseDropdown( GuiComboBox Databases )
	{
		try 
		{	
			if( MyMeta.IsConnected )
			{
				Databases.BindData( MyMeta.Databases );
				if( MyMeta.DefaultDatabase != null ) 
				{
					Databases.SelectedValue = MyMeta.DefaultDatabase.Alias;
					bindTables( Databases.SelectedValue );
					bindViews( Databases.SelectedValue );
				}
			}
		}
		catch
		{
		}
	}
	
	public void bindTables( string sDatabase )
	{
		int count = 0;
	
		GuiListBox lstTables = ui["chooseTables"] as GuiListBox;
		
		try 
		{	
			IDatabase db = MyMeta.Databases[sDatabase];
			lstTables.BindData( db.Tables );
		}
		catch
		{
		}
	}
	
	public void bindViews( string sDatabase )
	{
		int count = 0;
	
		GuiListBox lstViews = ui["chooseViews"] as GuiListBox;
		
		try 
		{	
			IDatabase db = MyMeta.Databases[sDatabase];
			lstViews.BindData( db.Views );
		}
		catch
		{
		}
	}
	
	public void chooseDatabase_onchange( GuiComboBox control )
	{
		int count = 0;
		GuiComboBox cmbDatabases = ui["chooseDatabase"] as GuiComboBox;
		bindTables( cmbDatabases.SelectedText );
		bindViews( cmbDatabases.SelectedText );
		GuiTextBox dbConnection = ui["dbConnection"] as GuiTextBox;
		dbConnection.Text=cmbDatabases.SelectedText;
		GuiTextBox classNamespace = ui["classNamespace"] as GuiTextBox;
		classNamespace.Text=cmbDatabases.SelectedText + ".CSLA.Library";
	}
	<%#FILE MakeGuiCheckBox.cs %>
	
}
##|GUI_END
##|BODY_MODE Markup
##|BODY_ENGINE .Net Script
##|BODY_LANGUAGE C#
##|BODY_TAG_START <%
##|BODY_TAG_END %>
##|BODY_BEGIN
<%#NAMESPACE System.IO, System.Text, System.Text.RegularExpressions, System.Globalization %><%
public class GeneratedTemplate : DotNetScriptTemplate
{
	private ArrayList _selectedTables;
	private ArrayList _selectedViews;
	private ArrayList _classList;
	private ArrayList _duplicateList;
	private ArrayList _PropDescList;
	private string _dbName;
	private string _tableName;
	private string _className;
	private string _exportPath;
	private string _nameSpace;
	private string _prefix;
	private string _dbConnection;
	private string _subclassName;
	private string _refreshMine;
	private ITable _workingTable;
	private Hashtable dicRead;
	//private Hashtable dicReadI;
	private bool _chkGenerateMain; 
	private bool _chkFKList; 
	private bool _chkFKItem; 
	private bool _chkInfoList; 
	private bool _chkInfo; 
	private bool _chkCreateFiles; 
	private bool _chkPartBM;
	private bool _chkPartDA;
	private bool _chkPartVR;
	private bool _chkPartEX;
	private bool _chkPartAR;
	private bool _chkPartDF;
	private bool _chkPartFM;
	private bool _chkPartEXT;
	private bool _chkPartCM;
	private bool _chkDatabase;
	private bool _chkPartL4N;
	private bool _chkDebug;
	private bool _chkVolian;
	private string _tbDebug;
	private string _databaseLogDebug;
	private string _databaseLogInfo;
	private string _databaseLogWarn;
	private string _databaseLogError;
	private string _databaseLogFatal;
	private bool _doOldParent=false;
	
	public bool AddToClassList(string className)
	{
		if (_classList.Contains(className))
		{
			_duplicateList.Add(className);
			return false;
		}
		else
		{
			_classList.Add(className);
			return true;
		}
	}
	public delegate bool Filter(IColumn column);
	public string Debug(string str)
	{
	if (_chkDebug && str.CompareTo(_tbDebug) >= 0)return "/**** MyGeneration Debug " + str + " ****/";
	return "";
	}
	public string DebugLine(string str)
	{
	if (_chkDebug && str.CompareTo(_tbDebug) >= 0)return "\r\n/**** MyGeneration Debug " + str + " ****/";
	return "";
	}
	public void SaveFile()
	{
		if (_chkCreateFiles)
		{
			output.save( Path.Combine( _exportPath, _className + ".cs" ), false );
			output.clear();
		}
	}
	public GeneratedTemplate( ZeusContext context ) : base( context ) {}
	public override void Render()
	{	
		DateTime tStart = DateTime.Now;
		if (context.Objects.ContainsKey("DnpUtils"))DnpUtils.SaveInputToCache(context);
		try{
			InitializeDictionaries();
			_dbName = input["chooseDatabase"].ToString();
			_PropDescList = new ArrayList();
			_selectedTables = input["chooseTables"] as ArrayList;
			_selectedViews = input["chooseViews"] as ArrayList;
			_exportPath = input["outputPath"].ToString();
			_nameSpace = input["classNamespace"].ToString();
			_prefix = input["memberPrefix"].ToString();
			_dbConnection = input["dbConnection"].ToString();
			_chkGenerateMain=(bool)input["chkGenerateMain"];
			_chkFKList=(bool)input["chkFKList"];
			_chkFKItem=(bool)input["chkFKItem"];
			_chkInfoList=(bool)input["chkInfoList"];
			_chkInfo=(bool)input["chkInfo"];
			_chkCreateFiles=(bool)input["chkCreateFiles"];
			_chkPartBM=(bool)input["chkPartBM"];
			_chkPartDA=(bool)input["chkPartDA"];
			_chkPartVR=(bool)input["chkPartVR"];
			_chkPartEX=(bool)input["chkPartEX"];
			_chkPartAR=(bool)input["chkPartAR"];
			_chkPartDF=(bool)input["chkPartDF"];
			_chkPartFM=(bool)input["chkPartFM"];
			_chkPartEXT=(bool)input["chkPartEXT"];
			_chkPartCM=(bool)input["chkPartCM"];
			_chkPartL4N=(bool)input["chkPartL4N"];
			if (_chkPartL4N)
			{
				_databaseLogDebug = "if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat";
				_databaseLogInfo = "if (_MyLog.IsInfoEnabled) _MyLog.InfoFormat";
				_databaseLogWarn = "if (_MyLog.IsWarnEnabled) _MyLog.WarnFormat";
				_databaseLogError = "if (_MyLog.IsErrorEnabled) _MyLog.Error";
				_databaseLogFatal = "if (_MyLog.IsFatalEnabled) _MyLog.Fatal";
			}
			else
			{
				_databaseLogDebug = "Database.LogInfo";
				_databaseLogInfo = "Database.LogInfo";
				_databaseLogWarn = "Database.LogInfo";
				_databaseLogError = "Database.LogException";
				_databaseLogFatal = "Database.LogException";
			}
			_chkDatabase=(bool)input["chkDatabase"];
			_chkDebug=(bool)input["chkDebug"];
			_chkVolian=(bool)input["chkVolian"];
			_tbDebug=(string)input["tbDebug"];
			_classList=new ArrayList();
			_duplicateList=new ArrayList();
			if (_chkDatabase)GenerateDatabase();
			foreach( string _newTable in _selectedTables )
			{
				_workingTable = MyMeta.Databases[_dbName].Tables[_newTable];
				GenerateClassFiles( _workingTable );
			}
			GeneratePropertyDescriptor();
			GenerateCommonRules();
			if (_duplicateList.Count > 0)
			{
				WriteLine("Duplicate Classes");
				foreach(string s in _duplicateList)
				{
					WriteLine("[{0}]",s);
				}
			}
			DateTime tEnd = DateTime.Now;
			WriteLine(string.Format("Total Generation Time: {0} Seconds",TimeSpan.FromTicks(tEnd.Ticks - tStart.Ticks).TotalSeconds));
			//foreach( string _newView in _selectedViews )
			//{
			//	IView _workingView = MyMeta.Databases[_dbName].Views[_newView];
			//		GenerateClassFiles( _workingView.Columns, _className);
			//}
		}
		catch(Exception ex)
		{
			output.write(ex.Message);
		}
	}
	private void InitializeDictionaries()
	{
		dicRead = new Hashtable();
		dicRead["Guid"]="{fmember} = dr.GetGuid(\"{fname}\");";
		dicRead["string"]="{fmember} = dr.GetString(\"{fname}\");";
		dicRead["SmartDate"]="{fmember} = dr.GetSmartDate(\"{fname}\").Text;";
		dicRead["DateTime"]="{fmember} = dr.GetDateTime(\"{fname}\");";
		dicRead["timestamp"]="dr.GetBytes(\"{fname}\", 0, {fmember}, 0, 8);";
		dicRead["image"]="{fmember} = (byte[])dr.GetValue(\"{fname}\");";
		dicRead["varbinary"]="{fmember} = (byte[])dr.GetValue(\"{fname}\");";
		dicRead["int"]="{fmember} = dr.GetInt32(\"{fname}\");";
		dicRead["Int32"]="{fmember} = dr.GetInt32(\"{fname}\");";
		dicRead["Int16"]="{fmember} = dr.GetInt16(\"{fname}\");";
		dicRead["Int16"]="{fmember} = dr.GetInt16(\"{fname}\");";
		dicRead["Int64"]="{fmember} = dr.GetInt64(\"{fname}\");";
		dicRead["byte"]="{fmember} = dr.GetByte(\"{fname}\");";
		dicRead["char"]="{fmember} = dr.GetChar(\"{fname}\");";
		dicRead["double"]="{fmember} = dr.GetDouble(\"{fname}\");";
		dicRead["float"]="{fmember} = dr.GetFloat(\"{fname}\");";
		dicRead["decimal"]="{fmember} = dr.GetDecimal(\"{fname}\");";
		dicRead["bool"]="{fmember} = dr.GetBoolean(\"{fname}\");";
		dicRead["long"]="{fmember} = dr.GetInt64(\"{fname}\");";
		dicRead["int?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["Int32?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["Int16?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["Int16?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["Int64?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["byte?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["char?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["double?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["float?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["decimal?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["bool?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["long?"]="{fmember} = ({ctype})dr.GetValue(\"{fname}\");";
		dicRead["DateTime?"]="if (!dr.IsDBNull(dr.GetOrdinal(\"{fname}\"))) {fmember} = dr.GetDateTime(\"{fname}\");";
	}
	private void GenerateClassFiles(ITable tbl)
	{
		if (_chkGenerateMain)GenerateMainClass(tbl);
		Hashtable dicAlias = new Hashtable();
		foreach(IForeignKey fk in tbl.ForeignKeys)
		{
			if (tbl == fk.PrimaryTable)
			{
				if (!IsPrimaryKey(fk))
				{
					//string sAlias = GetAlias(dicAlias,fk.ForeignTable);
					string sAlias = GetAlias(fk);
					if (_chkFKList)GenerateFKListClass(fk,sAlias);
					if (_chkFKItem && fk.PrimaryTable != fk.ForeignTable )GenerateFKClass(fk,sAlias);
				}
			}
		}
		if (_chkInfoList && AnyNotOneToOne(tbl))GenerateInfoListClass(tbl); // InfoList if any non 1 to 1 relationships
		if (_chkInfo)GenerateInfoClass(tbl);
	}
//	private void ShowForeignKey(ForeignKey fk)
//	{
//		output.writeln("Primary " + fk.PrimaryTable.Name);
//		foreach(IColumn col in fk.PrimaryColumns)output.writeln("  " + col.Name + " " + col.IsInPrimaryKey.ToString());
//		output.writeln(" Foreign " + fk.ForeignTable.Name);
//		foreach(IColumn col in fk.ForeignColumns)output.writeln("  " + col.Name + " " + col.IsInPrimaryKey.ToString());
//	}
	private void GenerateMainClass( ITable tbl )
	{
		_className = ClassName( tbl );
		_PropDescList.Add(_className);
		if (!AddToClassList(_className))return;
		_tableName = tbl.Alias;
		vlnHeader("\r\nusing System.Collections.Generic;\r\nusing Csla.Validation;");
		string sInterface="";
		if (_chkPartCM)
		{
			//sInterface = ", ICustomTypeDescriptor";
%>
	[TypeConverter(typeof(<%=_className%>Converter))]<%
		}
%>
	public partial class <%=_className%> : BusinessBase<<%=_className%>><%=sInterface%>, IDisposable, IVEHasBrokenRules
	{<%
		Log4Net();
		vlnRefreshInfo();
		vlnCollection(tbl,UniqueIndexes(tbl),false);
		if (_chkPartBM)vlnBusinessMethods(tbl.Columns);
		if (_chkPartVR)vlnValidationRules(tbl.Columns);
		if (_chkPartAR)vlnAuthorizationRules(tbl.Columns);
		if (_chkPartFM)vlnFactoryMethods(tbl.Columns);
		if (_chkPartDA)vlnDataAccessPortal(tbl.Columns);
		if (_chkPartEX)vlnExists(tbl.Columns);
		if (_chkPartDF)vlnDefaults(tbl.Columns);
		vlnFooterCM("");
		if (_chkPartEXT)vlnExtension(tbl.Columns);
		SaveFile();
	}
	private void GenerateFKListClass(IForeignKey fk,string sAlias)
	{
		_className =  ClassName( fk.PrimaryTable ) + ClassesName( fk.ForeignTable )+sAlias;
		_className = FKClassesName(fk)+sAlias;
		if (!AddToClassList(_className))return;
		if (fk.PrimaryTable == fk.ForeignTable)
			_subclassName =  ClassName( fk.PrimaryTable);
		else
			_subclassName =  ClassName( fk.PrimaryTable) + ClassName( fk.ForeignTable )+sAlias;
		_tableName =  "//CSLATODO: No Table Name";
		vlnHeader("\r\nusing System.Collections.Generic;\r\nusing Csla.Validation;");
		string sInterface = "";
		if (_chkPartCM)
		{
			sInterface = ", ICustomTypeDescriptor";
%>
	[TypeConverter(typeof(<%=_className%>Converter))]<%
		}
%>
	public partial class <%=_className%> : BusinessListBase<<%=_className%>, <%=_subclassName%>><%=sInterface%>, IVEHasBrokenRules , IDisposable
	{<%
		Log4Net();
		if (_chkPartBM)vlnBusinessMethodsFKList(fk,sAlias);
		if (_chkPartVR)vlnValidationRulesFKList(fk,sAlias);
		if (_chkPartFM)vlnFactoryMethodsFKList(fk,sAlias);
		if (_chkPartDA)vlnDataAccessPortalFKList(fk,sAlias);
		vlnFooterCM(ClassesName( fk.ForeignTable ) + sAlias);
		SaveFile();
	}
	private void GenerateFKClass(IForeignKey fk,string sAlias)
	{
		_className =  ClassName( fk.PrimaryTable ) + ClassName( fk.ForeignTable ) + sAlias;
		_PropDescList.Add(_className);
		if (!AddToClassList(_className))return;
		_tableName =  fk.ForeignTable.Alias;
		vlnHeader("\r\nusing System.Collections.Generic;\r\nusing Csla.Validation;");
		string sInterface="";
		if (_chkPartCM)
		{
			//sInterface = ", ICustomTypeDescriptor";
%>
	[TypeConverter(typeof(<%=_className%>Converter))]<%
		}
%>
	public partial class <%=_className%> : BusinessBase<<%=_className%>><%=sInterface%>, IVEHasBrokenRules, IDisposable
	{<%
		Log4Net();
		if (_chkPartBM)vlnBusinessMethodsFKItem(fk,sAlias);
		if (_chkPartVR)vlnValidationRulesFKItem(fk,sAlias);
		if (_chkPartAR)vlnAuthorizationRulesFKItem(fk,sAlias);
		if (_chkPartFM)vlnFactoryMethodsFKItem(fk,sAlias);
		if (_chkPartDA)vlnDataAccessPortalFKItem(fk,sAlias);
		if (_chkPartDF)vlnDefaults(fk.ForeignTable.Columns);
		vlnFooterCM("");
		if (_chkPartEXT)vlnExtension(fk.ForeignTable.Columns);
		SaveFile();
	}
	private void vlnFooterCM(string displayName)
	{
		if (_chkPartCM)
		{
			if (displayName!="")vlnComponentModelFKList();
%>
	} // Class<%
			if (displayName!="")vlnPropertyDescriptorFKList();
			if (displayName!="")vlnConvertorFKList(displayName);
			else vlnConvertorFKItem();
%>
} // Namespace
<%
		}
		else
		{
%>
	} // Class
} // Namespace
<%
		}
	}
	private void GenerateInfoListClass( ITable tbl )
	{
		_className = ClassName( tbl ) + "InfoList";
		if (!AddToClassList(_className))return;
		_tableName = tbl.Alias;
		_subclassName =  ClassName( tbl ) + "Info";
		vlnHeader("\r\nusing System.Collections.Generic;");
		string sInterface="";
		if (_chkPartCM)
		{
			sInterface = ", ICustomTypeDescriptor";
%>
	[TypeConverter(typeof(<%=_className%>Converter))]<%
		}
%>
	public partial class <%=_className%> : ReadOnlyListBase<<%=_className%>, <%=_subclassName%>><%=sInterface%>, IDisposable
	{<%
		Log4Net();
		if (_chkPartBM)
		{
%>
		#region Business Methods
		internal new IList<<%=_subclassName%>> Items
		{ get { return base.Items; } }
		public void AddEvents()
		{
			foreach (<%=_subclassName%> tmp in this)
			{
				tmp.Changed += new <%=_subclassName%>Event(tmp_Changed);
			}
		}
		void tmp_Changed(object sender)
		{
			for (int i = 0; i < Count; i++)
			{
				if (base[i] == sender)
					this.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, i));
			}
		}
		private bool _Disposed = false;
		private static int _CountCreated = 0;
		private static int _CountDisposed = 0;
		private static int _CountFinalized = 0;
		private static int IncrementCountCreated
		{ get { return ++_CountCreated; } }
		private int _CountWhenCreated = IncrementCountCreated;
		public static int CountCreated
		{ get { return _CountCreated; } }
		public static int CountNotDisposed
		{ get { return _CountCreated - _CountDisposed; } }
		public static int CountNotFinalized
		{ get { return _CountCreated - _CountFinalized; } }
		~<%=_className%>()
		{
			_CountFinalized++;
		}
		public void Dispose()
		{
			if (_Disposed) return;
			_CountDisposed++;
			_Disposed = true;
			foreach (<%=_subclassName%> tmp in this)
			{
				tmp.Changed -= new <%=_subclassName%>Event(tmp_Changed);
			}
		}
		#endregion<%}
		if (_chkPartFM)vlnFactoryMethodsInfoList(tbl.Columns);
		if (_chkPartDA)vlnDataAccessPortalInfoList(tbl.Columns);
		vlnFooterCM(ClassesName( tbl ) );
		SaveFile();
	}
	private void GenerateInfoClass( ITable tbl )
	{
		_className = ClassName( tbl ) + "Info";
		_PropDescList.Add(_className);
		if (!AddToClassList(_className))return;
		_tableName = tbl.Alias;
		vlnHeader("\r\nusing System.Collections.Generic;","\r\n\tpublic delegate void " + _className + "Event(object sender);");
		string sInterface="";
		if (_chkPartCM)
		{
			//sInterface = ", ICustomTypeDescriptor";
%>
	[TypeConverter(typeof(<%=_className%>Converter))]<%
		}
%>
	public partial class <%=_className%> : ReadOnlyBase<<%=_className%>><%=sInterface%>, IDisposable
	{
		public event <%=_className%>Event Changed;
		private void OnChange()
		{
			if (Changed != null) Changed(this);
		}<%
		Log4Net();
		vlnCollection(tbl,new ArrayList(),true);
		if (_chkPartBM)vlnBusinessMethodsInfo(tbl.Columns);
		if (_chkPartFM)vlnFactoryMethodsInfo(tbl.Columns);
		if (_chkPartDA)vlnDataAccessPortalInfo(tbl.Columns);
		vlnInfoExtension(tbl.Columns);//20070410
		vlnFooterCM("");
		SaveFile();
	}
	private void vlnHeader()
	{
		vlnHeader("");
	}
	private void vlnHeader(string sUsing)
	{
		vlnHeader(sUsing,"");
	}
	private void vlnHeader(string sUsing,bool serialize)
	{
		vlnHeader(sUsing,"",serialize);
	}
	private void vlnHeader(string sUsing,string sDelegate)
	{
		vlnHeader(sUsing,sDelegate,true);
	}
	private void vlnHeader(string sUsing,string sDelegate,bool serialize)
	{
		if (_chkVolian){
%>// ========================================================================
// Copyright 2007 - Volian Enterprises, Inc. All rights reserved.          
// Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
// ------------------------------------------------------------------------
// $Workfile: $     $Revision: $                                           
// $Author: $   $Date: $                                                   
//                                                                         
// $History: $                                                             
// ========================================================================
<%
		}
%>
using System;
using System.Data;
using System.Data.SqlClient;
using Csla;
using Csla.Data;
using System.Configuration;
using System.IO;<%
		if (_chkPartCM)
		{
%>
using System.ComponentModel;<%
		}
%><%=sUsing%>
namespace <%=_nameSpace%>
{<%=sDelegate%>
	/// 
	///	<%=_className%> Generated by MyGeneration using the CSLA Object Mapping template
	/// <%
		if (serialize)
		{
%>
	[Serializable()]<%
		}
	}
	private bool IsPrimaryKey(IIndex ind)
	{
		IColumns colsi = ind.Columns;
		IColumns colsp = ind.Table.PrimaryKeys;
		if (colsi.Count != colsp.Count)return false;
		for(int i=0;i
		#region Collection
		private static List<<%=_className%>> _CacheList = new List<<%=_className%>>();
		protected static void AddToCache(<%=_className%> <%=LocalName(_className)%>)
		{
			if (!_CacheList.Contains(<%=LocalName(_className)%>)) _CacheList.Add(<%=LocalName(_className)%>); // In AddToCache
		}
		protected static void RemoveFromCache(<%=_className%> <%=LocalName(_className)%>)
		{
			while (_CacheList.Contains(<%=LocalName(_className)%>)) _CacheList.Remove(<%=LocalName(_className)%>); // In RemoveFromCache
		}
		private static Dictionary>> _CacheByPrimaryKey = new Dictionary>>();<%
		//ArrayList uniqueIndexes=UniqueIndexes(tbl);
		foreach(IIndex ind in uniqueIndexes)
		{
			string sBy = FormatColumns("{name}",ind.Columns,"_","");
%>
		private static Dictionary>> _CacheBy<%=sBy%> = new Dictionary>>();<%
		}
%>
		private static void ConvertListToDictionary()
		{
			while (_CacheList.Count > 0) // Move <%=_className%>(s) from temporary _CacheList to _CacheByPrimaryKey
			{
				<%=_className%> tmp = _CacheList[0]; // Get the first <%=_className%>
				string pKey = <%=pKey%>;
				if (!_CacheByPrimaryKey.ContainsKey(pKey))
				{
					_CacheByPrimaryKey[pKey] = new List<<%=_className%>>(); // Add new list for PrimaryKey<%
		foreach(IIndex ind in uniqueIndexes)
		{
			string sBy = FormatColumns("{name}",ind.Columns,"_","");
			string sKey = FormatColumns("tmp.{prop}.ToString()",ind.Columns," + \"_\" + ","");
%>
					_CacheBy<%=sBy%>[<%=sKey%>] = new List<<%=_className%>>(); // Add new list for <%=sBy%><%
		}
%>
				}
				_CacheByPrimaryKey[pKey].Add(tmp); // Add to Primary Key list<%
		foreach(IIndex ind in uniqueIndexes)
		{
			string sBy = FormatColumns("{name}",ind.Columns,"_","");
			string sKey = FormatColumns("tmp.{prop}.ToString()",ind.Columns," + \"_\" + ","");
%>
				_CacheBy<%=sBy%>[<%=sKey%>].Add(tmp); // Unique Index<%
		}
%>
				_CacheList.RemoveAt(0); // Remove the first <%=_className%>
			}
		}<%
		if (bInfo && AnyNotOneToOne(_workingTable)) // AddList function for infolist - Any non 1 to 1 relationships
		{
%>
		internal static void AddList(<%=_className%>List lst)
		{
			foreach (<%=_className%> item in lst) AddToCache(item);
		}<%
		}
%>
		protected static <%=_className%> GetCachedByPrimaryKey(<%=pKeysType%>)
		{
			ConvertListToDictionary();
			string key = <%=pKey2%>;
			if (_CacheByPrimaryKey.ContainsKey(key)) return _CacheByPrimaryKey[key][0];
			return null;
		}<%
		foreach(IIndex ind in uniqueIndexes)
		{
			string sBy = FormatColumns("{name}",ind.Columns,"_","");
			string sKey = FormatColumns("{local}.ToString()",ind.Columns," + \"_\" + ","");
			string sKeysType = FormatColumns("{ctype} {local}",ind.Columns,", ","");
			string sKeys = FormatColumns("{local}",ind.Columns,", ","");
%>
		protected static <%=_className%> GetCachedBy<%=sBy%>(<%=sKeysType%>)
		{
			ConvertListToDictionary();
			string key = <%=sKey%>;
			if (_CacheBy<%=sBy%>.ContainsKey(key)) return _CacheBy<%=sBy%>[key][0];
			return null;
		}<%
		}
%>
		#endregion<%
	}
	private void vlnBusinessMethods(IColumns Columns )
	{
%>
		#region Business Methods
		private string _ErrorMessage = string.Empty;
		public string ErrorMessage
		{
			get { return _ErrorMessage; }
		}<%
		vlnProperties(Columns);
		//vlnRelatedItems(Columns);
		vlnToString(Columns);
		vlnGetIDValue(_workingTable.PrimaryKeys);
%>
		#endregion<%
	}
	private string ParentCheck(IColumn col)  // 20070221 - Logic to check for parent value
	{
		IForeignKey pfk = FKParentFK(col.Table);
		if (pfk == null)return null;
		IColumn relCol = RelatedColumnF(col,pfk);
		if (relCol==null) return null;
		return FormatColumn("\r\n\t\t\t\tif (_" + ParentName(pfk) + " != null) return _" + ParentName(pfk) + ".{prop};",relCol); 
	}
	private void vlnProperties(IColumns Columns)
	{
		// Create all properties
		foreach(IColumn col in Columns)
		{
			bool bReadOnly = col.IsInPrimaryKey || col.IsAutoKey || col.IsComputed;
//			bool bRelatedObject = true;
			vlnIdentity(col);
//			string sParentCheck = ParentCheck(col);
//			if (sParentCheck != null)
//			{
//				bReadOnly=true;
//				bRelatedObject=false;
//			}
			// Need logic to handle parent child
			string sParentCheck="";
			if (IsRelObj(col))
				sParentCheck =FormatColumn("\r\n\t\t\t\tif ({!member} != null) {member} = {!member}.{!column};",col);
			vlnProperty(CSLAType( col ),MemberName(col)
				,PropertyName(col),InitializeValue( col ),GetDescription(col),bReadOnly || IsRelObj(col),col.IsInPrimaryKey,false,null,sParentCheck,null,null);
//			if (bRelatedObject)
			vlnRelObjProperty(col,bReadOnly,false);
		}
		// Add Foreign Key Properties - This should be controllable
//		foreach(IColumn field in Columns)
//		{
//			if (field.IsInForeignKey && field.IsInPrimaryKey)
//			{
				//A column that's in a fk and in the pk represents a fk relationship
				//from another table, a one-to-many relationship.  (This might be 
				//a bad assumption for a table with a composite primary key.)
				//... and then we have to add collections for the foreign tables.
				string sExtDirty="";
				string sExtValid="";
//				foreach( IForeignKey fk in field.ForeignKeys )
				Hashtable dicAlias = new Hashtable();
				foreach(IForeignKey fk in _workingTable.ForeignKeys)
				{
					if (fk.PrimaryTable == _workingTable){
						//string sAlias = GetAlias(dicAlias,fk.ForeignTable);
						string sAlias = GetAlias(fk);
//							string sList = _className + ClassesName( fk.ForeignTable );
							string sList = FKClassName(fk );
							string sLists = FKClassesName(fk );
							vlnProperty("int",MemberName(sList) + sAlias + "Count" ,sList + sAlias + "Count", " = 0;",
								"Count of " + sLists + " for this " + ClassName(_workingTable)  + Debug("20070501.3"),true,false,false,null,null,null,null);
						if (!IsPrimaryKey(fk)){
							//vlnProperty(sLists+sAlias,MemberName(sLists)+sAlias,sLists + sAlias,
							//" = " + sLists+sAlias + ".New();","Related Field" + Debug("20070501.2"),true,false,true,fk,null,null,null);
							vlnProperty(sLists+sAlias,MemberName(sLists)+sAlias,sLists + sAlias,
							" = null;","Related Field" + Debug("20070501.2"),true,false,true,fk,null,null,null);
							//sExtDirty += " || " + MemberName(sLists+sAlias) + ".IsDirty";
							//sExtValid += " && " + MemberName(sLists+sAlias) + ".IsValid";
							sExtDirty += string.Format(" || ({0} == null ? false : {0}.IsDirtyList(list))",MemberName(sLists+sAlias));
							// Added List 20100924
							sExtValid += string.Format(" && ({0} == null ? true : {0}.IsValidList(list))",MemberName(sLists+sAlias));
						} else {
							string sItem = ClassName(fk.ForeignTable);
							//vlnProperty(sItem+sAlias, MemberName("My" + sItem)+sAlias,"My" + sItem + sAlias,
							//" = My" + sItem+sAlias + ".New();","Related Field",true,false,true,fk,null,null);
							string sCheck = string.Format("\r\n\t\t\t\tif ({0} == null) {0} = {1}.New({2});",
								MemberName("My" + sItem)+sAlias, sItem, OneToOne(fk) ? "this" : FormatColumns("{member}",fk.PrimaryColumns,", ",""));
							vlnProperty(sItem+sAlias, MemberName("My" + sItem)+sAlias,"My" + sItem + sAlias,
							" = null;","Related Field" + Debug("20070501.1"),true,false,true,fk,sCheck,null,null);
							bool bReq = !fk.ForeignColumns[0].IsNullable;
							sExtDirty += string.Format(" || ({0} == null ? false : {0}.IsDirtyList(list))",MemberName("My" + sItem+sAlias));
							sExtValid += string.Format(" && ({0} == null ? true : {0}.IsValidList(list))",MemberName("My" + sItem+sAlias));
						}
					}
					else // 
					{
						if (IsPrimaryKey1(fk) && !IsPrimaryKey(fk)){
							bool bReq = !fk.ForeignColumns[0].IsNullable;
							string sClass = ClassName(fk.PrimaryTable.Name) + GetNewAlias(fk,fk);
							//sExtDirty += string.Format(" || ({0} == null? " + bReq.ToString().ToLower() + " : {0}.IsDirty)",MemberName("My" + sClass));
							//sExtValid += string.Format(" && ({0} == null? " + (!bReq).ToString().ToLower() + " : {0}.IsValid)",MemberName("My" + sClass));
							sExtDirty += string.Format(" || ({0} == null ? false : {0}.IsDirtyList(list))",MemberName("My" + sClass));
							sExtValid += string.Format(" && ({0} == null ? true : {0}.IsValidList(list))",MemberName("My" + sClass));
						}
					}
				}
				//if (sExtDirty!="")
				vlnDirty(sExtDirty);
				//if (sExtValid!="")vlnOverride("Valid",sExtValid);
				vlnValid(sExtValid);
//			}
//		}
	}
	private void vlnDirty(string sExtension)
	{
		if(sExtension == "")
		{
	%>
		public override bool IsDirty
		{
			get { return base.IsDirty; }
		}
		public bool IsDirtyList(List