Read Me For UncleGED Source Code

Original: December 28, 2003
Updated: July 31, 2005


Table Of Contents

Introduction

The  source code for the production release of UncleGED is written in Micrsoft Visual Basic 5/6. This was later ported over to VB.NET using the Upgrade Wizard (UncleGED rls 6). Once inside of VB.NET, I converted the main program over from a Windows (WinForms) application to a Command-Line (Console) application. I then went to the next step of porting the code to C#. The published source provided is written in C# and is labled UncleGED rls 7 (0.7). (See Why C#? under Notes On Source)


Requirements

UncleGED rls 7 is written in the .NET language C# and requires that the Microsoft .NET Framework 1.1 be installed on the user's PC. To ensure adequate performance, the .NET Framework has the following minimum and recommended system requirements for applications. Operating System Requirements The .NET Framework is supported on the following platforms.

Note On all these systems, Microsoft® Internet Explorer 5.01 or later and Microsoft® Windows® Installer 2.0 or later are also required. Hardware Requirements

*Or the minimum required by the operating system, whichever is higher.

To obtain and install the Microsoft .NET Framework 1.1, please visit this Microsoft site "How to Get the Microsoft .NET Framework"  (see also How To Build UncleGED)


How To Build UncleGED

To build UncleGED you will need to download and install the Microsoft .NET Framework 1.1 SDK or use Visual Studio .NET 2003.

To build from the command line use the make.bat file or enter from the command line:

csc /out:uged.exe /t:exe *.cs /debug /r:System.dll;System.Data.dll;System.XML.dll

The UncleGED source consists of the following files:


What To Do Next


Using UncleGED 7

Now A Command-line Program

Unlike previous versions, Uncle GED 7 is console-based program that is designed to be run from the DOS command-line. It does not present a standard Windows user-interface. Some user's may find this a little too retro for their tastes, however Uncle GED 7 is very easy to use and is much more flexible than previous versions.

Uncle GED was originally designed to do one thing- take the input from a GEDCOM file and output the data found in the GEDCOM file into a series of HTML files. Subsequent versions of UncleGED added some little extras along the way, but it primary purpose remained the same: GEDCOM-to-HTML.

In a sense the command-line version of Uncle GED goes back to the basics of its original purpose with all of the fixes and enhancements that were added into versions 2 through 5. Gone, however, are some of the side enhancements such as the catalog feature and the book feature.

To use Uncle GED you simply open up a command prompt window in the UncleGED directory and type uged followed by the name of the gedcom file.

Examples:

uged /f:gedcom\abigged.ged
or
uged /f:"c:\program files\uncleged\uncleged6\gedcom\asmallged.ged"

Note the double-quotes around the file path and name in the second example. This is required if there is a space in the path (as in "program files") The file path and file name can be any valid file path and name.

If you had a GEDCOM file called myged.ged located in the ancestors directory on drive D: you could enter...
uged /f:d:\ancestors\myged.ged ...
and UncleGED would open and process that file.

HTML Output

Where's does the output go? By default it goes into a "html" sub-directory under the UncleGED directory. By default this would be ".\html". However this directory can be changed to any valid directory by editing in the uged_config.xml file and changing the "HtmlPath" entry.

Custom Configurations

A new feature introduced in Uncle GED 7 is the ability to specify a custom configuration. You can now copy and modify the uged_config.xml file and then tell Uncle GED to use a different configuration. This is done by adding the new config file to the command line.

Example: process "d:\ancestors\myged.ged" and use mycustom_config.xml as the config file:
uged /f:d:\ancestors\myged.ged /c:".\mycustom_config.xml"

What this does is allow you to create batch files to process your gedcom into html using a specific configuration. You could then add to these batch files the necessary intructions to upload the HTML output to your website via FTP.


Command-line Switches

/f[GEDCOM FILE]
/c[alternate XML CONFIG FILE to use]
/w create a default XML config file

BOOLEAN OPTIONS - These act as switches that reverses the default setting
-ac - AddUserCopyright (default:False)
-ak - AddKeywords (default:True)
-as - AddSurnameCount (default:True)
-cl - ChronoLinks (default:True)
-cp - CreateChronoPage (default:True)
-de - DoDateEstimation (default:False)
-dm - DisplayMRIN (default:True)
-dr - DisplayRIN (default:True)
-gf - CreateGendexFile (default:False)
-hr - HiLiteMostRecent (default:True)
-io - IgnoreOccupations (default:True)
-ld - LocDisplayEventDates (default:False)
-lo - LocReverseOrder (default:True)
-lp - CreateLocPage (default:True)
-lr - CreateListReport (default:True)
-lt - OccLocEqualsOccText (default:False)
-mi - MostRecentOnIndex (default:True)
-mp - MostRecentOnPage (default:True)
-op - CreateOccupationsPage (default:True)
-pr - Privacy (default:True)
-sc - SurnamesAllCaps (default:True)
-sp - CreateStatsPage (default:True)
-ub - UseBackground (default:True)
-ur - UseBanner (default:True)
-wa - WarnNonAnsi (default:False)
-xl - ExcludeLivingIndividualsAfterBirthCutOff (default:False)
-xn - ExcludeNotes (default:False)

COMMAND OPTIONS - These require additional input
-b[BackgroundFile] - BackgroundFile
-c[ChronoCutOff] - ChronoCutOff
-e[AuthorsEmail] - AuthorsEmail
-h[HtmlPath] - HtmlPath
-n[AuthorsName] - AuthorsName
-p[FamFilePrefix] - FamFilePrefix
-r[BannerFile] - BannerFile
-s[0|1|2] - LocEstimateMethod
-t[MainPageTitle] - MainPageTitle
-u[AuthorsUrl] - AuthorsUrl
-y[BirthCutOffYears] - BirthCutOffYears

Example configuring UncleGED from the command line:

uged /fmyged.ged -n"Joe Blow" -uhttp://mywebsite.com/~joeb -ac


Uncle GED Configuration Options

Configuration options for UncleGED 7 are stored in a XML file which by default is called uged_config.xml. You can create a default config file from the command-line by running UncleGED with the /w option.

Data

Option

Default

Description

Privacy

TRUE

Mark information for individuals currently living as private. With this option on any data (notes, etc.) for individual with a valid birth date less than 80 years will be marked as private. [private]. However to best address privacy issues it better to filter your GEDCOM at the time that you export it from your genealogy software.

 

AuthorsEmail

{blank}

The email address of the GEDCOM's author

AuthorsName

{blank}

The GEDCOM's author's name

AddUserCopyright

FALSE

When this option is set to TRUE, Uncle GED displays the Author's name and email within a copyright statement at the bottom of each page.

 

DisplayMRIN

FALSE

Display MRIN after marriage - When this option is selected, Uncle GED displays the MRIN (marriage reference number) in the title of the family HTML page.

 

DisplayRIN

FALSE

Display RIN after name - When this option is selected, Uncle GED displays the RIN (individual reference number) after eachindividuals name.

 

AuthorsUrl

{blank}

A link to this page will be added to the table contents page (index.htm). Prior to rel. 4.01 this pointed to ../index.htm. You may now link to any page that you wish. if left blank, the link will not be added to the page.

 

CreateGendexFile

FALSE

When this option is selected, Uncle GED creates a GENDEX file called GENDEX.txt in the html directory. For more information on GENDEX files and their purpose visit Welcome to GENDEX .

 

MainPageTitle

Family Page

As of UncleGED 4.01 you may now specify the main page title.

 

Images

Option

Default

Description

UseBackground

FALSE

Use background image (images/ug_bkgrd.gif). With this option the ug_bkgrd.gif file located normally “C:\PROGRAM FILES\UNCLEGED\HTML\IMAGES” will be used as the background for all HTML files produced by UncleGED. NOTE: As of UncleGED 4.01, you may specify any background image and location for that image that you wish.

 

UseBanner

FALSE

Use banner image (images/ug_banner.gif). With this option the ug_banner.gif file located normally “C:\PROGRAM FILES\UNCLEGED\HTMl\IMAGES” will be used as the banner for all HTML files produced by UncleGED. NOTE: As of UncleGED 4.01, you may specify any banner image and location for that image that you wish. The size that I used for my banner is 224 X 38, but you may use any size that you like.

 

BackgroundFile

images/ug_bkgrd.gif

Relative or absolute URL location of background file

 

BannerFile

images/ug_banner.gif

Relative or absolute URL location of banner file

 

Processing

Option

Default

Description

ExcludeNotes

FALSE

Excludes notes from HTML pages. With option set to true any notes found in the GEDCOM file are excluded from the HTML pages

 

AddKeywords

FALSE

Surnames As Keywords On Index Page. When this option is selected, Uncle GED adds all surnames found with a count greater than five to the meta sections of the index page….

 

WarnNonAnsi

FALSE

There is a optional setting in UncleGED that warns about non-ANSI files The warning reads: "WARNING: This file has been saved in a character format other than ANSI and as a result some characters may not translate correctly. While UncleGED should not have any problem processing the file, it works best with GEDCOM files saved in the ANSI character format." Also, UncleGED cannot process GEDCOM files that do not contain carriage returns and line feeds (CR/LF). Some GEDCOM files downloaded from the internet may only contain line feed characters. If you try to open one of these files with UncleGED you will see the following message: "File is possibly corrupt and can not be read. It is missing carriage returns." TIP: Try opening the file with a word processor and re-saving the file as text only.

 

AddSurnameCount

FALSE

Add Surname Count to Surnames Page. When this option is selected, Uncle GED adds a count to each surname displayed on the surname page.

 

CreateListReport

FALSE

When this option is set to TRUE, Uncle GED creates a listing file when HTML pages are created. This listing file is a comma-delimited file that lists the individual's name, their RIN, and which HTML they appear in. Look for list.txt in the UncleGED application directory.

 

CreateStatsPage

FALSE

When this option is selected, Uncle GED creates a statistics page  that lists the statistics for the GEDCOM file. Look for stats.htm in the HTML directory.

 

CreateChronoPage

FALSE

Create Chronology Of Events Page - When this option is selected, Uncle GED will create a Chronology of Events page.  

 

ChronoCutOff

1900

Last date (year) for the chronology listings. Any year after the ChronoCutOff date will not be listed in the chronology.

 

FamFilePrefix

fam

As of UncleGED 5, the "family file prefix" feature allows the user to designate a 3 character naming convention for the files. This is useful if you want to split your maternal and paternal lines. For example I have one set of files that follow the pattern of debxxx.html for my father's side and another set with the pattern dobxxx.html for my mother's. If you set this three character prefix to something other than "fam" (for example "deb") then all famxxx.html files become debxxx.html and the other files will have the family file prefix prepended to them (for example locations.html becomes deb_locations.html and so forth).

 

ChronoLinks

TRUE

Adds links for the family pages to the chronology page.

 

SurnamesAllCaps

FALSE

Display Surnames In Upper-Case

 

MostRecentOnIndex

TRUE

Display Last Update For Individual On Index - Besides displaying the individual's name and birth date on the index, Uncle GED optionally displays the last date that this individuals record was updated.

 

MostRecentOnPage

TRUE

Display Most Recent Change Date On Family Pages - When this option is selected, Uncle GED displays the most recent change date at the bottom of each family page. Example: The most recent update of information contained on this page was on: 15 July 2001 The date displayed here is determined by examining the change dates stored in the GEDCOM file for each of the individuals displayed uniquely on this page.

 

HiLiteMostRecent

TRUE

 Make Bold Most Recent Updates On Index - When this option is selected along with the option described above, Uncle GED will display all changes made in the last 90 days in formatting in bold. NOTE: The change dates are provided in GEDCOM files created with PAF and may not be in files produced by other software vendors. For change dates UncleGED looks for something like the following in the GEDCOM file: 1 CHAN 2 DATE 24 Feb 2002 3 TIME 12:34:12

 

CreateLocPage

FALSE

There are a number of options available for creating a listing of locations and place names. An example of this page can be found at Example Locations Page. Selecting the "Create Locations Page" option will not only create this style of HTML page, but will also create a file called "loc_report.txt". The "loc_report.txt" provides a listing of all locations and place names found in your GEDCOM file and can be useful in locating problems with place names in the GEDCOM. Setting CreateLocPage  to true creates the files listed above.

 

LocDisplayEventDates

FALSE

Display Event Dates On Locations Page - displays a date (if available) between the individuals name and the event description.

 

LocEstimateMethod

0

Estimated Locations - Although not a part of the GEDCOM specification, there is a format used by the LDS in Ancestral files for entering "estimated" locations and that is to enter the location surrounded by the "<" and ">" characters. UncleGED automatically converts the "<" and ">" characters to "[" and "]" characters. The following options regarding estimated locations are as follows: 0. Do Not List Estimated Locations - locations surrounded by the "[" and "]" characters are not displayed. 1. Treat Estimated Locations The Same As Actual Locations - the "[" and "]" characters are dropped from the estimated locations and all locations are displayed together. 2. List Estimated Locations At Bottom Of Page - locations surrounded by the "[" and "]" characters are retained and are displayed at the bottom of the page.

 

LocReverseOrder

TRUE

List Locations In Reverse Order - when selected an entry such as "Houston, Harris, Texas" will be displayed as "Texas, Harris, Houston".

 

IgnoreOccupations

FALSE

Do Not Print Occupations On Locations Page - Occupation listing are excluded from the Locations page (If the source of your GEDCOM file is FTW (Family Tree Maker) then set this option to TRUE; otherwise leave FALSE).

 

CreateOccupationsPage

FALSE

Create Occupations Page - creates the occupation.html file.

 

OccLocEqualsOccText

FALSE

Occupation Location Equals Occupation Text - This rather wordy option basically means that both the location and the description of the occupation are within the same field in the GEDCOM file. (If the source of your GEDCOM file is FTW (Family Tree Maker) then set this option to true; otherwise leave cleared ).

 

HtmlPath

{app path\}html

Specify the directory to which the family pages and other HTML files will be written.

 

DoDateEstimation FALSE

When this option is selected UncleGED with attempt estimate the birth date for individuals without birthdates.

 

ExcludeLivingIndividualsAfterBirthCutoff FALSE

When this option is selected UncleGED will exclude any individual from final processing if the individual's birthdate is less than BirthCutoffYears from the current year. In other words if the  BirthCutoffYears is set to 80 and the current year is 2003 then any individual born in or after 1923 will be excluded from the HTML pages created.

 

BirthCutoffYears 80 See the setting ExcludeLivingIndividualsAfterBirthCutoff

The following options are no longer supported or used by Uncle GED 7: DisplayOptionBeforeBuild, AppendCatalog, TabDelimit, CatalogPath, GedcomPath and BookPath.


Notes On Source Code

Why C#?

The simple answer is that I wanted / needed to learn C# and the best way I could think of doing it was to take an existing program written in VB that I was very familar with and attempt to port it to C#.

Why make the source available?

My main reason for doing is in the hope that someone might aide me in creating versions of UncleGED that produce HTML output in alternate languages (French, German, Spanish, etc.)

Porting to C#

For the initial port I used a free VB to C# translation tool called  BabelFisken by Lars Johansson. This resulted in at least translating the majority of the code over from VB.NET to C#, however there was a considerable amount of clean-up required. Here is a list of some of the issues that I had to deal with:

After a few days of hacking I was finally able to get the code to compile and successfully run. Porting UncleGED over to C# also kicked over a hornet's nest (so to speak) and unleashed a whole slew of "hidden" bugs in UncleGED. A lot of this involved "errors" that were being ignored due the use of On Error Resume Next in the VB versions. 

I ran a series of tests on the code using GEDCOM files exported from LEGACY, PAF, FTW, and TMG and everything appears to be in working order; however I'm convinced that there are few more yet uncovered bugs in this source, but then if there weren't any bugs in the code what fun would there be in playing with this code? :).


Basic Program Flow 

  1. Process the configuration settings .
  2. Parse in the contents of the GEDCOM file line-by-line and store the data in various objects (Individual, Family, etc.) .
  3. Further process (prep) the data. 
  4. Build the HTML pages.


Notes On UncleGED Configuration Settings

Internally the configuration settings are stored in the "UgedApplicationSettings" class.

Originally in the VB6 version of UncleGED configuration settings were saved in the Windows registry (only because Microsoft told me that was the way things should be done c.1995). This was later changed to using a good old INI file. When going to .NET, rather than use the .NET app.config to store configuration settings (or revert back to reading/writing the Registry), I found that a "quick trick" was to make the Configuration class serializable and this allowed for easily "dumping" the contents of the class out to an XML file.

Here is an example of how this is done in the VB.NET version:

Public TheApp As New UgedApplicationSettings
.....
'(Populate the configuration properties)
.....
   'method for saving the app settings to an XML file
   Public Sub SaveXmlSettings(ByRef sXmlConfig As String)
      Dim XmlS As New XmlSerializer(GetType(UgedApplicationSettings))
      Dim fStream As New IO.FileStream(sXmlConfig, IO.FileMode.Create)
      XmlS.Serialize(fStream, TheApp)
      fStream.Close()
      fStream = Nothing
      XmlS = Nothing
   End Sub

   'method for reading the app settings from an XML file	
   Public Function LoadXmlSettings(ByRef sXmlConfig As String) As UgedApplicationSettings
      Dim myAppSettings As UgedApplicationSettings

      Try
         Dim XmlS As New XmlSerializer(GetType(UgedApplicationSettings))
         Dim fStream As New IO.FileStream(sXmlConfig, IO.FileMode.Open)
         myAppSettings = CType(XmlS.Deserialize(fStream), uged.UgedApplicationSettings)
         fStream.Close()
         fStream = Nothing
         XmlS = Nothing
      Catch ex As Exception
         myAppSettings = Nothing
      End Try

      Return myAppSettings

   End Function

Here is that same code in C#

		UgedApplicationSettings configSettings =  new UgedApplicationSettings();
.....
//(Populate the configuration properties)
.....
		public static void SaveXmlSettings(string  sXmlConfig, UgedApplicationSettings ConfigSettings) 
		{
			XmlSerializer  XmlS = new XmlSerializer(typeof(UgedApplicationSettings));
			FileStream  fStream = new FileStream(sXmlConfig, FileMode.Create);
			XmlS.Serialize(fStream, ConfigSettings);
			fStream.Close();
		}

		public static UgedApplicationSettings LoadXmlSettings(string sXmlConfig) 
		{
			UgedApplicationSettings configSettings;

			try 
			{
				XmlSerializer  XmlS = new XmlSerializer(typeof(UgedApplicationSettings));
				FileStream  fStream = new FileStream(sXmlConfig, FileMode.Open);
				configSettings = (UgedApplicationSettings)XmlS.Deserialize(fStream);
				fStream.Close();
				fStream = null;
				XmlS = null;
			} 
			catch
			{
				configSettings = null;
			}

			return configSettings;

		}


Notes On Parsing The GEDCOM

C# equivalents of VB string function

I found the first few of these methods on the web (see the article  Overloading strings in C#) and added a few other VB/VB.NET type functions that I needed to replace in UGed keeping in mind that I could have just have easily re-wrote the portion of the code that used a VB function such as Trim(string) with string.Trim(), but in the interest of time and the desire to just get the damn-thing to compile and run, I elected to create replacement functions so I could just use "search-and-destroy" to replace the original VB function calls with their C# replacements.

using System;

namespace UGed
{

	public class StringFuncs
	{
		public StringFuncs()
		{
			//constructor
		}

		public string Left(string inputString, int strLen)
		{
			if (inputString.Length > strLen)
			{
				string retValue = inputString.Substring(0, strLen);
				return retValue;
			} 
			else 
			{
				return inputString;		 
			}
		} 

		public string Right(string inputString, int strLen)
		{
			if (inputString.Length > strLen)
			{
				string retValue = inputString.Substring(inputString.Length - strLen, strLen);
				return retValue;
			}						
			else 
			{
				return inputString;		 
			}

		}

		public string Mid(string inputString, int startIndex, int strLen)
		{
			string retValue = inputString.Substring(startIndex - 1, strLen);
			return retValue;
		}

		public string Mid(string inputString, int startIndex)
		{
			string retValue = inputString.Substring(startIndex - 1);
			return retValue;
		}

		public int Len(string inputString)
		{
			return inputString.Length;
		}

		public string UCase(string inputString)
		{
			return inputString.ToUpper();
		}

		public string LCase(string inputString)
		{
			return inputString.ToLower();
		}

		public int InStr(string String1, string String2)
		{

			int retValue = String1.IndexOf(String2) + 1;
			return retValue;
		}

		public int InStr(int Start, string String1, string String2)
		{

			int retValue = String1.IndexOf(String2, Start - 1) + 1;
			return retValue;
		}

		public string Trim(string inputString)
		{
			try
			{
				if (inputString.Length > 0)
				{
					return inputString.Trim();
				} 
				else 
				{
					return "";
				}
			} 
			catch
			{
				return "";
			}
		}

		public DateTime DateValue(string dateString)
		{
			DateTime dateValue = System.DateTime.Parse(dateString);
			return dateValue;
			
		}


		public bool IsDate(string inValue)
		{
			bool bValid;
			try 
			{
				DateTime myDT = DateTime.Parse(inValue);
				bValid = true;
			}
			catch //(FormatException e) 
			{
				bValid = false;
			}
				return bValid;
		}


	}
}


Notes On Data Objects

Replacing VB Collection Classes in C#

A collection is an object that contains a set of related objects. It is a class module that exists solely to group all the objects of another class.

Here is the Individuals collection class as written in VB6 (slightly modified from the collection class as generated by the VB Class Builder add-in):

Option Explicit

Private mCol As Collection

Public Function Add(NewIndividual As Individual) As Boolean
   Dim sKey As String
   On Error GoTo AddIndividual_EH
   Add = True
   sKey = NewIndividual.ID
   'the next line will fail if the key is duplicated
   mCol.Add NewIndividual, sKey
   
Exit Function
AddIndividual_EH:
   Add = False
End Function

'the Get property allows the Individual object to be retrieved
'by using either the string Key or by using a numeric index
'(ex. theIndividual = MyIndividuals("@I1@") or theIndividual = MyIndividuals(0))
Public Property Get Item(vntIndexKey As Variant) As Individual
  Set Item = mCol(vntIndexKey)
End Property

Public Property Get Count() As Long
    Count = mCol.Count
End Property

Public Sub Remove(vntIndexKey As Variant)
    mCol.Remove vntIndexKey
End Sub

'NewEnum allows for accessing the Indvidual objects using For Each
Public Property Get NewEnum() As IUnknown
    Set NewEnum = mCol.[_NewEnum]
End Property

Private Sub Class_Initialize()
    Set mCol = New Collection
End Sub

Private Sub Class_Terminate()
    Set mCol = Nothing
End Sub

Here is that same collection class after upgrading to VB.NET using the Upgrade Wizard:

Imports System
Imports Microsoft.VisualBasic
					
Friend Class Individuals
   Implements System.Collections.IEnumerable

   Private mCol As Collection 'a VB Collection

   Public Function Add(ByRef NewIndividual As Individual) As Boolean
      Dim sKey As String
      Try
         sKey = NewIndividual.ID
         mCol.Add(NewIndividual, sKey)
         Return True
      Catch ex As Exception
         Return False
      End Try
   End Function

   'the Item property allows the Individual object to be retrieved
   'by using either the string Key or by using a numeric index
   'Note that it is declared as default so you do not need to include  
   '"Item" when using:
   '(ex. theIndividual = MyIndividuals("@I1@") or theIndividual = MyIndividuals.Item("@I1@"))
   Default Public ReadOnly Property Item(ByVal vntIndexKey As Object) As Individual
      Get
         Item = CType(mCol.Item(vntIndexKey), Individual)
      End Get
   End Property

   Public ReadOnly Property Count() As Integer
      Get
         Count = mCol.Count()
      End Get
   End Property

   'GetEnumerator allows for accessing the Indvidual objects using For Each
   Public Function GetEnumerator() As System.Collections.IEnumerator _
     Implements System.Collections.IEnumerable.GetEnumerator
      GetEnumerator = mCol.GetEnumerator
   End Function

   Public Sub Remove(ByRef vntIndexKey As Integer)
      mCol.Remove(vntIndexKey)
   End Sub

   Public Sub Remove(ByRef vntIndexKey As String)
      mCol.Remove(vntIndexKey)
   End Sub

   Public Sub New()
      MyBase.New()
      mCol = New Collection
   End Sub

   Protected Overrides Sub Finalize()
      MyBase.Finalize()
   End Sub
End Class


Now here is the same collection class written in C# (this is a variation of  the C# collection class(es) described in Franceso Balena's article Create .NET Custom Collections):

 
using System; 
using System.Collections; 
using System.Collections.Specialized; 

	public class Individuals: System.Collections.Specialized.NameObjectCollectionBase
	{
		Hashtable ht = new Hashtable();

		public bool Add(Individual NewIndividual) 
		{
			string  key;
			try 
			{
				key = NewIndividual.ID;
				ht.Add(key, null); //will fail if duplicate key 	
				this.BaseAdd(key, NewIndividual);
				return true;
			} 
			catch 
			{
				return false;
			}
		}

		public void Clear()
		{
			this.BaseClear();
		}

		// the Remove method that takes a string key
		public void Remove(string key)
		{
			this.Remove(key);
		}

		// the Remove method that takes a numeric index
		public void Remove(int index)
		{
			this.Remove(index);
		}

		// the Item property that takes a string key
		public Individual this[string key]
		{
			get { return (Individual) this.BaseGet(key); }
			set { this.BaseSet(key, value); }
		}

		// the Item property that takes a numeric index
		public Individual this[int index]
		{
			get { return (Individual) this.BaseGet(index); }
			set { this.BaseSet(index, value); }
		}

		public new IEnumerator GetEnumerator()
		{
			// return an instance of the inner enumerator object
			return new myEnumerator(this);
		}

		private class myEnumerator: IEnumerator
		{
			// a reference to the parent object
			Individuals parent;
			Individual currObject;
			int index = 0;

			public myEnumerator(Individuals fc)
			{
				this.parent = fc;
			}

			public bool MoveNext() 
			{
				if (index < parent.Count) 
				{
					currObject = parent[index];
					index++;
					return true;
				}
				else 
				{
					index = 0;
					return false;
				}
			}

			public object Current
			{
				get
				{
					// just return the line read by MoveNext
					return currObject;
				}
			}

			public void Reset() 
			{
				// this method is never called and can be left empty
			}
		}

	}