Inheritance: ScanBase, IColorScan
 public AsmHighlighterScanner(IAsmHighlighterTokenProvider tokenProvider)
 {
     lex = new Scanner();
     lex.AsmHighlighterTokenProvider = tokenProvider;
 }
        /*
        public class X86TextSpan
        {
            public X86TextSpan(int start, int end)
            {
                Start = start;
                End = end;
            }

            public int Start { get; set; }
            public int End { get; set; }
        }

        public class X86Instruction : X86TextSpan
        {
            public X86Instruction(int start, int end, string name, AsmHighlighterToken type) : base(start, end)
            {
                Name = name;
                Type = type;
            }

            public string Name { get; set; }
            public AsmHighlighterToken Type { get; set; }
        }

        public class X86Code
        {
            public X86Instruction Instruction { get; set; }

        }

        public X86Code Parse(Scanner lexer, string codeToParse)
        {
            lexer.SetSource(codeToParse, 0);
            int state = 0;
            int start, end;

            AsmHighlighterToken token = (AsmHighlighterToken)lexer.GetNext(ref state, out start, out end);
            List<EditSpan> changes = new List<EditSpan>();
            while (token != AsmHighlighterToken.EOF)
            {
                bool isToStrip = false;
                string stripReplace = "";
                string tokenStr = codeToParse.Substring(start, end - start + 1).ToLower();
                switch (token)
                {
                    case AsmHighlighterToken.INSTRUCTION:
                        if (tokenStr == "call" || tokenStr.StartsWith("j"))
                        {
                            string restOfLine = codeToParse.Substring(end + 1, codeToParse.Length - (end + 1)).Trim();
                            // Default call|jmp dword
                            if (!restOfLine.StartsWith("dword") && !restOfLine.StartsWith("short"))
                            {
                                isToStrip = true;
                                stripReplace = tokenStr + " dword";
                            }
                        }
                        break;
                    case AsmHighlighterToken.LEFT_SQUARE_BRACKET:

                        break;
                    case AsmHighlighterToken.RIGHT_SQUARE_BRACKET:

                        break;
                    case AsmHighlighterToken.REGISTER:
                        if (tokenStr.StartsWith("st("))
                        {
                            tokenStr = tokenStr.Replace("(", "");
                            tokenStr = tokenStr.Replace(")", "");
                            isToStrip = true;
                            stripReplace = tokenStr;
                        }
                        break;
                    case AsmHighlighterToken.DIRECTIVE:
                        // strip register
                        if (tokenStr == "ptr")
                        {
                            isToStrip = true;
                            stripReplace = "";
                        }
                        break;

                    case AsmHighlighterToken.IDENTIFIER:
                        // Convert all identifiers to 0 in order to be able to compile the code
                        isToStrip = true;
                        stripReplace = "125125";
                        break;
                }
                if (isToStrip)
                {
                    TextSpan editTextSpan = new TextSpan();
                    editTextSpan.iStartLine = 0;
                    editTextSpan.iEndLine = 0;
                    editTextSpan.iStartIndex = start;
                    editTextSpan.iEndIndex = end + 1;

                    changes.Add(new EditSpan(editTextSpan, stripReplace));
                }
                token = (AsmHighlighterToken)lexer.GetNext(ref state, out start, out end);
            }
            return null;
        }
        */
        public static string ConvertToFasm(Scanner lexer, string codeToFormat, Dictionary<string, string> defines)
        {
            lexer.SetSource(codeToFormat, 0);
            int state = 0;
            int start, end;

            bool isInBracket = false;
            int countRegisterInBracket = 0;
            AsmHighlighterToken token = (AsmHighlighterToken)lexer.GetNext(ref state, out start, out end);
            List<EditSpan> changes = new List<EditSpan>();
            while (token != AsmHighlighterToken.EOF)
            {
                bool isToStrip = false;
                string stripReplace = "";

                string tokenStr = codeToFormat.Substring(start, end - start + 1).ToLower();
                switch (token)
                {
                    case AsmHighlighterToken.INSTRUCTION:
                        if ( tokenStr == "call" || tokenStr.StartsWith("j"))
                        {
                            string restOfLine = codeToFormat.Substring(end + 1, codeToFormat.Length - (end + 1)).Trim();
                            // Set default call|jxx to dword
                            if (!restOfLine.StartsWith("dword") && !restOfLine.StartsWith("short") && !restOfLine.StartsWith("near") && !restOfLine.StartsWith("far"))
                            {
                                isToStrip = true;
                                stripReplace = tokenStr + " dword";
                            }
                        }
                        break;
                    case AsmHighlighterToken.LEFT_SQUARE_BRACKET:
                        isInBracket = true;
                        break;
                    case AsmHighlighterToken.RIGHT_SQUARE_BRACKET:
                        isInBracket = false;
                        countRegisterInBracket = 0;
                        break;
                    case AsmHighlighterToken.REGISTER:
                    case AsmHighlighterToken.REGISTER_FPU:
                    case AsmHighlighterToken.REGISTER_MMXSSE:
                        if (isInBracket)
                        {
                            countRegisterInBracket++;
                        }
                        // Convert st(#) register to st#
                        if (token == AsmHighlighterToken.REGISTER_FPU)
                        {
                            tokenStr = tokenStr.Replace("(", "");
                            tokenStr = tokenStr.Replace(")", "");
                            isToStrip = true;
                            stripReplace = tokenStr;
                        }
                        break;
                    case AsmHighlighterToken.DIRECTIVE:
                        // strip register
                        if (tokenStr == "ptr")
                        {
                            isToStrip = true;
                            stripReplace = "";
                        }
                        break;

                    case AsmHighlighterToken.IDENTIFIER:
                        isToStrip = true;
                        stripReplace  = (defines.ContainsKey(tokenStr)) ? defines[tokenStr] : "4";
                        if (isInBracket)
                        {
                            if ( (lexer.AsmHighlighterTokenProvider.GetTokenFromIdentifier(stripReplace) & AsmHighlighterToken.IS_REGISTER) != 0 )
                            {
                                countRegisterInBracket++;
                            }
                            else if (stripReplace == "4")
                            {
                                // No register before 1st identifier
                                if ( countRegisterInBracket == 0)
                                {
                                    // Fake dword adress if we have mov [IDENTIFIER + ....]
                                    stripReplace = "123123";
                                }
                            }
                        }
                        break;
                }
                if ( isToStrip )
                {
                    TextSpan editTextSpan = new TextSpan();
                    editTextSpan.iStartLine = 0;
                    editTextSpan.iEndLine = 0;
                    editTextSpan.iStartIndex = start;
                    editTextSpan.iEndIndex = end+1;

                    changes.Add(new EditSpan(editTextSpan, stripReplace));
                }
                token = (AsmHighlighterToken)lexer.GetNext(ref state, out start, out end);
            }

            for (int i = changes.Count - 1; i >= 0; i-- )
            {
                EditSpan editSpan = changes[i];
                codeToFormat = codeToFormat.Substring(0, editSpan.Span.iStartIndex) + editSpan.Text +
                               codeToFormat.Substring(editSpan.Span.iEndIndex, codeToFormat.Length - editSpan.Span.iEndIndex);
            }

            // Force the FASM code to 32 bit
            codeToFormat = "use32\r\n" + codeToFormat;
            return codeToFormat;
        }