public GedcomLineData DecodeLine()
        {
            int  parsePos = 0;
            bool failure  = false;

            if (linePos == 0)
            {
                lineNo++;
                return(null);
            }
            //trace.TraceInformation("DecodeLine start");

            lineData = new GedcomLineData();


            if (trace.Switch.Level.HasFlag(SourceLevels.Information))
            {
                DebugStringAdd("Line:" + lineNo + " [line start]");
                for (int i = 0; i < linePos; i++)
                {
                    DebugStringAdd(lineBuffer[i].ToString());
                }
                DebugStringAdd("");
                DebugStringAdd("[line end]");
            }

            tempString = "";

            while (parser.IsBlankChar(lineBuffer[parsePos]))
            {
                parsePos++;
            }
            while (!parser.IsBlankChar(lineBuffer[parsePos]))
            {
                tempString += lineBuffer[parsePos++];
            }
            lineData.level = DecodeLevelString(tempString, ref failure);

            while (parser.IsBlankChar(lineBuffer[parsePos]))
            {
                parsePos++;
            }
            if (lineBuffer[parsePos] == '@')
            {
                tempString = "";

                while (!parser.IsBlankChar(lineBuffer[parsePos]))
                {
                    tempString += lineBuffer[parsePos++];
                }
                if (!DecodeXrefString(tempString))
                {
                    DebugStringAdd("Line:" + lineNo + " invalid xref id string!");
                    failure = true;
                }
                while (parser.IsBlankChar(lineBuffer[parsePos]))
                {
                    parsePos++;
                }
            }
            tempString = "";
            while (!parser.IsBlankChar(lineBuffer[parsePos]) && (parsePos < linePos))
            {
                tempString += lineBuffer[parsePos++];
            }
            if (!DecodeTagString(tempString) && !failure)
            {
                DebugStringAdd("Line:" + lineNo + " invalid tag!");
                failure = true;
            }
            tempString = "";

            // Only eat first blank character in value part.
            if (parser.IsBlankChar(lineBuffer[parsePos]))
            {
                parsePos++;
            }
            while (parsePos < linePos)
            {
                tempString += lineBuffer[parsePos++];
            }
            if (!DecodeValueString(tempString) && !failure)
            {
                DebugStringAdd("Line:" + lineNo + " invalid value!");
                failure = true;
            }
            if ((lineData.tagString.Length < 3) && !failure)
            {
                DebugStringAdd("Line:" + lineNo + " invalid tag: " + lineData.tagString);
                failure = true;
            }
            if (!failure)
            {
                lineData.valid = true;
            }
            lineData.lineNo = lineNo;
            linePos         = 0;
            lineNo++;

            if (trace.Switch.Level.HasFlag(SourceLevels.Information))
            {
                lineData.Print();
            }

            return(lineData);
        }