/// <summary>
		/// A private method to create a precision model object based on the type in
		/// the Run object that is passed in.
		/// </summary>
		/// <param name="r">The Run object.</param>
		/// <returns>UrbanScience.Geographic.Geometries.PrecisionModel</returns>
		private Geotools.Geometries.PrecisionModel CreatePrecisionModel(Run r)
		{
			// if the type is FLOATING, call the constructor with no parameters...
			if(r.PrecisionModel.Type == "FLOATING")
			{
				return new Geotools.Geometries.PrecisionModel();
			}
			else
			{
				// otherwise call the constructor and pass in the attributes of the precision model...
				return new Geotools.Geometries.PrecisionModel(double.Parse(r.PrecisionModel.Scale), 
																			 double.Parse(r.PrecisionModel.OffSetX),
																			 double.Parse(r.PrecisionModel.OffSetY));
			}
		}
		/// <summary>
		/// This method builds the entire Run object for the current test file.
		/// The Run object has a description, a precision model, and a number of 
		/// test cases. Each test case contains a number of tests which each contain
		/// one operation to perform.
		/// </summary>
		/// <param name="tr">
		/// tr is an XmlTextReader object that already contains the XML from the test file.
		/// </param>
		/// <returns>
		/// Returns a complete Run object to the caller.
		/// </returns>
		private Run BuildRunObject(XmlTextReader tr)
		{
			// make sure the XmlTextReader is not null...
			if(tr == null)
			{
				throw new System.ArgumentNullException("The XML reader is null!");
			}
			// make sure we know where we are in the Xml file. We should be at
			// the first run element...
			else if(tr.Name != "run")
			{
				throw new System.ArgumentException("The XML reader is not pointing to the <run> element");
			}

			// Get Run object to build...
			Run tmpRun = new Run();
			
			// The XmlTextReader comes in to this method "pointing" to the 
			// <run> element so do another read to look for the description element...
			tr.Read();

			// make sure the current node is an element...
			if(tr.NodeType == XmlNodeType.Element)
			{
				// we're looking for the description node of the run...
				if(tr.Name == "desc")
				{
					// if the name is desc, then we have a description
					// for the run. So do another read, make sure it is
					// a text node and set the description field in the Run
					// object...
					tr.Read();
					// make sure the current node is text...
					if(tr.NodeType == XmlNodeType.Text)
					{
						// if it is text, then grab
						tmpRun.Description = tr.Value;
						// do 2 more reads to move to the precisionModel node...
						tr.Read();
						tr.Read();
					}
				}
			}
			
			// if there is no description, then the next node should be
			// the precision model for the run. Check to make sure...
			if(tr.Name == "precisionModel")
			{
				// Get some variables to hold the attributes of the precision model...
				string pmType = "";
				string pmScale = "";
				string pmOffSetX = "";
				string pmOffSetY = "";
											
				// make sure the node has attributes...
				if (tr.HasAttributes)
				{
					// move through the attributes and store the values in
					// the variables...
					while (tr.MoveToNextAttribute())
					{
						if(tr.Name == "type")
						{
							pmType = tr.Value;
						}
						else if(tr.Name == "scale")
						{
							pmScale = tr.Value;
						}
						else if(tr.Name == "offsetx")
						{
							pmOffSetX = tr.Value;
						}
						else if(tr.Name == "offsety")
						{
							pmOffSetY = tr.Value;
						}
					}
				}
				// Add the precision model to the Run object...
				tmpRun.SetPrecisionModel(pmType, pmScale, pmOffSetX, pmOffSetY);
			}
			// return the Run object...
			return tmpRun;
		}
		/// <summary>
		/// A private method to extract the information contained in the Run object
		/// and return.
		/// </summary>
		/// <param name="r">The Run object from which to extract the information.</param>
		/// <returns>A string containing the information about the Run object passed in.</returns>
		private string GetRunInformation(Run r)
		{
			// Extract the information for the current Run in a string and return it...
			// The XML test file associated with this Run object...
			string temp = "Filename: " + r.Filename + "\n";
			// The description for the Run...
			temp += "Run description: " + r.Description + "\n";
			// The number of TestCase objects in this run...
			temp += "Total test cases in this run: " + r.TestCaseCount + "\n";

			// count all the tests in the Run...
			long totalTests = 0;
			foreach(TestCase tc in r)
			{
				totalTests += tc.TestCount;
			}
			
			// add the number of tests in the run to the return string...
			temp += "Total tests in this run: " + totalTests.ToString() + "\n";

			// return the string...
			return temp;
		}
		/// <summary>
		/// ReadTestFile starts the process of building the Run opject by creating
		/// the Run and XmlTextReader objects. It then opens the XML file via the XmlTextReader
		/// and does a read on the XmlTextReader
		/// object to position the current node to the first run element. It then calls
		/// the BuildRunObject private method to build the Run object. It continues to read
		/// the XML file finding each case element and the calls the private method BuileTestCase.
		/// After each TestCase object is built, it is added to the Run object.
		/// </summary>
		/// <param name="fileName">
		/// fileName contains the complete path to the XML test file.
		/// </param>
		/// <returns>
		/// Returns a Run object containing all the test cases, geometries, tests, and operations
		/// from the XML test file.
		/// </returns>
		public Run ReadTestFile(string fileName)
		{
			// Verify the parameter...
			if(fileName == "")
			{
				throw new System.ArgumentException("The XML filename is empty!");
			}
			if(fileName == null)
			{
				throw new System.ArgumentNullException("The XML filename is null!");
			}
			if(!File.Exists(fileName))
			{
				throw new System.ArgumentException("The XML file does not exist!");
			}

			// Get a Run object to hold the information and return
			// to caller...
			Run tmpRun = new Run();
			
			// Get an XmlTextReader object to read the file...
			XmlTextReader tr = new XmlTextReader(fileName);
			// Turn off the whitespace handling...
			tr.WhitespaceHandling = WhitespaceHandling.None;

			// start reading the file...
			while(tr.Read())
			{
				// make sure the node type is an element...
				if(tr.NodeType == XmlNodeType.Element)
				{
					// if we're at the run element, build the Run object...
					if(tr.Name == "run")
					{
						tmpRun = BuildRunObject(tr);
					}
					// if we're at a case element, build the test case...
					else if(tr.Name == "case")
					{
						TestCase tc = BuildTestCase(tr);
						tmpRun.AddTestCase(tc);
					}
				}
			}
			
			// return the complete Run object...
			return tmpRun;
		}