public ConversionResults TryConvert(string str)
    {
        //some local variables
            int sign; //sign of the coordinate
            string[] DecimalBit, DdMmSs, DdMm; //arrays for splitting
            double Dd = 0, Mm = 0, Ss = 0, Mmm = 0, Sss = 0, Dec = 0; //parts of the coordinates

            char DecSeparator = char.Parse(GetDecimalSeparator()); //gets the current decimal separator

            Regex TempRegex; //regular expression object for 'on demand' patern matching

            ConversionResults results = new ConversionResults();

            //Get the matched pattern
            string[] pattern;
            int ptrnnum = MatchPattern(str);
            if (ptrnnum != -1)
            {
                pattern = (string[])patterns[ptrnnum];
            }
            else
            {
                pattern = new string[2];
                pattern[0] = "Unknown";
                pattern[1] = "No pattern matched";
            }

            switch (pattern[0]) //pattern[0] holds patern name
            {
                default: //pattern not recognised

                    results.PatternRecognised = false;
                    results.PatternType = pattern[0];
                    results.PatternMatched = pattern[1];

                    results.ConversionSuccessful = false;
                    results.ConvertedCoord = 99999; //this is to mark an error...

                    results.ConversionComments = "Coordinate pattern not recognised!";

                    break;

                case "Variation of DD.DDD":

                    //Pattern matched
                    results.PatternRecognised = true;

                    //Matching pattern succeeded so intialy the parsing is ok
                    results.ConversionSuccessful = true;

                    //pattern info
                    results.PatternType = pattern[0];
                    results.PatternMatched = pattern[1];

                    //get sign
                    sign = GetSign(str);

                    //Replace comma or dot with a current decimal separator
                    str = FixDecimalSeparator(str);

                    //Remove all the unwanted stuff
                    str = RemoveSign(str);
                    str = RemoveWhiteSpace(str);

                    //Since this is already a decimal degree no spliting is needed
                    Dd = double.Parse(str);

                    //do some additional checking if the coords fall into the range
                    if (Dd < -180 | Dd > 180)//degree may require another param specifying whether it's lat or lon...
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Degrees fall outside the range: DD < -180 | DD > 180; ";
                    }

                    //Do the conversion if everything ok
                    if (results.ConversionSuccessful)
                    {
                        results.ConversionComments = "Conversion successful.";

                        Dec = sign * Dd;
                        results.ConvertedCoord = Dec;

                        //Check whether the coordinate exceeds +/- 90 and mark it in comments
                        if (Dec <= 90 & Dec >= -90) { results.CanBeLat = true; }
                    }

                    break;

                case "Variation of DD(°|d)MM.MMM('|m)":

                    //Pattern matched
                    results.PatternRecognised = true;

                    //Matching pattern succeeded so intialy the parsing is ok
                    results.ConversionSuccessful = true;

                    //pattern info
                    results.PatternType = pattern[0];
                    results.PatternMatched = pattern[1];

                    //get sign
                    sign = GetSign(str);

                    //Replace comma or dot with a current decimal separator
                    str = FixDecimalSeparator(str);

                    //Remove all the unwanted stuff
                    str = RemoveSign(str);
                    str = RemoveWhiteSpace(str);

                    //do some further replacing
                    //Replace degree symbol
                    TempRegex = new Regex("(°|º|D|d)");
                    str = TempRegex.Replace(str, ":");

                    //remove minute symbol
                    TempRegex = new Regex("(ʹ|'|M|m)");
                    str = TempRegex.Replace(str, "");

                    //Extract decimal part
                    DecimalBit = str.Split(DecSeparator);

                    //split degrees and minutes
                    DdMm = DecimalBit[0].Split(':');

                    //extract values from the strings
                    Dd = int.Parse(DdMm[0]); //Degrees

                    if (DdMm.Length > 1)//Minutes
                    {
                        //check if the string is not empty
                        if (DdMm[1] != "") { Mm = int.Parse(DdMm[1]); }
                    }

                    if (DecimalBit.Length > 1)//DecimalSeconds
                    {
                        //check if the string is not empty
                        if (DecimalBit[1] != "")
                        {
                            Mmm = double.Parse(DecimalBit[1]) / Math.Pow(10, (DecimalBit[1].Length));
                        }
                    }

                    //do some additional checking if the coords fall into the range
                    if (Dd < -180 | Dd > 180)//degree may require another param specifying whether it's lat or lon...
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Degrees fall outside the range: DD < -180 | DD > 180; ";
                    }
                    if (Mm > 59) //minutes
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Minutes fall outside the range: MM > 59; ";
                    }

                    //Do the conversion if everything ok
                    if (results.ConversionSuccessful)
                    {

                        Dec = sign * (Dd + (Mm + Mmm) / 60);

                        //one more check to ensure a coord does not exceed 180
                        if (Dec > 180 | Dec < -180)
                        {
                            results.ConversionSuccessful = false;
                            results.ConvertedCoord = 99999; //this is to mark an error...
                            results.ConversionComments += "Coordinate is either > 180 or < -180; ";
                        }
                        else
                        {
                            results.ConvertedCoord = Dec;

                            results.ConversionComments = "Conversion successful.";

                            //Check whether the coordinate exceeds +/- 90 and mark it in comments
                            if (Dec <= 90 & Dec >= -90) { results.CanBeLat = true; }
                        }
                    }

                    break;

                case "Variation of DD(°|d)MM(ʹ|m)SS.SSS(ʺ|s)":

                    /*
                     * Note:
                     * This pattern allows the seconds to be specified with S, s or " or nothing at all
                     * If the seconds are marked with "s" and there is no other indication of the hemisphere
                     * the coordinate will be parsed as southern (negative).
                     *
                     * If the N / E / W / + indicator is found the coordinate will be parsed appropriately no matter
                     * what is the second notation
                    */

                    //Pattern matched
                    results.PatternRecognised = true;

                    //Matching pattern succeeded so intialy the parsing is ok
                    results.ConversionSuccessful = true;

                    //pattern info
                    results.PatternType = pattern[0];
                    results.PatternMatched = pattern[1];

                    //get sign
                    sign = GetSign(str);

                    //Replace comma or dot with a current decimal separator
                    str = FixDecimalSeparator(str);

                    //Remove all the unwanted stuff
                    str = RemoveSign(str);
                    str = RemoveWhiteSpace(str);

                    //remove second symbol (s is removed by the get sign method)
                    //double apostrophe is not removed here as single apostrphe may mark minutes!
                    //it's taken care of later after extracting the decimal part
                    TempRegex = new Regex("(ʺ|\")");
                    str = TempRegex.Replace(str, "");

                    //do some further replacing
                    //Replace degree symbol
                    TempRegex = new Regex("(°|º|D|d|ʹ|'|M|m)");
                    str = TempRegex.Replace(str, ":");

                    //Extract decimal part
                    DecimalBit = str.Split(DecSeparator);

                    //remove : from the decimal part [1]! This is needed when a double apostrophe was used to mark seconds
                    if (DecimalBit.Length > 1)
                    {
                        DecimalBit[1].Replace(":", "");
                    }

                    //split degrees and minutes
                    DdMmSs = DecimalBit[0].Split(':');

                    //extract values from the strings
                    Dd = int.Parse(DdMmSs[0]); //Degrees
                    if (DdMmSs.Length > 1)//Minutes
                    {
                        //check if the string is not empty
                        if (DdMmSs[1] != "") { Mm = int.Parse(DdMmSs[1]); }
                    }
                    if (DdMmSs.Length > 2)//Seconds
                    {
                        //check if the string is not empty
                        if (DdMmSs[2] != "") { Ss = int.Parse(DdMmSs[2]); }
                    }
                    if (DecimalBit.Length > 1)//DecimalSeconds
                    {
                        //check if the string is not empty
                        if (DecimalBit[1] != "")
                        {
                            Sss = double.Parse(DecimalBit[1]) / Math.Pow(10, (DecimalBit[1].Length));
                        }
                    }

                    //do some additional checking if the coords fall into the range
                    if (Dd < -180 | Dd > 180)//degree may require another param specifying whether it's lat or lon...
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Degrees fall outside the range: DD < -180 | DD > 180; ";
                    }
                    if (Mm > 59) //minutes
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Minutes fall outside the range: MM > 59; ";
                    }
                    if (Ss > 59) //seconds
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Seconds fall outside the range: MM >= 60; ";
                    }

                    //Do the conversion if everything ok
                    if (results.ConversionSuccessful)
                    {
                        results.ConversionComments = "Conversion successful.";

                        Dec = sign * (Dd + Mm / 60 + (Ss + Sss) / 3600);

                        //one more check to ensure a coord does not exceed 180
                        if (Dec > 180 | Dec < -180)
                        {
                            results.ConversionSuccessful = false;
                            results.ConvertedCoord = 99999; //this is to mark an error...
                            results.ConversionComments += "Coordinate is either > 180 or < -180; ";
                        }
                        else
                        {
                            results.ConvertedCoord = Dec;

                            results.ConversionComments = "Conversion successful.";

                            //Check whether the coordinate exceeds +/- 90 and mark it in comments
                            if (Dec <= 90 & Dec >= -90) { results.CanBeLat = true; }
                        }
                    }
                    break;

                case "Variation of DD:MM:SS.SSS":

                    //Pattern matched
                    results.PatternRecognised = true;

                    //Matching pattern succeeded so intialy the parsing is ok
                    results.ConversionSuccessful = true;

                    //pattern info
                    results.PatternType = pattern[0];
                    results.PatternMatched = pattern[1];

                    //get sign
                    sign = GetSign(str);

                    //Replace comma or dot with a current decimal separator
                    str = FixDecimalSeparator(str);

                    //Remove all the unwanted stuff
                    str = RemoveSign(str);
                    str = RemoveWhiteSpace(str);

                    //Do some splitting
                    DecimalBit = str.Split(DecSeparator);
                    DdMmSs = DecimalBit[0].Split(':');

                    //extract values from the strings
                    Dd = int.Parse(DdMmSs[0]); //Degrees
                    if (DdMmSs.Length > 1)//Minutes
                    {
                        //check if the string is not empty
                        if (DdMmSs[1] != "") { Mm = int.Parse(DdMmSs[1]); }
                    }
                    if (DdMmSs.Length > 2)//Seconds
                    {
                        //check if the string is not empty
                        if (DdMmSs[2] != "") { Ss = int.Parse(DdMmSs[2]); }
                    }
                    if (DecimalBit.Length > 1)//DecimalSeconds
                    {
                        //check if the string is not empty
                        if (DecimalBit[1] != "")
                        {
                            Sss = double.Parse(DecimalBit[1]) / Math.Pow(10, (DecimalBit[1].Length));
                        }
                    }

                    //do some additional checking if the coords fall into the range
                    if (Dd < -180 | Dd > 180)//degree may require another param specifying whether it's lat or lon...
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Degrees fall outside the range: DD < -180 | DD > 180; ";
                    }
                    if (Mm > 59) //minutes
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Minutes fall outside the range: MM > 59; ";
                    }
                    if (Ss > 59) //seconds
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Seconds fall outside the range: MM >= 60; ";
                    }

                    //Do the conversion if everything ok
                    if (results.ConversionSuccessful)
                    {
                        results.ConversionComments = "Conversion successful.";

                        Dec = sign * (Dd + Mm / 60 + (Ss + Sss) / 3600);

                        //one more check to ensure a coord does not exceed 180
                        if (Dec > 180 | Dec < -180)
                        {
                            results.ConversionSuccessful = false;
                            results.ConvertedCoord = 99999; //this is to mark an error...
                            results.ConversionComments += "Coordinate is either > 180 or < -180; ";
                        }
                        else
                        {
                            results.ConvertedCoord = Dec;

                            results.ConversionComments = "Conversion successful.";

                            //Check whether the coordinate exceeds +/- 90 and mark it in comments
                            if (Dec <= 90 & Dec >= -90) { results.CanBeLat = true; }
                        }
                    }

                    break;

                //-------------Customs patterns start here-------------

                case "Custom variation of DD.DDD":

                    //Pattern matched
                    results.PatternRecognised = true;

                    //Matching pattern succeeded so intialy the parsing is ok
                    results.ConversionSuccessful = true;

                    //pattern info
                    results.PatternType = pattern[0];
                    results.PatternMatched = pattern[1];

                    //get sign
                    sign = GetCustomSign(str);

                    //Remove all the unwanted stuff
                    //Note: This method also replaces the symbols with ":"
                    //Note: In certain cases it may make the coord unparsable
                    str = RemoveCustomPatternParts(str);

                    str = RemoveWhiteSpace(str);

                    //Replace comma or dot with a current decimal separator
                    str = FixDecimalSeparator(str);

                    //remove the ":" here as it is not needed here for decimal degrees
                    str = str.Replace(":", "");

                    try
                    {
                        //Since this is already a decimal degree no spliting is needed
                        Dd = double.Parse(str);
                    }
                    catch
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments =
                            "It looks like the supplied pattern has some ambiguous elements and the parser was unable to parse the coordinate." +
                            "<br/>If the supplied symbols used for marking degrees, minutes or seconds contain hemisphere indicators, " +
                            "the parser is likely to fail or yield rubbish results even though the pattern itself has been recognised."
                            ;

                        //exit method
                        return results;
                    }

                    //Since this is already a decimal degree no spliting is needed
                    Dd = double.Parse(str);

                    //do some additional checking if the coords fall into the range
                    if (Dd < -180 | Dd > 180)//degree may require another param specifying whether it's lat or lon...
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Degrees fall outside the range: DD < -180 | DD > 180; ";
                    }

                    //Do the conversion if everything ok
                    if (results.ConversionSuccessful)
                    {
                        results.ConversionComments = "Conversion successful.";

                        Dec = sign * Dd;
                        results.ConvertedCoord = Dec;

                        //Check whether the coordinate exceeds +/- 90 and mark it in comments
                        if (Dec <= 90 & Dec >= -90) { results.CanBeLat = true; }
                    }

                    break;

                case "Custom variation of DD:MM.MMM":

                    //Pattern matched
                    results.PatternRecognised = true;

                    //Matching pattern succeeded so intialy the parsing is ok
                    results.ConversionSuccessful = true;

                    //pattern info
                    results.PatternType = pattern[0];
                    results.PatternMatched = pattern[1];

                    //get sign
                    sign = GetCustomSign(str);

                    //Remove all the unwanted stuff
                    //Note: This method also replaces the symbols with ":"
                    //Note: In certain cases it may make the coord unparsable
                    str = RemoveCustomPatternParts(str);

                    str = RemoveWhiteSpace(str);

                    //Replace comma or dot with a current decimal separator
                    str = FixDecimalSeparator(str);

                    //Extract decimal part
                    DecimalBit = str.Split(DecSeparator);

                    //split degrees and minutes
                    DdMm = DecimalBit[0].Split(':');

                    try
                    {
                        //extract values from the strings
                        Dd = int.Parse(DdMm[0]); //Degrees

                        if (DdMm.Length > 1)//Minutes
                        {
                            //check if the string is not empty
                            if (DdMm[1] != "") { Mm = int.Parse(DdMm[1]); }
                        }

                        if (DecimalBit.Length > 1)//DecimalSeconds
                        {
                            //check if the string is not empty
                            if (DecimalBit[1] != "")
                            {
                                //replace the ":" if any (may be here as a result of custom symbol replacement
                                DecimalBit[1] = DecimalBit[1].Replace(":", "");

                                Mmm = double.Parse(DecimalBit[1]) / Math.Pow(10, (DecimalBit[1].Length));
                            }
                        }
                    }
                    catch
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments =
                            "It looks like the supplied pattern has some ambiguous elements and the parser was unable to parse the coordinate." +
                            "<br/>If the supplied symbols used for marking degrees, minutes or seconds contain hemisphere indicators, " +
                            "the parser is likely to fail or yield rubbish results even though the pattern itself has been recognised."
                            ;

                        //exit method
                        return results;
                    }

                    //do some additional checking if the coords fall into the range
                    if (Dd < -180 | Dd > 180)//degree may require another param specifying whether it's lat or lon...
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Degrees fall outside the range: DD < -180 | DD > 180; ";
                    }
                    if (Mm > 59) //minutes
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Minutes fall outside the range: MM > 59; ";
                    }

                    //Do the conversion if everything ok
                    if (results.ConversionSuccessful)
                    {

                        Dec = sign * (Dd + (Mm + Mmm) / 60);

                        //one more check to ensure a coord does not exceed 180
                        if (Dec > 180 | Dec < -180)
                        {
                            results.ConversionSuccessful = false;
                            results.ConvertedCoord = 99999; //this is to mark an error...
                            results.ConversionComments += "Coordinate is either > 180 or < -180; ";
                        }
                        else
                        {
                            results.ConvertedCoord = Dec;

                            results.ConversionComments = "Conversion successful.";

                            //Check whether the coordinate exceeds +/- 90 and mark it in comments
                            if (Dec <= 90 & Dec >= -90) { results.CanBeLat = true; }
                        }
                    }

                    break;

                case "Custom variation of DD:MM:SS.SSS":

                    //Pattern matched
                    results.PatternRecognised = true;

                    //Matching pattern succeeded so intialy the parsing is ok
                    results.ConversionSuccessful = true;

                    //pattern info
                    results.PatternType = pattern[0];
                    results.PatternMatched = pattern[1];

                    //get sign
                    sign = GetCustomSign(str);

                    //Remove all the unwanted stuff
                    //Note: This method also replaces the symbols with ":"
                    //Note: In certain cases it may make the coord unparsable
                    str = RemoveCustomPatternParts(str);

                    str = RemoveWhiteSpace(str);

                    //Replace comma or dot with a current decimal separator
                    str = FixDecimalSeparator(str);

                    //Extract decimal part
                    DecimalBit = str.Split(DecSeparator);

                    //split degrees and minutes
                    DdMmSs = DecimalBit[0].Split(':');

                    try
                    {

                        //extract values from the strings
                        Dd = int.Parse(DdMmSs[0]); //Degrees
                        if (DdMmSs.Length > 1)//Minutes
                        {
                            //check if the string is not empty
                            if (DdMmSs[1] != "") { Mm = int.Parse(DdMmSs[1]); }
                        }
                        if (DdMmSs.Length > 2)//Seconds
                        {
                            //check if the string is not empty
                            if (DdMmSs[2] != "") { Ss = int.Parse(DdMmSs[2]); }
                        }
                        if (DecimalBit.Length > 1)//DecimalSeconds
                        {
                            //check if the string is not empty
                            if (DecimalBit[1] != "")
                            {
                                Sss = double.Parse(DecimalBit[1]) / Math.Pow(10, (DecimalBit[1].Length));
                            }
                        }
                    }
                    catch
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments =
                            "It looks like the supplied pattern has some ambiguous elements and the parser was unable to parse the coordinate." +
                            "<br/>If the supplied symbols used for marking degrees, minutes or seconds contain hemisphere indicators, " +
                            "the parser is likely to fail or yield rubbish results even though the pattern itself has been recognised."
                            ;

                        //exit method
                        return results;
                    }

                    //do some additional checking if the coords fall into the range
                    if (Dd < -180 | Dd > 180)//degree may require another param specifying whether it's lat or lon...
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Degrees fall outside the range: DD < -180 | DD > 180; ";
                    }
                    if (Mm > 59) //minutes
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Minutes fall outside the range: MM > 59; ";
                    }
                    if (Ss > 59) //seconds
                    {
                        results.ConversionSuccessful = false;
                        results.ConvertedCoord = 99999; //this is to mark an error...
                        results.ConversionComments += "Seconds fall outside the range: MM >= 60; ";
                    }

                    //Do the conversion if everything ok
                    if (results.ConversionSuccessful)
                    {
                        results.ConversionComments = "Conversion successful.";

                        Dec = sign * (Dd + Mm / 60 + (Ss + Sss) / 3600);

                        //one more check to ensure a coord does not exceed 180
                        if (Dec > 180 | Dec < -180)
                        {
                            results.ConversionSuccessful = false;
                            results.ConvertedCoord = 99999; //this is to mark an error...
                            results.ConversionComments += "Coordinate is either > 180 or < -180; ";
                        }
                        else
                        {
                            results.ConvertedCoord = Dec;

                            results.ConversionComments = "Conversion successful.";

                            //Check whether the coordinate exceeds +/- 90 and mark it in comments
                            if (Dec <= 90 & Dec >= -90) { results.CanBeLat = true; }
                        }
                    }

                    break;

            }

            //do the self check here
            results = selfTest(results);

            //return conversion results
            return results;
    }
    private ConversionResults selfTest(ConversionResults results)
    {
        ConversionResults newresults = results;

            if (results.ConversionSuccessful != false)
            {
                int sign = 1;
                if (Math.Sign(results.ConvertedCoord) < 0) { sign = -1; }

                double decimalDegrees = sign * results.ConvertedCoord;
                int fullDegrees;

                double decimalMinutes;
                int fullMinutes;

                double decimalSeconds;
                int fullSeconds;

                //Get full degrees
                fullDegrees = (int)Math.Floor(decimalDegrees);

                //get minutes
                decimalMinutes = (decimalDegrees - fullDegrees) * 60;
                fullMinutes = (int)Math.Floor(decimalMinutes);

                decimalSeconds = (decimalMinutes - fullMinutes) * 60;
                fullSeconds = (int)Math.Floor(decimalSeconds);

                //save the test results
                newresults.Dd = fullDegrees;
                newresults.Mm = fullMinutes;
                newresults.Mmm = decimalSeconds;
                newresults.Ss = fullSeconds;
                newresults.Sss = decimalSeconds;

            }

            return newresults;
    }