Commits

Nerzhul500 committed fb91d44

Fixed crash on invalid sentence received.
Code cleanup.

  • Participants
  • Parent commits a473f41

Comments (0)

Files changed (7)

File Waymex.GpsLibrary.sln

-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Waymex.GpsLibrary - v40", "Waymex.GpsLibrary\Waymex.GpsLibrary - v40.csproj", "{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}"
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.30324.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Waymex.GpsLibrary", "Waymex.GpsLibrary\Waymex.GpsLibrary.csproj", "{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}"
 EndProject
 Global
-	GlobalSection(TeamFoundationVersionControl) = preSolution
-		SccNumberOfProjects = 2
-		SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
-		SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs35
-		SccLocalPath0 = .
-		SccProjectUniqueName1 = Waymex.GpsLibrary\\Waymex.GpsLibrary\u0020-\u0020v40.csproj
-		SccProjectName1 = Waymex.GpsLibrary
-		SccLocalPath1 = Waymex.GpsLibrary
-	EndGlobalSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug Retail|x86 = Debug Retail|x86
-		Debug Trial|x86 = Debug Trial|x86
-		Debug|x86 = Debug|x86
-		Release Retail|x86 = Release Retail|x86
-		Release Trial|x86 = Release Trial|x86
-		Release|x86 = Release|x86
+		Debug Retail 4.0|x86 = Debug Retail 4.0|x86
+		Debug Trial 4.0|x86 = Debug Trial 4.0|x86
+		Release Retail 4.0|x86 = Release Retail 4.0|x86
+		Release Trial 4.0|x86 = Release Trial 4.0|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Debug Retail|x86.ActiveCfg = Debug Retail 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Debug Retail|x86.Build.0 = Debug Retail 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Debug Trial|x86.ActiveCfg = Debug Trial 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Debug Trial|x86.Build.0 = Debug Trial 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Debug|x86.ActiveCfg = Debug Retail 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Debug|x86.Build.0 = Debug Retail 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Release Retail|x86.ActiveCfg = Release Retail 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Release Retail|x86.Build.0 = Release Retail 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Release Trial|x86.ActiveCfg = Release Trial 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Release Trial|x86.Build.0 = Release Trial 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Release|x86.ActiveCfg = Release Retail 4.0|x86
-		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Release|x86.Build.0 = Release Retail 4.0|x86
+		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Debug Retail 4.0|x86.ActiveCfg = Debug Retail 4.0|x86
+		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Debug Retail 4.0|x86.Build.0 = Debug Retail 4.0|x86
+		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Debug Trial 4.0|x86.ActiveCfg = Debug Trial 4.0|x86
+		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Debug Trial 4.0|x86.Build.0 = Debug Trial 4.0|x86
+		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Release Retail 4.0|x86.ActiveCfg = Release Retail 4.0|x86
+		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Release Retail 4.0|x86.Build.0 = Release Retail 4.0|x86
+		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Release Trial 4.0|x86.ActiveCfg = Release Trial 4.0|x86
+		{BF382DB4-F177-4795-8BD6-0BE2B76D53CD}.Release Trial 4.0|x86.Build.0 = Release Trial 4.0|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

File Waymex.GpsLibrary.sln.DotSettings

+<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
+	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="m_" Suffix="" Style="aaBb" /&gt;</s:String></wpf:ResourceDictionary>

File Waymex.GpsLibrary/Gps/ExceptionOccurredEventArgs.cs

+using System;
+using Waymex.Gps.Nmea;
+
+namespace Waymex.Gps
+{
+  public class ExceptionOccurredEventArgs : EventArgs
+  {
+    public Exception Exception { get; private set; }
+
+    public ExceptionOccurredEventArgs(Exception exception)
+    {
+      Exception = exception;
+    }
+  }
+}

File Waymex.GpsLibrary/Gps/Nmea/SerialLink.cs

         internal SerialLink()
         {
             //m_commPort.DataReceived += new SerialDataReceivedEventHandler(object obj, SerialErrorReceivedEventArgs args);
-            m_commPort.DataReceived+=new SerialDataReceivedEventHandler(m_commPort_DataReceived);
+            m_commPort.DataReceived+=m_commPort_DataReceived;
         }
         internal void Open()
         {

File Waymex.GpsLibrary/Gps/NmeaDevice.cs

 using System;
+using System.Diagnostics;
+using System.Globalization;
 using System.IO;
-using System.Diagnostics;
 using Waymex.Gps.Nmea;
-using System.Globalization;
-using System.ComponentModel;
-using System.Runtime.InteropServices;
 using Waymex.Security;
-
-
 #if(!CF)
 using Waymex.Diagnostics;
+
 #endif
 
 namespace Waymex.Gps
 {
+  /// <summary>
+  ///   This class allows acces to a connected NMEA device. The class exposes a single event
+  ///   that fires when a valid NMEA sentence is received from the NMEA device.
+  ///   The following Sentence types are supported with specific typed objects;
+  ///   BOD, GGA, GLL, GSA, GSV, RMB, RMC, WPL, PGRMC, PGRME, PGRMM, PGRMZ, PSLIB.
+  ///   Other sentence type are accessed via a generic sentence type.
+  /// </summary>
+  /// <example>
+  ///   C#
+  ///   <code><![CDATA[
+  ///  
+  ///  // Register the event, typically in Form_Load
+  ///  gps.ReceiveSentence += new EventHandler<ReceiveSentenceEventArgs>(gpsDevice_ReceiveSentence);
+  /// 
+  ///  // Use a delegate as Windows Forms Controls are not thread safe
+  ///  private delegate void DisplayNmeaDelegate(Sentence sentence);
+  /// 
+  ///  // The Event is then raised by the assembly when data is received from the NMEA device.
+  ///  private void gpsDevice_ReceiveSentence(object source, ReceiveSentenceEventArgs e)
+  ///  {
+  ///      // Call the Display function
+  /// 	    DisplayNmea(e.Sentence);
+  ///  }
+  ///  
+  ///  private void DisplayNmea(Sentence sentence)
+  ///  {
+  /// 
+  ///     // Populate a label called lblSentence
+  /// 
+  ///     // Do NOT do this, as we may not be on the UI thread.
+  ///     // lblSentence.Text = sentence.ToString();
+  /// 
+  ///     // Check if we need to call Invoke.
+  ///     if (this.InvokeRequired)
+  ///     {
+  ///         // Pass the this function to Invoke,
+  ///         // then the call will come in on the correct
+  ///         // thread and InvokeRequired will be false.
+  ///         this.BeginInvoke(new DisplayNmeaDelegate(DisplayNmea), new object[] { sentence });
+  ///         return;
+  ///     }
+  /// 
+  ///     //ok now as we are on the UI thread so this is OK
+  ///     lblSentence.Text = sentence.ToString();
+  /// 
+  ///     // All sentence objects are derived from Waymex.Gps.NMEA.Sentence, to get to the
+  ///     // specific properties of a derived type (e.g. SentenceRmc) simply
+  ///     // cast the Sentence object to the approriate type as follows;
+  ///     switch (sentence.TypeId)
+  ///     {
+  ///         case "RMC":
+  /// 
+  ///             // RMC Sentence received so cast to the SentenceRmc type
+  ///             SentenceRmc sentenceRmc = (SentenceRmc)sentence;
+  /// 
+  ///             // process the properties as required
+  ///             lblLatitude.Text = sentenceRmc.Latitude.ToString();
+  ///             lblLongitude.Text = sentenceRmc.Longitude.ToString();
+  /// 
+  ///             break;
+  /// 
+  ///         case "RMB":
+  /// 
+  ///             // RMB Sentence received so cast to the SentenceRmb type
+  ///            SentenceRmb sentenceRmb = (SentenceRmb)sentence;
+  /// 
+  ///             // process the properties as required
+  ///             lblDestLatitude.Text = sentenceRmb.DestinationLatitude.ToString();
+  /// 
+  ///              break;
+  ///      }
+  ///  }
+  ///  ]]></code>
+  /// </example>
+  public class NmeaDevice : IDisposable
+  {
+    private const string ERR_MSG_LIC_NONEXISTENT = "The licence for this product is invalid or missing.";
+    private const string ERR_MSG_LIC_EXPIRED = "The licence for this product has expired.";
+    private const double TRIAL_EXPIRY_DAYS = 30.0;
+
+    private const string ERR_PORT_RANGE = "The value for port must be between 1 and 256 must be specified.";
+
+    private const string ERR_BAUD_RANGE =
+      "The value for speed must be one of the following: 1200, 4800, 9600, 19200, 57600 or 115200.";
+
+    //these need moving out to a different namespace or making dynamic
+    //used as the registry keys for licencing
+    private const string PRODUCT_NAME = "GPS Library .Net";
+    private const string PRODUCT_VERSION = "3.2";
+
+    //private const string INSTALLSHIELD_PRODUCT_CODE_TRIAL = "{271A284E-8913-45C0-862A-8687A329B7AC}";
+
+    private readonly SerialLink ComPort;
+    private LicenceStatus m_licenceStatus = LicenceStatus.licenceValid;
+    private int m_port = 1; //this represents com1
+    private int m_speed = 4800;
+
+    private string m_strCaptureFile = "";
+    private string m_strCaptureFileFilter = "";
+
     /// <summary>
-    /// This class allows acces to a connected NMEA device. The class exposes a single event
-    /// that fires when a valid NMEA sentence is received from the NMEA device. 
-    /// The following Sentence types are supported with specific typed objects; 
-    /// BOD, GGA, GLL, GSA, GSV, RMB, RMC, WPL, PGRMC, PGRME, PGRMM, PGRMZ, PSLIB.
-    /// Other sentence type are accessed via a generic sentence type.
+    ///   Constructor for the Device class.
     /// </summary>
-    /// <example>C#
-    /// <code><![CDATA[
-    /// 
-    /// // Register the event, typically in Form_Load
-    /// gps.ReceiveSentence += new EventHandler<ReceiveSentenceEventArgs>(gpsDevice_ReceiveSentence);
-    ///
-    /// // Use a delegate as Windows Forms Controls are not thread safe
-    /// private delegate void DisplayNmeaDelegate(Sentence sentence);
-    ///
-    /// // The Event is then raised by the assembly when data is received from the NMEA device.
-    /// private void gpsDevice_ReceiveSentence(object source, ReceiveSentenceEventArgs e)
-    /// {
-    ///     // Call the Display function
-    ///	    DisplayNmea(e.Sentence);
-    /// }
-    /// 
-    /// private void DisplayNmea(Sentence sentence)
-    /// {
-    ///
-    ///    // Populate a label called lblSentence
-    ///
-    ///    // Do NOT do this, as we may not be on the UI thread.
-    ///    // lblSentence.Text = sentence.ToString();
-    ///
-    ///    // Check if we need to call Invoke.
-    ///    if (this.InvokeRequired)
-    ///    {
-    ///        // Pass the this function to Invoke,
-    ///        // then the call will come in on the correct
-    ///        // thread and InvokeRequired will be false.
-    ///        this.BeginInvoke(new DisplayNmeaDelegate(DisplayNmea), new object[] { sentence });
-    ///        return;
-    ///    }
-    ///
-    ///    //ok now as we are on the UI thread so this is OK
-    ///    lblSentence.Text = sentence.ToString();
-    ///
-    ///    // All sentence objects are derived from Waymex.Gps.NMEA.Sentence, to get to the
-    ///    // specific properties of a derived type (e.g. SentenceRmc) simply
-    ///    // cast the Sentence object to the approriate type as follows;
-    ///    switch (sentence.TypeId)
-    ///    {
-    ///        case "RMC":
-    ///
-    ///            // RMC Sentence received so cast to the SentenceRmc type
-    ///            SentenceRmc sentenceRmc = (SentenceRmc)sentence;
-    ///
-    ///            // process the properties as required
-    ///            lblLatitude.Text = sentenceRmc.Latitude.ToString();
-    ///            lblLongitude.Text = sentenceRmc.Longitude.ToString();
-    ///
-    ///            break;
-    ///
-    ///        case "RMB":
-    ///
-    ///            // RMB Sentence received so cast to the SentenceRmb type
-    ///           SentenceRmb sentenceRmb = (SentenceRmb)sentence;
-    ///
-    ///            // process the properties as required
-    ///            lblDestLatitude.Text = sentenceRmb.DestinationLatitude.ToString();
-    ///
-    ///             break;
-    ///     }
-    /// }
-    /// ]]></code>
-    /// </example>
-    public class NmeaDevice : IDisposable
+    public NmeaDevice()
     {
-        private const string ERR_MSG_LIC_NONEXISTENT = "The licence for this product is invalid or missing.";
-        private const string ERR_MSG_LIC_EXPIRED = "The licence for this product has expired.";
-        private const double TRIAL_EXPIRY_DAYS = 30.0;
-
-        private const string ERR_PORT_RANGE = "The value for port must be between 1 and 256 must be specified.";
-        private const string ERR_BAUD_RANGE = "The value for speed must be one of the following: 1200, 4800, 9600, 19200, 57600 or 115200.";
-       
-        //these need moving out to a different namespace or making dynamic
-        //used as the registry keys for licencing
-        private const string PRODUCT_NAME = "GPS Library .Net";            
-        private const string PRODUCT_VERSION = "3.2";
-
-        //private const string INSTALLSHIELD_PRODUCT_CODE_TRIAL = "{271A284E-8913-45C0-862A-8687A329B7AC}";
-        
-        private LicenceStatus m_licenceStatus = LicenceStatus.licenceValid;
-
-        private SerialLink ComPort = null;
-        int m_speed = 4800;
-        int m_port = 1;	//this represents com1
-
-        private string m_strCaptureFile = "";
-        private string m_strCaptureFileFilter = "";
-
-        /// <summary>
-        /// This event provides access to real time NMEA data. The Event fires when a valid
-        /// NMEA Sentence is received from the NMEA device. Passed to the Event is an object
-        /// representing the sentence received. The following Sentence types are supported
-        /// with specific typed objects;
-        /// BOD, GGA, GLL, GSA, GSV, RMB, RMC, WPL, PGRMC, PGRME, PGRMM, PGRMZ, PSLIB.
-        /// Other sentence type are accessed via a generic sentence type.
-        /// </summary>
-        /// <example>C#
-        /// <code><![CDATA[
-        /// 
-        /// // Register the event, typically in Form_Load
-        /// gps.ReceiveSentence += new EventHandler<ReceiveSentenceEventArgs>(gpsDevice_ReceiveSentence);
-        ///
-        /// // Use a delegate as Windows Forms Controls are not thread safe
-        /// private delegate void DisplayNmeaDelegate(Sentence sentence);
-        ///
-        /// // The Event is then raised by the assembly when data is received from the NMEA device.
-        /// private void gpsDevice_ReceiveSentence(object source, ReceiveSentenceEventArgs e)
-        /// {
-        ///     // Call the Display function
-        ///	    DisplayNmea(e.Sentence);
-        /// }
-        /// 
-        /// private void DisplayNmea(Sentence sentence)
-        /// {
-        ///
-        ///    // Populate a label called lblSentence
-        ///
-        ///    // Do NOT do this, as we may not be on the UI thread.
-        ///    // lblSentence.Text = sentence.ToString();
-        ///
-        ///    // Check if we need to call Invoke.
-        ///    if (this.InvokeRequired)
-        ///    {
-        ///        // Pass the this function to Invoke,
-        ///        // then the call will come in on the correct
-        ///        // thread and InvokeRequired will be false.
-        ///        this.BeginInvoke(new DisplayNmeaDelegate(DisplayNmea), new object[] { sentence });
-        ///        return;
-        ///    }
-        ///
-        ///    //ok now as we are on the UI thread so this is OK
-        ///    lblSentence.Text = sentence.ToString();
-        ///
-        ///    // All sentence objects are derived from Waymex.Gps.NMEA.Sentence, to get to the
-        ///    // specific properties of a derived type (e.g. SentenceRmc) simply
-        ///    // cast the Sentence object to the approriate type as follows;
-        ///    switch (sentence.TypeId)
-        ///    {
-        ///        case "RMC":
-        ///
-        ///            // RMC Sentence received so cast to the SentenceRmc type
-        ///            SentenceRmc sentenceRmc = (SentenceRmc)sentence;
-        ///
-        ///            // process the properties as required
-        ///            lblLatitude.Text = sentenceRmc.Latitude.ToString();
-        ///            lblLongitude.Text = sentenceRmc.Longitude.ToString();
-        ///
-        ///            break;
-        ///
-        ///        case "RMB":
-        ///
-        ///            // RMB Sentence received so cast to the SentenceRmb type
-        ///           SentenceRmb sentenceRmb = (SentenceRmb)sentence;
-        ///
-        ///            // process the properties as required
-        ///            lblDestLatitude.Text = sentenceRmb.DestinationLatitude.ToString();
-        ///
-        ///             break;
-        ///     }
-        /// }
-        /// ]]></code>
-        /// </example>
-        public event EventHandler<ReceiveSentenceEventArgs> ReceiveSentence;
-
-        //not required in .Net 2.0
-        //public delegate void ReceiveSentenceEventHandler(object sender, ReceiveSentenceEventArgs e);
-
-        //use the following code to raise the event
-        //
-        //		if (ReceiveSentence != null)
-        //		{
-        //			ReceiveSentence(this, new ReceiveSentenceEventArgs(<object>));
-        //		}
-
-        /// <summary>
-        /// Constructor for the Device class.
-        /// </summary>
-        public NmeaDevice()
-        {
-            try
-            {
+      try
+      {
 #if(TRIAL)
-                //m_licenceStatus = Waymex.Security.Licencing.GetQlmLicenceStatus(typeof(Waymex.Gps.DeviceBase), 1, "GPS Library for .Net (2.0)", 3, 0, "{69C9C619-7226-4DF0-816D-3528133BC06F}");
-                //m_licenceStatus = Licencing.GetLicenceStatus(typeof(Waymex.Gps.DeviceBase));
+  //m_licenceStatus = Waymex.Security.Licencing.GetQlmLicenceStatus(typeof(Waymex.Gps.DeviceBase), 1, "GPS Library for .Net (2.0)", 3, 0, "{69C9C619-7226-4DF0-816D-3528133BC06F}");
+  //m_licenceStatus = Licencing.GetLicenceStatus(typeof(Waymex.Gps.DeviceBase));
                 m_licenceStatus = Waymex.Security.Licencing.GetLicenceStatus(PRODUCT_NAME, PRODUCT_VERSION, TRIAL_EXPIRY_DAYS);
 
                 //if there is no licence present they should not be using this version
                     throw new ApplicationException(ERR_MSG_LIC_NONEXISTENT);
                 }
 #else
-                m_licenceStatus = LicenceStatus.licenceValid;
+        m_licenceStatus = LicenceStatus.licenceValid;
 #endif
 
-                ComPort = new SerialLink();
-                ComPort.OnRxSentence += new SerialLink.OnRxSentenceEventHandler(ComPort_OnRxSentence);
-                Waymex.Diagnostics.TraceLog.WriteHeader();
-
-            }
-            catch (Exception ex)
-            {
-                TraceLog.WriteError(ex);
-                throw ex;
-            }
-        }
-        /// <summary>
-        /// Provides a mechanism to send an NMEA sentence to the GPS Device.
-        /// </summary>
-        public void Send(Sentence sentence)
-        {
-
-            try
-            {
-                ComPort.Send(StringToByte(sentence.ToString()));
-            }
-            catch (Exception ex)
-            {
-                TraceLog.WriteError(ex);
-                throw new DataTransferException(ex.Message, ex);
-            }
-        }
-        /// <summary>
-        /// Closes the communications port and stops processing NMEA data.
-        /// </summary>
-        public void Stop()
-        {
-            try
-            {
-                if (ComPort.Online)
-                {
-                    ComPort.Close();
-                }
-            }
-            catch (Exception ex)
-            {
-                TraceLog.WriteError(ex);
-                throw new PortException(ex.Message, ex);
-            }
-        }
-        /// <summary>
-        /// Specifies and opens the serial communication port to use.
-        /// </summary>
-        /// <param name="port">The serial port to use. Values in the range 1 to 256 are accepted.</param>
-        public void OpenPort(int port)
-        {
-            OpenPort(port, 4800);
-        }
-
-        /// <summary>
-        /// Specifies and opens the serial communication port to use at the specified speed.
-        /// </summary>
-        /// <param name="port">Specifies the serial port to use. Values in the range 1 to 256 are accepted.</param>
-        /// <param name="speed">Specifies the baud rate to use.</param>
-        public void OpenPort(int port, int speed)
-        {
-            if (port < 1 || port > 256)
-                throw new ArgumentOutOfRangeException(ERR_PORT_RANGE);
-            m_port = port;
-
-            if (speed == 1200 || speed == 4800 || speed == 9600 || speed == 19200 || speed == 57600 || speed == 115200)
-                m_speed = speed;
-            else
-                throw new ArgumentOutOfRangeException(ERR_BAUD_RANGE);
-        
-        }
-        /// <summary>
-        /// Opens the default port, COM 1 at the default speed, 4800 baud..
-        /// </summary>
-        public void OpenPort()
-        {
-            //set this to zero ensures usb will be selected
-            OpenPort(1, 4800);
-        }
-
-        /// <summary>
-        /// Closes the currently open port. This can safely be called at any time.
-        /// </summary>
-        public void ClosePort()
-        {
-            //do nothing, this is simply here to keep users happy.
-        }
-
-        /// <summary>
-        /// Gets/Sets the communications port to use.
-        /// </summary>
-        [Obsolete("Property depreciated. Use the OpenPort() and ClosePort() methods to set a communication port.")]
-        public Port CommunicationsPort
-        {
-            get
-            {
-                return (Port)m_port;
-            }
-            set
-            {
-                m_port = (int)value;
-            }
-        }
-
-        /// <summary>
-        /// Sets/Gets the Baud rate of the serial connection.
-        /// </summary>
-        [Obsolete("Property depreciated. Use the OpenPort() and ClosePort() methods to set a communication port.")]
-        public BaudRate BaudRate
-        {
-            get
-            {
-                return (BaudRate)m_speed;
-            }
-            set
-            {
-                m_speed = (int)value;
-            }
-        }
-        /// <summary>
-        /// Opens the communications Port and starts processing the NMEA data.
-        /// </summary>
-        public void Start()
-        {
-            try
-            {
-                ComPort.Close();
-
-                ComPort.Port = m_port;
-                ComPort.BaudRate = m_speed;
-                ComPort.Open();
-            }
-            catch (Exception ex)
-            {
-                TraceLog.WriteError(ex);
-                throw new PortException(ex.Message, ex);
-            }
-        }
-
-        internal void ComPort_OnRxSentence(object source, OnRxSentenceEventArgs eargs)
-        {
-            string strMessage = "";
-            Sentence objSentence = null;
-
-            try
-            {
-                //write the line, remove the trailing CR first
-                strMessage = eargs.RxSentence.ToString(CultureInfo.InvariantCulture);
-
-                TraceLog.WriteMessage(strMessage.Substring(0, strMessage.Length - 2), System.Diagnostics.TraceLevel.Verbose, true);
-
-                //this could return an error if garbage is received
-                objSentence = new Sentence(eargs.RxSentence);
-
-                if (objSentence != null)
-                {
-                    switch (objSentence.TypeId)
-                    {
-                        case "RMC":
-                            SentenceRmc objSentenceRmc = new SentenceRmc(strMessage);
-                            WriteToCaptureFile(objSentenceRmc, m_strCaptureFileFilter);
-                            if (ReceiveSentence != null)
-                            {
-                                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceRmc));
-                            }
-                            break;
-
-                        case "RMB":
-
-
-                                SentenceRmb objSentenceRmb = new SentenceRmb(strMessage);
-                                WriteToCaptureFile(objSentenceRmb, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceRmb));
-                                }
-                            break;
-
-                        case "BOD":
-
-                                SentenceBod objSentenceBod = new SentenceBod(strMessage);
-                                WriteToCaptureFile(objSentenceBod, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceBod));
-                                }
-                            break;
-                        case "GGA":
-                                SentenceGga objSentenceGga = new SentenceGga(strMessage);
-                                WriteToCaptureFile(objSentenceGga, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceGga));
-                                }
-                            break;
-                        case "GLL":
-                                SentenceGll objSentenceGll = new SentenceGll(strMessage);
-                                WriteToCaptureFile(objSentenceGll, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceGll));
-                                }
-                            break;
-                        case "GSA":
-                                SentenceGsa objSentenceGsa = new SentenceGsa(strMessage);
-                                WriteToCaptureFile(objSentenceGsa, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceGsa));
-                                }
-                            break;
-                        case "GSV":
-                                SentenceGsv objSentenceGsv = new SentenceGsv(strMessage);
-                                WriteToCaptureFile(objSentenceGsv, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceGsv));
-                                }
-                            break;
-                        case "WPL":
-                                SentenceWpl objSentenceWpl = new SentenceWpl(strMessage);
-                                WriteToCaptureFile(objSentenceWpl, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceWpl));
-                                }
-                            break;
-                        case "PGRMC":
-                                SentencePgRmc objSentencePgRmc = new SentencePgRmc(strMessage);
-                                WriteToCaptureFile(objSentencePgRmc, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentencePgRmc));
-                                }
-                            break;
-                        case "PGRME":
-                                SentencePgRme objSentencePgRme = new SentencePgRme(strMessage);
-                                WriteToCaptureFile(objSentencePgRme, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentencePgRme));
-                                }
-                            break;
-                        case "PGRMM":
-                                SentencePgRmm objSentencePgRmm = new SentencePgRmm(strMessage);
-                                WriteToCaptureFile(objSentencePgRmm, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentencePgRmm));
-                                }
-                            break;
-                        case "PGRMZ":
-                                SentencePgRmz objSentencePgRmz = new SentencePgRmz(strMessage);
-                                WriteToCaptureFile(objSentencePgRmz, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentencePgRmz));
-                                }
-                            break;
-                        case "PSLIB":
-                                SentencePsLib objSentencePsLib = new SentencePsLib(strMessage);
-                                WriteToCaptureFile(objSentencePsLib, m_strCaptureFileFilter);
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentencePsLib));
-                                }
-                            break;
-                        default:
-
-                                if (ReceiveSentence != null)
-                                {
-                                    ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentence));
-                                }
-                            break;
-
-                    }
-                }
-            }
-            catch
-            {
-                throw;
-            }
-        }
-        /// <summary>
-        /// Set this property to a valid filenamame and NMEA Sentences will be written to this file.
-        /// </summary>
-        public string CaptureFile
-        {
-            get
-            {
-                return m_strCaptureFile;
-            }
-            set
-            {
-                m_strCaptureFile = value;
-            }
-        }
-        /// <summary>
-        /// This property can be used to limit the NMEA sentences that are written to the Capture file.
-        /// For example setting the property to "RMC GLL" will ensure only the RMC and GLL sentence
-        /// types are written to the file. Leaving the property empty will ensure that all sentence
-        /// types are written to the file.
-        /// </summary>
-        public string CaptureFileFilter
-        {
-            get
-            {
-                return m_strCaptureFileFilter;
-            }
-            set
-            {
-                m_strCaptureFileFilter = value;
-            }
-        }
-
-        private void WriteToCaptureFile(Sentence p_objSentence, string p_strFilter)
-        {
-            StreamWriter swText;
-            string strText = "";
-
-            try
-            {
-                //make sure the capture file has been entered
-                if (m_strCaptureFile.Length > 0)
-                {
-                    // write to file here without CR as this is on source sentence;
-                    swText = new StreamWriter(m_strCaptureFile, true);
-
-                    //see if there is a filter in operation
-                    if (p_strFilter.Length > 0)
-                    {
-                        //see if the filter matches our TypeId
-                        if (p_strFilter.IndexOf(p_objSentence.TypeId) >= 0)
-                        {
-                            strText = p_objSentence.ToString();
-                            swText.Write(strText);
-                        }
-                    }
-                    else
-                    {
-                        strText = p_objSentence.ToString();
-                        swText.Write(strText);
-                    }
-
-                    swText.Close();
-                }
-            }
-            catch (Exception ex)
-            {
-                throw;
-            }
-        }
-
-        /// <summary>
-        /// Closes all resources and disposes of the object. 
-        /// </summary>
-        public void Dispose()
-        {
-            Dispose(true);
-        }
-        private void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                Dispose(true);
-                GC.SuppressFinalize(this);
-            }
-        }
-
-        private static byte[] StringToByte(string sData)
-        {
-            int iIndex = 0;
-            int iLength = 0;
-            byte[] bytData = null;
-            string strCharacter = "";
-            char[] chSentence = null;
-
-            try
-            {
-                iLength = sData.Length;
-
-                chSentence = sData.ToCharArray();
-
-                if (iLength > 0)
-                {
-                    bytData = new byte[iLength];
-
-                    for (iIndex = 0; iIndex < (bytData.Length); iIndex++)
-                    {
-                        strCharacter = sData.Substring(iIndex, 1);
-                        bytData[iIndex] = (byte)strCharacter.ToCharArray()[0];
-                    }
-                }
-            }
-            catch (Exception ex)
-            {
-                //TraceLog.WriteError(e)
-                throw;
-            }
-
-            return bytData;
-
-        }
+        ComPort = new SerialLink();
+        ComPort.OnRxSentence += ComPort_OnRxSentence;
+        TraceLog.WriteHeader();
+      }
+      catch (Exception ex)
+      {
+        TraceLog.WriteError(ex);
+        throw ex;
+      }
     }
 
-}
+    /// <summary>
+    ///   Gets/Sets the communications port to use.
+    /// </summary>
+    [Obsolete("Property depreciated. Use the OpenPort() and ClosePort() methods to set a communication port.")]
+    public Port CommunicationsPort
+    {
+      get { return (Port) m_port; }
+      set { m_port = (int) value; }
+    }
+
+    /// <summary>
+    ///   Sets/Gets the Baud rate of the serial connection.
+    /// </summary>
+    [Obsolete("Property depreciated. Use the OpenPort() and ClosePort() methods to set a communication port.")]
+    public BaudRate BaudRate
+    {
+      get { return (BaudRate) m_speed; }
+      set { m_speed = (int) value; }
+    }
+
+    /// <summary>
+    ///   Set this property to a valid filenamame and NMEA Sentences will be written to this file.
+    /// </summary>
+    public string CaptureFile
+    {
+      get { return m_strCaptureFile; }
+      set { m_strCaptureFile = value; }
+    }
+
+    /// <summary>
+    ///   This property can be used to limit the NMEA sentences that are written to the Capture file.
+    ///   For example setting the property to "RMC GLL" will ensure only the RMC and GLL sentence
+    ///   types are written to the file. Leaving the property empty will ensure that all sentence
+    ///   types are written to the file.
+    /// </summary>
+    public string CaptureFileFilter
+    {
+      get { return m_strCaptureFileFilter; }
+      set { m_strCaptureFileFilter = value; }
+    }
+
+    /// <summary>
+    ///   Closes all resources and disposes of the object.
+    /// </summary>
+    public void Dispose()
+    {
+      Dispose(true);
+    }
+
+    /// <summary>
+    ///   This event provides access to real time NMEA data. The Event fires when a valid
+    ///   NMEA Sentence is received from the NMEA device. Passed to the Event is an object
+    ///   representing the sentence received. The following Sentence types are supported
+    ///   with specific typed objects;
+    ///   BOD, GGA, GLL, GSA, GSV, RMB, RMC, WPL, PGRMC, PGRME, PGRMM, PGRMZ, PSLIB.
+    ///   Other sentence type are accessed via a generic sentence type.
+    /// </summary>
+    /// <example>
+    ///   C#
+    ///   <code><![CDATA[
+    ///  
+    ///  // Register the event, typically in Form_Load
+    ///  gps.ReceiveSentence += new EventHandler<ReceiveSentenceEventArgs>(gpsDevice_ReceiveSentence);
+    /// 
+    ///  // Use a delegate as Windows Forms Controls are not thread safe
+    ///  private delegate void DisplayNmeaDelegate(Sentence sentence);
+    /// 
+    ///  // The Event is then raised by the assembly when data is received from the NMEA device.
+    ///  private void gpsDevice_ReceiveSentence(object source, ReceiveSentenceEventArgs e)
+    ///  {
+    ///      // Call the Display function
+    /// 	    DisplayNmea(e.Sentence);
+    ///  }
+    ///  
+    ///  private void DisplayNmea(Sentence sentence)
+    ///  {
+    /// 
+    ///     // Populate a label called lblSentence
+    /// 
+    ///     // Do NOT do this, as we may not be on the UI thread.
+    ///     // lblSentence.Text = sentence.ToString();
+    /// 
+    ///     // Check if we need to call Invoke.
+    ///     if (this.InvokeRequired)
+    ///     {
+    ///         // Pass the this function to Invoke,
+    ///         // then the call will come in on the correct
+    ///         // thread and InvokeRequired will be false.
+    ///         this.BeginInvoke(new DisplayNmeaDelegate(DisplayNmea), new object[] { sentence });
+    ///         return;
+    ///     }
+    /// 
+    ///     //ok now as we are on the UI thread so this is OK
+    ///     lblSentence.Text = sentence.ToString();
+    /// 
+    ///     // All sentence objects are derived from Waymex.Gps.NMEA.Sentence, to get to the
+    ///     // specific properties of a derived type (e.g. SentenceRmc) simply
+    ///     // cast the Sentence object to the approriate type as follows;
+    ///     switch (sentence.TypeId)
+    ///     {
+    ///         case "RMC":
+    /// 
+    ///             // RMC Sentence received so cast to the SentenceRmc type
+    ///             SentenceRmc sentenceRmc = (SentenceRmc)sentence;
+    /// 
+    ///             // process the properties as required
+    ///             lblLatitude.Text = sentenceRmc.Latitude.ToString();
+    ///             lblLongitude.Text = sentenceRmc.Longitude.ToString();
+    /// 
+    ///             break;
+    /// 
+    ///         case "RMB":
+    /// 
+    ///             // RMB Sentence received so cast to the SentenceRmb type
+    ///            SentenceRmb sentenceRmb = (SentenceRmb)sentence;
+    /// 
+    ///             // process the properties as required
+    ///             lblDestLatitude.Text = sentenceRmb.DestinationLatitude.ToString();
+    /// 
+    ///              break;
+    ///      }
+    ///  }
+    ///  ]]></code>
+    /// </example>
+    public event EventHandler<ReceiveSentenceEventArgs> ReceiveSentence;
+
+    public event EventHandler<ExceptionOccurredEventArgs> ExceptionOccurred;
+
+    //not required in .Net 2.0
+    //public delegate void ReceiveSentenceEventHandler(object sender, ReceiveSentenceEventArgs e);
+
+    //use the following code to raise the event
+    //
+    //		if (ReceiveSentence != null)
+    //		{
+    //			ReceiveSentence(this, new ReceiveSentenceEventArgs(<object>));
+    //		}
+
+    /// <summary>
+    ///   Provides a mechanism to send an NMEA sentence to the GPS Device.
+    /// </summary>
+    public void Send(Sentence sentence)
+    {
+      try
+      {
+        ComPort.Send(StringToByte(sentence.ToString()));
+      }
+      catch (Exception ex)
+      {
+        TraceLog.WriteError(ex);
+        throw new DataTransferException(ex.Message, ex);
+      }
+    }
+
+    /// <summary>
+    ///   Closes the communications port and stops processing NMEA data.
+    /// </summary>
+    public void Stop()
+    {
+      try
+      {
+        if (ComPort.Online)
+        {
+          ComPort.Close();
+        }
+      }
+      catch (Exception ex)
+      {
+        TraceLog.WriteError(ex);
+        throw new PortException(ex.Message, ex);
+      }
+    }
+
+    /// <summary>
+    ///   Specifies and opens the serial communication port to use.
+    /// </summary>
+    /// <param name="port">The serial port to use. Values in the range 1 to 256 are accepted.</param>
+    public void OpenPort(int port)
+    {
+      OpenPort(port, 4800);
+    }
+
+    /// <summary>
+    ///   Specifies and opens the serial communication port to use at the specified speed.
+    /// </summary>
+    /// <param name="port">Specifies the serial port to use. Values in the range 1 to 256 are accepted.</param>
+    /// <param name="speed">Specifies the baud rate to use.</param>
+    public void OpenPort(int port, int speed)
+    {
+      if (port < 1 || port > 256)
+        throw new ArgumentOutOfRangeException(ERR_PORT_RANGE);
+      m_port = port;
+
+      if (speed == 1200 || speed == 4800 || speed == 9600 || speed == 19200 || speed == 57600 || speed == 115200)
+        m_speed = speed;
+      else
+        throw new ArgumentOutOfRangeException(ERR_BAUD_RANGE);
+    }
+
+    /// <summary>
+    ///   Opens the default port, COM 1 at the default speed, 4800 baud..
+    /// </summary>
+    public void OpenPort()
+    {
+      //set this to zero ensures usb will be selected
+      OpenPort(1, 4800);
+    }
+
+    /// <summary>
+    ///   Closes the currently open port. This can safely be called at any time.
+    /// </summary>
+    public void ClosePort()
+    {
+      //do nothing, this is simply here to keep users happy.
+    }
+
+    /// <summary>
+    ///   Opens the communications Port and starts processing the NMEA data.
+    /// </summary>
+    public void Start()
+    {
+      try
+      {
+        ComPort.Close();
+
+        ComPort.Port = m_port;
+        ComPort.BaudRate = m_speed;
+        ComPort.Open();
+      }
+      catch (Exception ex)
+      {
+        TraceLog.WriteError(ex);
+        throw new PortException(ex.Message, ex);
+      }
+    }
+
+    internal void ComPort_OnRxSentence(object source, OnRxSentenceEventArgs eargs)
+    {
+      string strMessage = "";
+      Sentence objSentence = null;
+
+      try
+      {
+        //write the line, remove the trailing CR first
+        strMessage = eargs.RxSentence.ToString(CultureInfo.InvariantCulture);
+
+        TraceLog.WriteMessage(strMessage.Substring(0, strMessage.Length - 2), TraceLevel.Verbose, true);
+
+        //this could return an error if garbage is received
+        objSentence = new Sentence(eargs.RxSentence);
+
+        if (objSentence != null)
+        {
+          switch (objSentence.TypeId)
+          {
+            case "RMC":
+              var objSentenceRmc = new SentenceRmc(strMessage);
+              WriteToCaptureFile(objSentenceRmc, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceRmc));
+              }
+              break;
+
+            case "RMB":
+
+
+              var objSentenceRmb = new SentenceRmb(strMessage);
+              WriteToCaptureFile(objSentenceRmb, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceRmb));
+              }
+              break;
+
+            case "BOD":
+
+              var objSentenceBod = new SentenceBod(strMessage);
+              WriteToCaptureFile(objSentenceBod, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceBod));
+              }
+              break;
+            case "GGA":
+              var objSentenceGga = new SentenceGga(strMessage);
+              WriteToCaptureFile(objSentenceGga, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceGga));
+              }
+              break;
+            case "GLL":
+              var objSentenceGll = new SentenceGll(strMessage);
+              WriteToCaptureFile(objSentenceGll, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceGll));
+              }
+              break;
+            case "GSA":
+              var objSentenceGsa = new SentenceGsa(strMessage);
+              WriteToCaptureFile(objSentenceGsa, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceGsa));
+              }
+              break;
+            case "GSV":
+              var objSentenceGsv = new SentenceGsv(strMessage);
+              WriteToCaptureFile(objSentenceGsv, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceGsv));
+              }
+              break;
+            case "WPL":
+              var objSentenceWpl = new SentenceWpl(strMessage);
+              WriteToCaptureFile(objSentenceWpl, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentenceWpl));
+              }
+              break;
+            case "PGRMC":
+              var objSentencePgRmc = new SentencePgRmc(strMessage);
+              WriteToCaptureFile(objSentencePgRmc, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentencePgRmc));
+              }
+              break;
+            case "PGRME":
+              var objSentencePgRme = new SentencePgRme(strMessage);
+              WriteToCaptureFile(objSentencePgRme, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentencePgRme));
+              }
+              break;
+            case "PGRMM":
+              var objSentencePgRmm = new SentencePgRmm(strMessage);
+              WriteToCaptureFile(objSentencePgRmm, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentencePgRmm));
+              }
+              break;
+            case "PGRMZ":
+              var objSentencePgRmz = new SentencePgRmz(strMessage);
+              WriteToCaptureFile(objSentencePgRmz, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentencePgRmz));
+              }
+              break;
+            case "PSLIB":
+              var objSentencePsLib = new SentencePsLib(strMessage);
+              WriteToCaptureFile(objSentencePsLib, m_strCaptureFileFilter);
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentencePsLib));
+              }
+              break;
+            default:
+
+              if (ReceiveSentence != null)
+              {
+                ReceiveSentence(this, new ReceiveSentenceEventArgs(objSentence));
+              }
+              break;
+          }
+        }
+      }
+      catch (Exception e)
+      {
+        if (ExceptionOccurred != null)
+        {
+          ExceptionOccurred(this, new ExceptionOccurredEventArgs(e));
+        }
+      }
+    }
+
+    private void WriteToCaptureFile(Sentence p_objSentence, string p_strFilter)
+    {
+      StreamWriter swText;
+      string strText = "";
+
+      try
+      {
+        //make sure the capture file has been entered
+        if (m_strCaptureFile.Length > 0)
+        {
+          // write to file here without CR as this is on source sentence;
+          swText = new StreamWriter(m_strCaptureFile, true);
+
+          //see if there is a filter in operation
+          if (p_strFilter.Length > 0)
+          {
+            //see if the filter matches our TypeId
+            if (p_strFilter.IndexOf(p_objSentence.TypeId) >= 0)
+            {
+              strText = p_objSentence.ToString();
+              swText.Write(strText);
+            }
+          }
+          else
+          {
+            strText = p_objSentence.ToString();
+            swText.Write(strText);
+          }
+
+          swText.Close();
+        }
+      }
+      catch (Exception ex)
+      {
+        throw;
+      }
+    }
+
+    private void Dispose(bool disposing)
+    {
+      if (disposing)
+      {
+        Dispose(true);
+        GC.SuppressFinalize(this);
+      }
+    }
+
+    private static byte[] StringToByte(string sData)
+    {
+      int iIndex = 0;
+      int iLength = 0;
+      byte[] bytData = null;
+      string strCharacter = "";
+      char[] chSentence = null;
+
+      try
+      {
+        iLength = sData.Length;
+
+        chSentence = sData.ToCharArray();
+
+        if (iLength > 0)
+        {
+          bytData = new byte[iLength];
+
+          for (iIndex = 0; iIndex < (bytData.Length); iIndex++)
+          {
+            strCharacter = sData.Substring(iIndex, 1);
+            bytData[iIndex] = (byte) strCharacter.ToCharArray()[0];
+          }
+        }
+      }
+      catch (Exception ex)
+      {
+        //TraceLog.WriteError(e)
+        throw;
+      }
+
+      return bytData;
+    }
+  }
+}

File Waymex.GpsLibrary/Gps/Waypoint.cs

 using System;
+using System.Globalization;
 using System.Xml;
-using System.Globalization;
-
 
 namespace Waymex.Gps
 {
-	/// <summary>
-	/// This object represents a single Waypoint and forms part of the 
-	/// of the WaypointCollection object that is returned by the GetWaypoints 
-	/// and GetProximityWaypoints methods of the Device object. 
-	/// This object is also returned by the Waypoints Property 
-	/// of the Route object.
-	/// </summary>
-	/// <remarks>
-    /// <para>
-	/// When receiving data from the Host, most GPS devices will overwrite any existing 
-	/// waypoints with the same name stored in the GPS device. For example, if the Host 
-	/// sends a waypoint named CBELLS, most GPS devices will overwrite a waypoint named
-	/// CBELLS that may be stored in GPS memory.
-	/// </para>
-	/// <para>
-	/// However some GPS devices compare the position of the new waypoint with the position
-	/// of the stored waypoint (altitude is ignored). If the positions match, the GPS
-	/// will erase the identically named waypoint and replace it with the new one.
-	/// If the positions differ, the unit will create a new, unique name for the
-	/// incoming waypoint and preserve the existing waypoint under its original name.
-	/// </para>
-	/// <para>
-	/// When the Host requests the GPS to send waypoints, the GPS will send every
-	/// waypoint stored in its database. When the Host sends waypoints to the GPS,
-	/// the Host may selectively transfer any number of waypoints.
-	/// </para>
-	/// <para>
-	/// When the Host requests the GPS to send proximity waypoints, the GPS will send all proximity
-	/// waypoints stored in its database.
-	/// </para>
-    /// <para>
-    /// <b>Symbols</b>
-	/// </para>
-    /// <para>
-    /// Garmin devices use three symbol sets for Waypoint symbols and 
-    /// Magellan devices use five symbol sets. 
-    /// The set used depends upon the specific device connected. 
-    /// The <see cref="ProductInfo.SymbolSet">ProductInfo.SymbolSet</see> property returns the symbol set in 
-    /// use by a particular device.
-    /// The <see cref="Waypoint.SymbolIdentifier">Waypoint.SymbolIdentifier</see> property allows for an enumerated value that 
-    /// works for all symbols across all devices (including Magellan devices).
-    /// The Waypoint.Symbol property (Int16) returns the raw symbol value of the waypoint
-    /// for garmin devices and the Waypoint.Icon property (String) returns the raw Icon 
-    /// value of the waypoint for Magellan devices.
-    /// </para>
-    /// <para>
-    /// When retrieving waypoint data from one device and transferring it to another device,
-    /// care must be taken when using the Symbol or Icon properties. For example the raw
-    /// symbol value for a 'dot' on a garmin device using symbol set 0 is 0 but a dot for
-    /// a device using symbol set 1 is 18. The SymbolIdentifier is a much safer approach.
-    /// </para>
-    /// <para><b>
-    /// Garmin Symbol Sets
-    /// </b>
-    /// </para>
-    /// <para>
-    /// Many GPS devices are limited to a much smaller subset of these symbols.  
-    /// However, the GPS will ignore any disallowed symbol values that are received 
-    /// and instead substitute the value for a generic dot symbol.
-    /// </para>
-    /// <para><b>Symbols Set 0</b></para>
-    /// <list type="table">
-    /// <listheader><term>Raw Value (Symbol property)</term><description>Symbol Description</description></listheader>
-    /// <item><term>0</term><description>dot</description></item>
-    /// <item><term>1</term><description>house</description></item>
-    /// <item><term>2</term><description>gas</description></item>
-    /// <item><term>3</term><description>car</description></item>
-    /// <item><term>4</term><description>fish</description></item>
-    /// <item><term>5</term><description>boat</description></item>
-    /// <item><term>6</term><description>anchor</description></item>
-    /// <item><term>7</term><description>wreck</description></item>
-    /// <item><term>8</term><description>exit</description></item>
-    /// <item><term>9</term><description>skull</description></item>
-    /// <item><term>10</term><description>flag</description></item>
-    /// <item><term>11</term><description>camp</description></item>
-    /// <item><term>12</term><description>circle with x </description></item>
-    /// <item><term>13</term><description>deer</description></item>
-    /// <item><term>14</term><description>first aid</description></item>
-    /// <item><term>15</term><description>back track</description></item>
-    /// </list>
-    /// <br/><br/>
-    /// <para><b>Symbols Set 1</b></para>
-    /// <list type="table">
-    /// <listheader><term>Raw Value (Symbol property)</term><description>Symbol Description</description></listheader>
-    /// <item><term>0</term><description>white anchor symbol</description></item>
-    /// <item><term>1</term><description>white bell symbol</description></item>
-    /// <item><term>2</term><description>green diamond symbol</description></item>
-    /// <item><term>3</term><description>red diamond symbol</description></item>
-    /// <item><term>4</term><description>diver down flag 1</description></item>
-    /// <item><term>5</term><description>diver down flag 2</description></item>
-    /// <item><term>6</term><description>white dollar symbol</description></item>
-    /// <item><term>7</term><description>white fish symbol</description></item>
-    /// <item><term>8</term><description>white fuel symbol</description></item>
-    /// <item><term>9</term><description>white horn symbol</description></item>
-    /// <item><term>10</term><description>white house symbol</description></item>
-    /// <item><term>11</term><description>white knife and fork symbol</description></item>
-    /// <item><term>12</term><description>white light symbol</description></item>
-    /// <item><term>13</term><description>white mug symbol</description></item>
-    /// <item><term>14</term><description>white skull and crossbones symbol</description></item>
-    /// <item><term>15</term><description>green square symbol</description></item>
-    /// <item><term>16</term><description>red square symbol</description></item>
-    /// <item><term>17</term><description>white buoy waypoint symbol</description></item>
-    /// <item><term>18</term><description>waypoint dot</description></item>
-    /// <item><term>19</term><description>white wreck symbol</description></item>
-    /// <item><term>20</term><description>null symbol (transparent)</description></item>
-    /// <item><term>21</term><description>man overboard symbol</description></item>
-    /// <item><term>22</term><description>amber map buoy symbol</description></item>
-    /// <item><term>23</term><description>black map buoy symbol</description></item>
-    /// <item><term>24</term><description>blue map buoy symbol</description></item>
-    /// <item><term>25</term><description>green map buoy symbol</description></item>
-    /// <item><term>26</term><description>green/red map buoy symbol</description></item>
-    /// <item><term>27</term><description>green/white map buoy symbol</description></item>
-    /// <item><term>28</term><description>orange map buoy symbol</description></item>
-    /// <item><term>29</term><description>red map buoy symbol</description></item>
-    /// <item><term>30</term><description>red/green map buoy symbol</description></item>
-    /// <item><term>31</term><description>red/white map buoy symbol</description></item>
-    /// <item><term>32</term><description>violet map buoy symbol</description></item>
-    /// <item><term>33</term><description>white map buoy symbol</description></item>
-    /// <item><term>34</term><description>white/green map buoy symbol</description></item>
-    /// <item><term>35</term><description>white/red map buoy symbol</description></item>
-    /// <item><term>36</term><description>white dot symbol</description></item>
-    /// <item><term>37</term><description>radio beacon symbol</description></item>
-    /// <item><term>150</term><description>boat ramp symbol</description></item>
-    /// <item><term>151</term><description>campground symbol</description></item>
-    /// <item><term>152</term><description>restrooms symbol</description></item>
-    /// <item><term>153</term><description>shower symbol</description></item>
-    /// <item><term>154</term><description>drinking water symbol</description></item>
-    /// <item><term>155</term><description>telephone symbol</description></item>
-    /// <item><term>156</term><description>first aid symbol</description></item>
-    /// <item><term>157</term><description>information symbol</description></item>
-    /// <item><term>158</term><description>parking symbol</description></item>
-    /// <item><term>159</term><description>park symbol</description></item>
-    /// <item><term>160</term><description>picnic symbol</description></item>
-    /// <item><term>161</term><description>scenic area symbol</description></item>
-    /// <item><term>162</term><description>skiing symbol</description></item>
-    /// <item><term>163</term><description>swimming symbol</description></item>
-    /// <item><term>164</term><description>dam symbol</description></item>
-    /// <item><term>165</term><description>controlled area symbol</description></item>
-    /// <item><term>166</term><description>danger symbol</description></item>
-    /// <item><term>167</term><description>restricted area symbol</description></item>
-    /// <item><term>168</term><description>null symbol</description></item>
-    /// <item><term>169</term><description>ball symbol</description></item>
-    /// <item><term>170</term><description>car symbol</description></item>
-    /// <item><term>171</term><description>deer symbol</description></item>
-    /// <item><term>172</term><description>shopping cart symbol</description></item>
-    /// <item><term>173</term><description>lodging symbol</description></item>
-    /// <item><term>174</term><description>mine symbol</description></item>
-    /// <item><term>175</term><description>trail head symbol</description></item>
-    /// <item><term>176</term><description>truck stop symbol</description></item>
-    /// <item><term>177</term><description>user exit symbol</description></item>
-    /// <item><term>178</term><description>flag symbol</description></item>
-    /// <item><term>179</term><description>circle with x in the center</description></item>
-    /// <item><term>180</term><description>open 24 hours symbol</description></item>
-    /// <item><term>181</term><description>U fishing hot spots facility (tm)</description></item>
-    /// <item><term>182</term><description>bottom conditions</description></item>
-    /// <item><term>183</term><description>tide/current prediction station</description></item>
-    /// <item><term>184</term><description>U anchor prohibited symbol</description></item>
-    /// <item><term>185</term><description>U beacon symbol</description></item>
-    /// <item><term>186</term><description>U coast guard symbol</description></item>
-    /// <item><term>187</term><description>U reef symbol</description></item>
-    /// <item><term>188</term><description>U weedbed symbol</description></item>
-    /// <item><term>189</term><description>U dropoff symbol</description></item>
-    /// <item><term>190</term><description>U dock symbol</description></item>
-    /// <item><term>191</term><description>U marina symbol</description></item>
-    /// <item><term>192</term><description>U bait and tackle symbol</description></item>
-    /// <item><term>193</term><description>U stump symbol</description></item>
-    /// </list>
-    /// <br/><br/>
-    /// <para><b>Symbols Set 2</b></para>
-    /// <list type="table">
-    /// <listheader><term>Raw Value (Symbol property)</term><description>Symbol Description</description></listheader>
-    /// <item><term>0</term><description>white anchor symbol</description></item>
-    /// <item><term>1</term><description>white bell symbol</description></item>
-    /// <item><term>2</term><description>green diamond symbol</description></item>
-    /// <item><term>3</term><description>red diamond symbol</description></item>
-    /// <item><term>4</term><description>diver down flag 1</description></item>
-    /// <item><term>5</term><description>diver down flag 2</description></item>
-    /// <item><term>6</term><description>white dollar symbol</description></item>
-    /// <item><term>7</term><description>white fish symbol</description></item>
-    /// <item><term>8</term><description>white fuel symbol</description></item>
-    /// <item><term>9</term><description>white horn symbol</description></item>
-    /// <item><term>10</term><description>white house symbol</description></item>
-    /// <item><term>11</term><description>white knife and fork symbol</description></item>
-    /// <item><term>12</term><description>white light symbol</description></item>
-    /// <item><term>13</term><description>white mug symbol</description></item>
-    /// <item><term>14</term><description>white skull and crossbones symbol</description></item>
-    /// <item><term>15</term><description>green square symbol</description></item>
-    /// <item><term>16</term><description>red square symbol</description></item>
-    /// <item><term>17</term><description>white buoy waypoint symbol</description></item>
-    /// <item><term>18</term><description>waypoint dot</description></item>
-    /// <item><term>19</term><description>white wreck symbol</description></item>
-    /// <item><term>20</term><description>null symbol (transparent)</description></item>
-    /// <item><term>21</term><description>man overboard symbol</description></item>
-    /// <item><term>22</term><description>amber map buoy symbol</description></item>
-    /// <item><term>23</term><description>black map buoy symbol</description></item>
-    /// <item><term>24</term><description>blue map buoy symbol</description></item>
-    /// <item><term>25</term><description>green map buoy symbol</description></item>
-    /// <item><term>26</term><description>green/red map buoy symbol</description></item>
-    /// <item><term>27</term><description>green/white map buoy symbol</description></item>
-    /// <item><term>28</term><description>orange map buoy symbol</description></item>
-    /// <item><term>29</term><description>red map buoy symbol</description></item>
-    /// <item><term>30</term><description>red/green map buoy symbol</description></item>
-    /// <item><term>31</term><description>red/white map buoy symbol</description></item>
-    /// <item><term>32</term><description>violet map buoy symbol</description></item>
-    /// <item><term>33</term><description>white map buoy symbol</description></item>
-    /// <item><term>34</term><description>white/green map buoy symbol</description></item>
-    /// <item><term>35</term><description>white/red map buoy symbol</description></item>
-    /// <item><term>36</term><description>white dot symbol</description></item>
-    /// <item><term>37</term><description>radio beacon symbol</description></item>
-    /// <item><term>150</term><description>boat ramp symbol</description></item>
-    /// <item><term>151</term><description>campground symbol</description></item>
-    /// <item><term>152</term><description>restrooms symbol</description></item>
-    /// <item><term>153</term><description>shower symbol</description></item>
-    /// <item><term>154</term><description>drinking water symbol</description></item>
-    /// <item><term>155</term><description>telephone symbol</description></item>
-    /// <item><term>156</term><description>first aid symbol</description></item>
-    /// <item><term>157</term><description>information symbol</description></item>
-    /// <item><term>158</term><description>parking symbol</description></item>
-    /// <item><term>159</term><description>park symbol</description></item>
-    /// <item><term>160</term><description>picnic symbol</description></item>
-    /// <item><term>161</term><description>scenic area symbol</description></item>
-    /// <item><term>162</term><description>skiing symbol</description></item>
-    /// <item><term>163</term><description>swimming symbol</description></item>
-    /// <item><term>164</term><description>dam symbol</description></item>
-    /// <item><term>165</term><description>controlled area symbol</description></item>
-    /// <item><term>166</term><description>danger symbol</description></item>
-    /// <item><term>167</term><description>restricted area symbol</description></item>
-    /// <item><term>168</term><description>null symbol</description></item>
-    /// <item><term>169</term><description>ball symbol</description></item>
-    /// <item><term>170</term><description>car symbol</description></item>
-    /// <item><term>171</term><description>deer symbol</description></item>
-    /// <item><term>172</term><description>shopping cart symbol</description></item>
-    /// <item><term>173</term><description>lodging symbol</description></item>
-    /// <item><term>174</term><description>mine symbol</description></item>
-    /// <item><term>175</term><description>trail head symbol</description></item>
-    /// <item><term>176</term><description>truck stop symbol</description></item>
-    /// <item><term>177</term><description>user exit symbol</description></item>
-    /// <item><term>178</term><description>flag symbol</description></item>
-    /// <item><term>179</term><description>circle with x in the center</description></item>
-    /// <item><term>180</term><description>open 24 hours symbol</description></item>
-    /// <item><term>181</term><description>U fishing hot spots facility (tm)</description></item>
-    /// <item><term>182</term><description>bottom conditions</description></item>
-    /// <item><term>183</term><description>tide/current prediction station</description></item>
-    /// <item><term>184</term><description>U anchor prohibited symbol</description></item>
-    /// <item><term>185</term><description>U beacon symbol</description></item>
-    /// <item><term>186</term><description>U coast guard symbol</description></item>
-    /// <item><term>187</term><description>U reef symbol</description></item>
-    /// <item><term>188</term><description>U weedbed symbol</description></item>
-    /// <item><term>189</term><description>U dropoff symbol</description></item>
-    /// <item><term>190</term><description>U dock symbol</description></item>
-    /// <item><term>191</term><description>U marina symbol</description></item>
-    /// <item><term>192</term><description>U bait and tackle symbol</description></item>
-    /// <item><term>193</term><description>U stump symbol</description></item>
-    /// <item><term>7680</term><description>first user customisable symbol</description></item>
-    /// <item><term>8191</term><description>last user customisable symbol</description></item>
-    /// <item><term>8192</term><description>interstate hwy symbol</description></item>
-    /// <item><term>8193</term><description>us hwy symbol</description></item>
-    /// <item><term>8194</term><description>state hwy symbol</description></item>
-    /// <item><term>8195</term><description>mile marker symbol</description></item>
-    /// <item><term>8196</term><description>TracBack (feet) symbol</description></item>
-    /// <item><term>8197</term><description>golf symbol</description></item>
-    /// <item><term>8198</term><description>small city symbol</description></item>
-    /// <item><term>8199</term><description>medium city symbol</description></item>
-    /// <item><term>8200</term><description>large city symbol</description></item>
-    /// <item><term>8201</term><description>intl freeway hwy symbol</description></item>
-    /// <item><term>8202</term><description>intl national hwy symbol</description></item>
-    /// <item><term>8203</term><description>capitol city symbol (star)</description></item>
-    /// <item><term>8204</term><description>amusement park symbol</description></item>
-    /// <item><term>8205</term><description>bowling symbol</description></item>
-    /// <item><term>8206</term><description>car rental symbol</description></item>
-    /// <item><term>8207</term><description>car repair symbol</description></item>
-    /// <item><term>8208</term><description>fast food symbol</description></item>
-    /// <item><term>8209</term><description>fitness symbol</description></item>
-    /// <item><term>8210</term><description>movie symbol</description></item>
-    /// <item><term>8211</term><description>museum symbol</description></item>
-    /// <item><term>8212</term><description>pharmacy symbol</description></item>
-    /// <item><term>8213</term><description>pizza symbol</description></item>
-    /// <item><term>8214</term><description>post office symbol</description></item>
-    /// <item><term>8215</term><description>RV park symbol</description></item>
-    /// <item><term>8216</term><description>school symbol</description></item>
-    /// <item><term>8217</term><description>stadium symbol</description></item>
-    /// <item><term>8218</term><description>dept. store symbol</description></item>
-    /// <item><term>8219</term><description>zoo symbol</description></item>
-    /// <item><term>8220</term><description>convenience store symbol</description></item>
-    /// <item><term>8221</term><description>live  heatre symbol</description></item>
-    /// <item><term>8222</term><description>ramp intersection symbol</description></item>
-    /// <item><term>8223</term><description>street intersection symbol</description></item>
-    /// <item><term>8226</term><description>inspection/weigh station symbol</description></item>
-    /// <item><term>8227</term><description>toll booth symbol</description></item>
-    /// <item><term>8228</term><description>elevation point symbol</description></item>
-    /// <item><term>8229</term><description>exit without services symbol</description></item>
-    /// <item><term>8230</term><description>Geographic place name</description></item>
-    /// <item><term>8231</term><description>Geographic place name</description></item>
-    /// <item><term>8232</term><description>Geographic place name</description></item>
-    /// <item><term>8233</term><description>bridge symbol</description></item>
-    /// <item><term>8234</term><description>building symbol</description></item>
-    /// <item><term>8235</term><description>cemetery symbol</description></item>
-    /// <item><term>8236</term><description>church symbol</description></item>
-    /// <item><term>8237</term><description>civil location symbol</description></item>
-    /// <item><term>8238</term><description>crossing symbol</description></item>
-    /// <item><term>8239</term><description>historical town symbol</description></item>
-    /// <item><term>8240</term><description>levee symbol</description></item>
-    /// <item><term>8241</term><description>military location symbol</description></item>
-    /// <item><term>8242</term><description>oil field symbol</description></item>
-    /// <item><term>8243</term><description>tunnel symbol</description></item>
-    /// <item><term>8244</term><description>beach symbol</description></item>
-    /// <item><term>8245</term><description>forest symbol</description></item>
-    /// <item><term>8246</term><description>summit symbol</description></item>
-    /// <item><term>8247</term><description>large ramp intersection symbol</description></item>
-    /// <item><term>8248</term><description>large exit without services smbl</description></item>
-    /// <item><term>8249</term><description>police/official badge symbol</description></item>
-    /// <item><term>8250</term><description>gambling/casino symbol</description></item>
-    /// <item><term>8251</term><description>snow skiing symbol</description></item>
-    /// <item><term>8252</term><description>ice skating symbol</description></item>
-    /// <item><term>8253</term><description>tow truck (wrecker) symbol</description></item>
-    /// <item><term>8254</term><description>border crossing (port of entry)</description></item>
-    /// <item><term>8255</term><description>goecache location symbol</description></item>
-    /// <item><term>8256</term><description>found geocache symbol</description></item>
-    /// <item><term>8257</term><description>Rhino contact symbol, "smiley"</description></item>
-    /// <item><term>8258</term><description>Rhino contact symbol, "ball cap"</description></item>
-    /// <item><term>8259</term><description>Rhino contact symbol, "big ear"</description></item>
-    /// <item><term>8260</term><description>Rhino contact symbol, "spike"</description></item>
-    /// <item><term>8261</term><description>Rhino contact symbol, "goatee"</description></item>
-    /// <item><term>8262</term><description>Rhino contact symbol, "afro"</description></item>
-    /// <item><term>8263</term><description>Rhino contact symbol, "dreads"</description></item>
-    /// <item><term>8264</term><description>Rhino contact symbol, "female 1"</description></item>
-    /// <item><term>8265</term><description>Rhino contact symbol, "female 2" </description></item>
-    /// <item><term>8266</term><description>Rhino contact symbol, "female 3" </description></item>
-    /// <item><term>8267</term><description>Rhino contact symbol, "ranger"</description></item>
-    /// <item><term>8268</term><description>Rhino contact symbol, "kung fu"</description></item>
-    /// <item><term>8269</term><description>Rhino contact symbol, "sumo"</description></item>
-    /// <item><term>8270</term><description>Rhino contact symbol, "pirate"</description></item>
-    /// <item><term>8271</term><description>Rhino contact symbol, "biker"</description></item>
-    /// <item><term>8272</term><description>Rhino contact symbol, "alien"</description></item>
-    /// <item><term>8273</term><description>Rhino contact symbol, "bug"</description></item>
-    /// <item><term>8274</term><description>Rhino contact symbol, "cat"</description></item>
-    /// <item><term>8275</term><description>Rhino contact symbol, "dog"</description></item>
-    /// <item><term>8276</term><description>Rhino contact symbol, "pig"</description></item>
-    /// <item><term>8282</term><description>water hydrant symbol</description></item>
-    /// <item><term>8284</term><description>blue flag symbol</description></item>
-    /// <item><term>8285</term><description>green flag symbol</description></item>
-    /// <item><term>8286</term><description>red flag symbol</description></item>
-    /// <item><term>8287</term><description>blue pin symbol</description></item>
-    /// <item><term>8288</term><description>green pin symbol</description></item>
-    /// <item><term>8289</term><description>red pin symbol</description></item>
-    /// <item><term>8290</term><description>blue block symbol</description></item>
-    /// <item><term>8291</term><description>green block symbol</description></item>
-    /// <item><term>8292</term><description>red block symbol</description></item>
-    /// <item><term>8293</term><description>bike trail symbol</description></item>
-    /// <item><term>8294</term><description>red circle symbol</description></item>
-    /// <item><term>8295</term><description>green circle symbol</description></item>
-    /// <item><term>8296</term><description>blue circle symbol</description></item>
-    /// <item><term>8299</term><description>blue diamond symbol</description></item>
-    /// <item><term>8300</term><description>red oval symbol</description></item>
-    /// <item><term>8301</term><description>green oval symbol</description></item>
-    /// <item><term>8302</term><description>blue oval symbol</description></item>
-    /// <item><term>8303</term><description>red rectangle symbol</description></item>
-    /// <item><term>8304</term><description>green rectangle symbol</description></item>
-    /// <item><term>8305</term><description>blue oval symbol</description></item>
-    /// <item><term>8308</term><description>blue square symbol</description></item>
-    /// <item><term>8309</term><description>red letter "A"</description></item>
-    /// <item><term>8310</term><description>red letter "B"</description></item>
-    /// <item><term>8311</term><description>red letter "C"</description></item>
-    /// <item><term>8312</term><description>red letter "D"</description></item>
-    /// <item><term>8313</term><description>green letter "A"</description></item>
-    /// <item><term>8314</term><description>green letter "B"</description></item>
-    /// <item><term>8315</term><description>green letter "C"</description></item>
-    /// <item><term>8316</term><description>green letter "D"</description></item>
-    /// <item><term>8317</term><description>blue letter "A"</description></item>
-    /// <item><term>8318</term><description>blue letter "B"</description></item>
-    /// <item><term>8319</term><description>blue letter "C"</description></item>
-    /// <item><term>8320</term><description>blue letter "D"</description></item>
-    /// <item><term>8321</term><description>red number "0"</description></item>
-    /// <item><term>8322</term><description>red number "1"</description></item>
-    /// <item><term>8323</term><description>red number "2"</description></item>
-    /// <item><term>8324</term><description>red number "3"</description></item>
-    /// <item><term>8325</term><description>red number "4"</description></item>
-    /// <item><term>8326</term><description>red number "5"</description></item>
-    /// <item><term>8327</term><description>red number "6"</description></item>
-    /// <item><term>8328</term><description>red number "7"</description></item>
-    /// <item><term>8329</term><description>red number "8"</description></item>
-    /// <item><term>8330</term><description>red number "9"</description></item>
-    /// <item><term>8331</term><description>green number "0"</description></item>
-    /// <item><term>8332</term><description>green number "1"</description></item>
-    /// <item><term>8333</term><description>green number "2"</description></item>
-    /// <item><term>8334</term><description>green number "3"</description></item>
-    /// <item><term>8335</term><description>green number "4"</description></item>
-    /// <item><term>8336</term><description>green number "5"</description></item>
-    /// <item><term>8337</term><description>green number "6"</description></item>
-    /// <item><term>8338</term><description>green number "7"</description></item>
-    /// <item><term>8339</term><description>green number "8"</description></item>
-    /// <item><term>8340</term><description>green number "9"</description></item>
-    /// <item><term>8341</term><description>blue number "0"</description></item>
-    /// <item><term>8342</term><description>blue number "1"</description></item>
-    /// <item><term>8343</term><description>blue number "2"</description></item>
-    /// <item><term>8344</term><description>blue number "3"</description></item>
-    /// <item><term>8345</term><description>blue number "4"</description></item>
-    /// <item><term>8346</term><description>blue number "5"</description></item>
-    /// <item><term>8347</term><description>blue number "6"</description></item>
-    /// <item><term>8348</term><description>blue number "7"</description></item>
-    /// <item><term>8349</term><description>blue number "8"</description></item>
-    /// <item><term>8350</term><description>blue number "9"</description></item>
-    /// <item><term>8351</term><description>blue triangle symbol</description></item>
-    /// <item><term>8352</term><description>green triangle symbol</description></item>
-    /// <item><term>8353</term><description>red triangle symbol</description></item>
-    /// <item><term>8359</term><description>asian food symbol</description></item>
-    /// <item><term>8360</term><description>deli symbol</description></item>
-    /// <item><term>8361</term><description>italian food symbol</description></item>
-    /// <item><term>8362</term><description>seafood symbol</description></item>
-    /// <item><term>8363</term><description>steak symbol</description></item>
-    /// <item><term>16384</term><description>airport symbol</description></item>
-    /// <item><term>16385</term><description>intersection symbol</description></item>
-    /// <item><term>16386</term><description>non-directional beacon symbol</description></item>
-    /// <item><term>16387</term><description>VHF omni-range symbol</description></item>
-    /// <item><term>16388</term><description>heliport symbol</description></item>
-    /// <item><term>16389</term><description>private field symbol</description></item>
-    /// <item><term>16390</term><description>soft field symbol</description></item>
-    /// <item><term>16391</term><description>tall tower symbol</description></item>
-    /// <item><term>16392</term><description>short tower symbol</description></item>
-    /// <item><term>16393</term><description>glider symbol</description></item>
-    /// <item><term>16394</term><description>ultralight symbol</description></item>
-    /// <item><term>16395</term><description>parachute symbol</description></item>
-    /// <item><term>16396</term><description>VOR/TACAN symbol</description></item>
-    /// <item><term>16397</term><description>VOR-DME symbol</description></item>
-    /// <item><term>16398</term><description>first approach fix</description></item>
-    /// <item><term>16399</term><description>localizer outer marker</description></item>
-    /// <item><term>16400</term><description>missed approach point</description></item>
-    /// <item><term>16401</term><description>TACAN symbol</description></item>
-    /// <item><term>16402</term><description>Seaplane Base</description></item>
-    /// </list>
-    /// <br/><br/>
-    /// <para><b>
-    /// Magellan Symbol Sets (Product Id is shown in brackets)
-    /// </b></para>
-    /// <para>
-    /// This tables below show which Magellan Icons the lowercase identifiers translate to for a specific device,
-    /// the product ID, as returned by MagellaDevice.GetProductInfo.ProductId, is shown in brackets:
-    /// </para>
-    /// <para><b>Symbols Set 0</b></para>
-    /// <para><b>Colortrak (19), Tracker (23), GPS 315/320 (24), MAP 410 (25) and Sportrak (37):</b></para>
-    /// <list type="table">
-    /// <listheader><term>Raw Value (Icon property)</term><description>Symbol Description</description></listheader>
-    /// <item><term>a</term><description>filled circle</description></item>
-    /// <item><term>b</term><description>box</description></item>
-    /// <item><term>c</term><description>red buoy</description></item>
-    /// <item><term>d</term><description>green buoy</description></item>
-    /// <item><term>e</term><description>anchor</description></item>
-    /// <item><term>f</term><description>rocks</description></item>
-    /// <item><term>g</term><description>green daymark</description></item>
-    /// <item><term>h</term><description>red daymark</description></item>
-    /// <item><term>i</term><description>bell</description></item>
-    /// <item><term>j</term><description>danger</description></item>
-    /// <item><term>k</term><description>diver down</description></item>
-    /// <item><term>l</term><description>fish</description></item>
-    /// <item><term>m</term><description>house</description></item>
-    /// <item><term>n</term><description>mark</description></item>
-    /// <item><term>o</term><description>car</description></item>
-    /// <item><term>p</term><description>tent</description></item>
-    /// <item><term>q</term><description>boat</description></item>
-    /// <item><term>r</term><description>food</description></item>
-    /// <item><term>s</term><description>fuel</description></item>
-    /// <item><term>t</term><description>tree</description></item>
-    /// </list>
-    /// <br/><br/>
-    /// <para><b>Symbols Set 1</b></para>
-    /// <para><b>NAV 6000 (18):</b></para>
-    /// <list type="table">
-    /// <listheader><term>Raw Value (Icon property)</term><description>Symbol Description</description></listheader>
-    /// <item><term>a</term><description>filled circle</description></item>
-    /// <item><term>b</term><description>fish</description></item>
-    /// <item><term>c</term><description>buoy</description></item>
-    /// <item><term>d</term><description>light</description></item>
-    /// <item><term>e</term><description>anchor</description></item>
-    /// <item><term>f</term><description>flag</description></item>
-    /// <item><term>g</term><description>red daymark</description></item>
-    /// <item><term>h</term><description>green daymark</description></item>
-    /// <item><term>i</term><description>wreck</description></item>
-    /// <item><term>j</term><description>house</description></item>
-    /// <item><term>k</term><description>boat</description></item>
-    /// <item><term>l</term><description>fuel</description></item>
-    /// <item><term>m</term><description>danger</description></item>
-    /// <item><term>n</term><description>diver down</description></item>
-    /// <item><term>o</term><description>food</description></item>
-    /// <item><term>p</term><description>w</description></item>
-    /// <item><term>q</term><description>l</description></item>
-    /// <item><term>r</term><description>r</description></item>
-    /// </list>
-    /// <br/><br/>
-    /// <para><b>Symbols Set 2</b></para>
-    /// <para><b>Meridian XL (5):</b></para>
-    /// <list type="table">
-    /// <listheader><term>Raw Value (Icon property)</term><description>Symbol Description</description></listheader>
-    /// <item><term>a</term><description>filled circle</description></item>
-    /// <item><term>b</term><description>flag right</description></item>
-    /// <item><term>c</term><description>flag left</description></item>
-    /// <item><term>d</term><description>diamond</description></item>
-    /// <item><term>e</term><description>square</description></item>
-    /// <item><term>f</term><description>filled square</description></item>
-    /// <item><term>g</term><description>anchor</description></item>
-    /// <item><term>h</term><description>banner</description></item>
-    /// <item><term>i</term><description>fish</description></item>
-    /// <item><term>j</term><description>crosshair</description></item>
-    /// </list>
-    /// <br/><br/>
-    /// <para><b>Symbols Set 3</b></para>
-    /// <para><b>Trailblazer XL (7):</b></para>
-    /// <list type="table">
-    /// <listheader><term>Raw Value (Icon property)</term><description>Symbol Description</description></listheader>
-    /// <item><term>a</term><description>filled circle</description></item>
-    /// <item><term>b</term><description>flag right</description></item>
-    /// <item><term>c</term><description>flag left</description></item>
-    /// <item><term>d</term><description>diamond</description></item>
-    /// <item><term>e</term><description>square</description></item>
-    /// <item><term>f</term><description>filled square</description></item>
-    /// <item><term>g</term><description>anchor</description></item>
-    /// <item><term>h</term><description>banner</description></item>
-    /// <item><term>i</term><description>fish</description></item>
-    /// <item><term>j</term><description>crosshair</description></item>
-    /// <item><term>k</term><description>car</description></item>
-    /// <item><term>l</term><description>house</description></item>
-    /// <item><term>m</term><description>wine glass</description></item>
-    /// <item><term>n</term><description>mountain</description></item>
-    /// <item><term>o</term><description>sign</description></item>
-    /// <item><term>p</term><description>tree</description></item>
-    /// <item><term>q</term><description>water</description></item>
-    /// <item><term>r</term><description>airplane</description></item>
-    /// <item><term>s</term><description>deer�s head</description></item>
-    /// </list>
-    /// <br/><br/>
-    /// <para><b>Symbols Set 4</b></para>
-    /// <para><b>MAP 330 (30), ProMark 2 (35), Meridian New (33), Sportrak Map/Pro (36):</b></para>
-    /// <list type="table">
-    /// <listheader><term>Raw Value (Icon property)</term><description>Symbol Description</description></listheader>
-    /// <item><term>a</term><description>crossed square</description></item>
-    /// <item><term>b</term><description>box</description></item>
-    /// <item><term>c</term><description>house</description></item>
-    /// <item><term>d</term><description>aerial</description></item>
-    /// <item><term>e</term><description>airport</description></item>
-    /// <item><term>f</term><description>amusement park</description></item>
-    /// <item><term>g</term><description>ATM</description></item>
-    /// <item><term>h</term><description>auto repair</description></item>
-    /// <item><term>i</term><description>boating</description></item>
-    /// <item><term>j</term><description>camping</description></item>
-    /// <item><term>k</term><description>exit ramp</description></item>
-    /// <item><term>l</term><description>first aid</description></item>
-    /// <item><term>m</term><description>nav aid</description></item>
-    /// <item><term>n</term><description>buoy</description></item>
-    /// <item><term>o</term><description>fuel</description></item>
-    /// <item><term>p</term><description>garden</description></item>
-    /// <item><term>q</term><description>golf</description></item>
-    /// <item><term>r</term><description>hotel</description></item>
-    /// <item><term>s</term><description>hunting/fishing</description></item>
-    /// <item><term>t</term><description>large city</description></item>
-    /// <item><term>u</term><description>lighthouse</description></item>
-    /// <item><term>v</term><description>major city</description></item>
-    /// <item><term>w</term><description>marina</description></item>
-    /// <item><term>x</term><description>medium city</description></item>
-    /// <item><term>y</term><description>museum</description></item>
-    /// <item><term>z</term><description>obstruction</description></item>
-    /// <item><term>aa</term><description>park</description></item>
-    /// <item><term>ab</term><description>resort</description></item>
-    /// <item><term>ac</term><description>restaurant</description></item>
-    /// <item><term>ad</term><description>rock</description></item>
-    /// <item><term>ae</term><description>scuba</description></item>
-    /// <item><term>af</term><description>RV service</description></item>
-    /// <item><term>ag</term><description>shooting</description></item>
-    /// <item><term>ah</term><description>sight seeing</description></item>
-    /// <item><term>ai</term><description>small city</description></item>
-    /// <item><term>aj</term><description>sounding</description></item>
-    /// <item><term>ak</term><description>sports arena</description></item>
-    /// <item><term>al</term><description>tourist info</description></item>
-    /// <item><term>am</term><description>truck service</description></item>
-    /// <item><term>an</term><description>winery</description></item>
-    /// <item><term>ao</term><description>wreck</description></item>
-    /// <item><term>ap</term><description>zoo</description></item>
-    ///</list>
-    /// <br/><br/>
-    /// <para><b>Magellan Devices</b></para>
-    /// <para>The following Properties are normally used by the Magellan devices. 
-    /// However when Waypoints form part of a route some may not be.
-    /// </para>
-    /// <list type="table">
-    /// <item><term>Identifier</term><description>String</description></item>
-    /// <item><term>Latitude</term><description>Double</description></item>
-    /// <item><term>Longitude</term><description>Double</description></item>
-    /// <item><term>Comment</term><description>String</description></item>
-    /// <item><term>Icon</term><description>String</description></item>
-    /// <item><term>Altitude</term><description>Single</description></item>
-    /// </list>
-    /// <br/><br/>
-    /// <para><b>Garmin Devices</b></para>
-    /// <para>
-	/// In most cases not all of the Properties of the Waypoint object are used. The Properties
-	/// actually used are determined by the protocol employed by the connected GPS Device.
-	/// Below is a list of which Properties are supported by Protocol. Please note that even though a
-	/// Property is identified as being supported does not mean that it will actually be used/populated.
-	/// </para>
-	/// <br/><br/>
-	/// <para>
-	/// <b>Protocol D100</b>
-	/// </para>
-	/// <list type="table">
-	/// <listheader><term>Property</term><description>Type</description></listheader>
-	/// <item><term>Identifier</term><description>String</description></item>
-	/// <item><term>Latitude</term><description>Double</description></item>
-	/// <item><term>Longitude</term><description>Double</description></item>
-	/// <item><term>Comment</term><description>String</description></item>
-	/// </list>
-	/// <br/><br/>
-	/// <para>
-	/// <b>Protocol D101</b>
-	/// </para>
-	/// <list type="table">
-	/// <listheader><term>Property</term><description>Type</description></listheader>
-	/// <item><term>Identifier</term><description>String</description></item>
-	/// <item><term>Latitude</term><description>Double</description></item>
-	/// <item><term>Longitude</term><description>Double</description></item>
-	/// <item><term>Comment</term><description>String</description></item>