public void Restyle(FontScheme fonts, List<Line> list, int lineNr)
        {
            fontMods.Clear();
            bool inBlockComment = lineNr > 0 && list[lineNr - 1].blockCommentAtEnd;
            bool blockCommetAtStart = inBlockComment;
            bool hadBlockCommentAtEnd = blockCommentAtEnd;
            blockCommentAtEnd = false;
            Lexer lexer = new Lexer(new StringReader(Text));
            tokens.Clear();
            List<Token> tokensNoWS = new List<Token>();
            Token token = null;
            while (true)
            {
                try
                {
                    token = lexer.Next();
                    if (token is EOF)
                        break;
                }
                catch (Exception)
                {
                    continue;
                }
                //Don't add comments to the list
                if (!(inBlockComment || token is TCommentBegin || token is TTraditionalComment || token is TEndOfLineComment || token is TDocumentationComment))
                {
                    tokens.Add(token);
                    if (!(token is TWhiteSpace))
                        tokensNoWS.Add(token);
                }
                if (inBlockComment)
                {
                    if (token is TCommentEnd)
                    {
                        fontMods.Add(new Interval(0, token.Pos + 1), Options.FontStyles.Comments);
                        inBlockComment = false;
                        continue;
                    }
                }
                else
                {
                    if (token is TTraditionalComment || token is TEndOfLineComment || token is TDocumentationComment)
                    {
                        fontMods.Add(new Interval(token.Pos - 1, token.Text.Length), Options.FontStyles.Comments);
                        continue;
                    }
                    if (token is TCommentBegin)
                    {
                        fontMods.Add(new Interval(token.Pos - 1, Text.Length - token.Pos + 1), Options.FontStyles.Comments);
                        inBlockComment = true;
                        continue;
                    }
                    if (token is TStringLiteral || token is TCharLiteral)
                    {
                        fontMods.Add(new Interval(token.Pos - 1, token.Text.Length), Options.FontStyles.Strings);
                        continue;
                    }
                    if (token is TUnknown && (token.Text == "\"" || token.Text == "'"))
                    {
                        fontMods.Add(new Interval(token.Pos - 1, Text.Length - token.Pos + 1), Options.FontStyles.Strings);
                        continue;
                    }

                    foreach (KeyValuePair<Options.FontStyles, List<string>> modification in fonts.Modifications)
                    {
                        if (modification.Value.Any(m => m == token.Text))
                        {
                            fontMods.Add(new Interval(token.Pos - 1, token.Text.Length), modification.Key);
                            continue;
                        }
                    }

                    if (token is TLParen && tokensNoWS.Count > 1)
                    {
                        Token prevToken = tokensNoWS[tokensNoWS.Count - 2];
                        if (prevToken is TIdentifier && Form1.Form.compiler.libraryData.Methods.Any(m => m.GetName().Text == prevToken.Text) &&
                            prevToken.Text != "InitMap")
                        {
                            bool isCustom = false;
                            if (tokensNoWS.Count > 2)
                            {
                                Token prevToken2 = tokensNoWS[tokensNoWS.Count - 3];
                                if (prevToken2 is TDot || prevToken2 is TArrow)
                                    isCustom = true;
                            }
                            if (!isCustom)
                            {
                                fontMods.Add(new Interval(prevToken.Pos - 1, prevToken.Text.Length), Options.FontStyles.NativeCalls);
                                continue;
                            }
                        }
                    }
                }
            }

            blockCommentAtEnd = inBlockComment;

            if (blockCommetAtStart == blockCommentAtEnd && blockCommetAtStart && fontMods.Count == 0)
            {
                fontMods.Add(new Interval(0, Text.Length), Options.FontStyles.Comments);
            }

            if (blockCommentAtEnd != hadBlockCommentAtEnd && lineNr + 1 < list.Count)
                list[lineNr + 1].edited = list[lineNr + 1].Invalidated = true;

            //Structs: identifier <identifer, star, lbracket, lbrace, nothing, dot>
            List<string> structNames = new List<string>();
            foreach (SourceFileContents sourceFile in Form1.Form.compiler.ParsedSourceFiles)
            {
                foreach (StructDescription str in sourceFile.GetAllStructs())
                {
                    structNames.Add(str.Name);
                }
            }
            for (int i = 0; i < tokensNoWS.Count; i++)
            {
                token = tokensNoWS[i];
                if (token is TIdentifier && !fontMods.Any(k => k.Key.Contains(token.Pos)) &&
                    structNames.Contains(token.Text))
                {
                    if (i < tokensNoWS.Count - 1 && !(tokensNoWS[i + 1] is TIdentifier ||
                        tokensNoWS[i + 1] is TStar || tokensNoWS[i + 1] is TLBracket ||
                        tokensNoWS[i + 1] is TLBrace || tokensNoWS[i + 1] is TDot || tokensNoWS[i + 1] is TLt))
                    {
                        if (
                            !(i > 0 &&
                              (tokensNoWS[i - 1] is TStruct || tokensNoWS[i - 1] is TClassToken ||
                               tokensNoWS[i - 1] is TRBracket) && tokensNoWS[i + 1] is TColon))
                            continue;
                    }
                    fontMods.Add(new Interval(token.Pos - 1, token.Text.Length), Options.FontStyles.Structs);
                }
            }

            edited = false;
        }
        public void GoToDeclaration()
        {
            TextPoint caretPos = caret.GetPosition(true);
            List<Token> tokens = new List<Token>();
            Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text));
            Token token;
            while (!((token = lexer.Next()) is EOF))
            {
                if (token is TWhiteSpace || token is TTraditionalComment || token is TEndOfLineComment || token is TDocumentationComment)
                    continue;
                    tokens.Add(token);
            }
            int nameIndex = -1;
            for (int i = 0; i < tokens.Count; i++)
            {
                Token t = tokens[i];
                if (t is TIdentifier &&
                    t.Pos - 1 <= caretPos.Pos &&
                    t.Pos + t.Text.Length - 1 >= caretPos.Pos)
                {
                    token = t;
                    nameIndex = i;
                    break;
                }
            }
            if (nameIndex == -1)
            {
                MessageBox.Show(Form1.Form, "The caret must be over an identifier.", "Error");
                return;
            }
            bool isMethod = nameIndex + 1 < tokens.Count && tokens[nameIndex + 1] is TLParen;
            string name = tokens[nameIndex].Text;
            List<SuggestionBoxItem> matchingDecls = new List<SuggestionBoxItem>();
            if (nameIndex > 0 && (tokens[nameIndex - 1] is TDot || tokens[nameIndex - 1] is TArrow))
            {
                //Dotted
                StringBuilder text = new StringBuilder();
                for (int line = 0; line < caretPos.Line; line++)
                {
                    text.AppendLine(lines[line].Text);
                }
                text.Append(lines[caretPos.Line].Text.Substring(0, token.Pos - 1));
                List<StructDescription> targetStructs;
                List<EnrichmentDescription> targetEnrichments;
                List<NamespaceDescription> targetNamespaces;
                List<MethodDescription> delegateTargets;
                bool b;
                List<StructDescription> staticStructs;

                Form1.Form.suggestionBox.Listbox.ExtractTargetType(text.ToString(), out targetStructs, out targetEnrichments, out targetNamespaces,
                                    out b, out staticStructs, out b, out delegateTargets, out b);
                if (isMethod)
                {
                    foreach (StructDescription str in targetStructs)
                    {
                        foreach (MethodDescription method in str.Methods)
                        {
                            if (method.Name == name && !method.IsStatic && !method.IsDelegate)
                                matchingDecls.Add(method);
                        }
                    }
                    foreach (EnrichmentDescription enrichment in targetEnrichments)
                    {
                        foreach (MethodDescription method in enrichment.Methods)
                        {
                            if (method.Name == name && !method.IsStatic && !method.IsDelegate)
                                matchingDecls.Add(method);
                        }
                    }
                    foreach (NamespaceDescription ns in targetNamespaces)
                    {
                        foreach (MethodDescription method in ns.Methods)
                        {
                            if (method.Name == name && !method.IsDelegate)
                                matchingDecls.Add(method);
                        }
                    }
                    foreach (StructDescription str in staticStructs)
                    {
                        foreach (MethodDescription method in str.Methods)
                        {
                            if (method.Name == name && method.IsStatic && !method.IsDelegate)
                                matchingDecls.Add(method);
                        }
                    }
                }
                else
                {
                    //Not methods
                    foreach (StructDescription str in targetStructs)
                    {
                        foreach (VariableDescription var in str.Fields)
                        {
                            if (var.Name == name && !var.IsStatic)
                                matchingDecls.Add(var);
                        }
                    }
                    foreach (EnrichmentDescription str in targetEnrichments)
                    {
                        foreach (VariableDescription var in str.Fields)
                        {
                            if (var.Name == name && !var.IsStatic)
                                matchingDecls.Add(var);
                        }
                    }
                    foreach (NamespaceDescription ns in targetNamespaces)
                    {
                        foreach (VariableDescription var in ns.Fields)
                        {
                            if (var.Name == name)
                                matchingDecls.Add(var);
                        }
                        foreach (NamespaceDescription ns2 in ns.Namespaces)
                        {
                            if (ns2.Name == name)
                                matchingDecls.Add(ns2);
                        }
                        foreach (StructDescription str in ns.Structs)
                        {
                            if (str.Name == name)
                                matchingDecls.Add(str);
                        }
                        foreach (TypedefDescription typedef in ns.Typedefs)
                            if (typedef.Name == name)
                                matchingDecls.Add(typedef);
                    }
                    foreach (StructDescription str in staticStructs)
                    {
                        foreach (VariableDescription var in str.Fields)
                        {
                            if (var.Name == name && var.IsStatic)
                                matchingDecls.Add(var);
                        }
                    }
                }

            }
            else
            {
                //Simple
                object openFileData = Tag is Form1.OpenFileData
                                          ? ((Form1.OpenFileData)Tag).File
                                          : (object)((DialogData)Tag).DialogItem;
                SourceFileContents sourceFile = null;
                foreach (SourceFileContents sourceFileContents in Form1.Form.compiler.ParsedSourceFiles)
                {
                    if (openFileData == sourceFileContents.Item && !sourceFileContents.IsDialogDesigner)
                    {
                        sourceFile = sourceFileContents;
                        break;
                    }
                }
                if (sourceFile == null)
                    return;
                IDeclContainer context = sourceFile.GetDeclContainerAt(caretPos.Line);
                StructDescription currentStruct = null;
                EnrichmentDescription currentEnrichment = null;
                MethodDescription currentMethod = null;
                foreach (StructDescription str in context.Structs)
                {
                    if (str.LineFrom <= caretPos.Line && str.LineTo >= caretPos.Line)
                    {
                        currentStruct = str;
                        foreach (MethodDescription method in str.Methods)
                        {
                            if (method.Start <= caretPos && method.End >= caretPos)
                            {
                                currentMethod = method;
                                break;
                            }
                        }
                        foreach (MethodDescription method in str.Constructors)
                        {
                            if (method.Start <= caretPos && method.End >= caretPos)
                            {
                                currentMethod = method;
                                break;
                            }
                        }
                        foreach (MethodDescription method in str.Deconstructors)
                        {
                            if (method.Start <= caretPos && method.End >= caretPos)
                            {
                                currentMethod = method;
                                break;
                            }
                        }
                        break;
                    }
                }
                if (currentStruct == null)
                    foreach (EnrichmentDescription str in context.Enrichments)
                    {
                        if (str.LineFrom <= caretPos.Line && str.LineTo >= caretPos.Line)
                        {
                            currentEnrichment = str;
                            foreach (MethodDescription method in str.Methods)
                            {
                                if (method.Start <= caretPos && method.End >= caretPos)
                                {
                                    currentMethod = method;
                                    break;
                                }
                            }
                            foreach (MethodDescription method in str.Constructors)
                            {
                                if (method.Start <= caretPos && method.End >= caretPos)
                                {
                                    currentMethod = method;
                                    break;
                                }
                            }
                            foreach (MethodDescription method in str.Deconstructors)
                            {
                                if (method.Start <= caretPos && method.End >= caretPos)
                                {
                                    currentMethod = method;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                if (currentMethod == null)
                    foreach (MethodDescription method in context.Methods)
                    {
                        if (method.Start <= caretPos && method.End >= caretPos)
                        {
                            currentMethod = method;
                            break;
                        }
                    }
                List<IDeclContainer> visibleDecls = sourceFile.GetVisibleDecls(context.NamespaceList, true);
                if (isMethod)
                {
                    if (currentStruct != null)
                        foreach (MethodDescription method in currentStruct.Methods)
                        {
                            if (method.Name == name && !method.IsDelegate)
                                matchingDecls.Add(method);
                        }
                    if (currentEnrichment != null)
                        foreach (MethodDescription method in currentEnrichment.Methods)
                        {
                            if (method.Name == name && !method.IsDelegate)
                                matchingDecls.Add(method);
                        }
                    if (matchingDecls.Count == 0)
                        foreach (IDeclContainer visibleDecl in visibleDecls)
                        {
                            foreach (MethodDescription method in visibleDecl.Methods)
                            {
                                if (method.Name == name && !method.IsDelegate)
                                    matchingDecls.Add(method);
                            }
                        }
                }
                else
                {
                    //Not method
                    if (currentMethod != null)
                    {
                        foreach (VariableDescription var in currentMethod.Locals)
                        {
                            if (var.Name == name)
                                matchingDecls.Add(var);
                        }
                        foreach (VariableDescription var in currentMethod.Formals)
                        {
                            if (var.Name == name)
                                matchingDecls.Add(var);
                        }
                    }
                    if (matchingDecls.Count == 0 && currentStruct != null)
                        foreach (VariableDescription var in currentStruct.Fields)
                        {
                            if (var.Name == name)
                                matchingDecls.Add(var);
                        }
                    if (matchingDecls.Count == 0 && currentEnrichment != null)
                        foreach (VariableDescription var in currentEnrichment.Fields)
                        {
                            if (var.Name == name)
                                matchingDecls.Add(var);
                        }
                    if (matchingDecls.Count == 0)
                        foreach (IDeclContainer visibleDecl in visibleDecls)
                        {
                            foreach (VariableDescription var in visibleDecl.Fields)
                            {
                                if (var.Name == name)
                                    matchingDecls.Add(var);
                            }
                            foreach (NamespaceDescription ns in visibleDecl.Namespaces)
                            {
                                if (ns.Name == name)
                                    matchingDecls.Add(ns);
                            }
                            foreach (TypedefDescription typedef in visibleDecl.Typedefs)
                                if (typedef.Name == name)
                                    matchingDecls.Add(typedef);
                        }
                }
            }

            if (matchingDecls.Count == 0)
            {
                MessageBox.Show(Form1.Form, "Found no matching declarations.", "Error");
                return;
            }

            SuggestionBoxItem item = matchingDecls[0];

            SourceFileContents file = item.ParentFile.File;

            Form1.Form.OpenFile((FileItem) file.Item);
            caretPos = item.Position;
            caretPos.Pos--;
            Form1.Form.CurrentOpenFile.OpenFile.Editor.MoveCaretTo(caretPos);
        }
        public bool ExecuteKey(KeyEventArgs e)
        {
            TextPoint caretPos = caret.GetPosition(true);
            bool shift = e.Shift;
            bool ctrl = e.Control;
            Keys keys = e.KeyData;
            if (shift) keys = e.KeyData ^ Keys.Shift;
            if (ctrl) keys = keys ^ Keys.Control;
            //Only handle special keys

            switch (keys)
            {
                case Keys.Tab:

                    if (IsReadonly) break;
                    if (!TextMarked)
                    {
                        if (!Options.Editor.ReplaceTabsWithSpaces)
                        {
                            lines[caretPos.Line].Text = lines[caretPos.Line].Text.Insert(caretPos.Pos, "\t");
                            lines[caretPos.Line].Invalidated = true;

                            UndoSys.TextAdded("\t", this, caretPos);
                            caretPos.Pos++;
                            caret.SetPosition(caretPos, true);
                            ExtendedLines(new List<Line>() { lines[caretPos.Line] });
                            Invalidate();
                            TextEdited();
                            CaretMoved(false);
                            return true;
                        }

                        int pos;
                        if (shift)
                        {//Remove spaces up to previous tab
                            int count = 0;
                            while (caretPos.Pos > 0 && lines[caretPos.Line].Text[caretPos.Pos - count - 1] == ' ')
                            {
                                if (caretPos.Pos - count == 0)
                                    break;
                                count++;
                                if ((caretPos.Pos - count) % 4 == 0)
                                {
                                    break;
                                }
                            }
                            if (count == 0)
                                return true;
                            UndoSys.TextRemoved(lines[caretPos.Line].Text.Substring(caretPos.Pos - count, count), this, new TextPoint(caretPos.Line, caretPos.Pos - count));
                            lines[caretPos.Line].Text = lines[caretPos.Line].Text.Remove(caretPos.Pos - count, count);
                            lines[caretPos.Line].Invalidated = true;
                            caretPos.Pos -= count;
                            caret.SetPosition(caretPos, true);
                            ShrunkLine(lines[caretPos.Line]);
                            Invalidate();
                            TextEdited();
                            CaretMoved(false);
                            return true;
                        }

                        pos = caretPos.Pos + 1;
                        string textInsert = " ";
                        while (pos % 4 > 0)
                        {
                            pos++;
                            textInsert += " ";
                        }
                        lines[caretPos.Line].Text = lines[caretPos.Line].Text.Insert(caretPos.Pos, textInsert);
                        lines[caretPos.Line].Invalidated = true;

                        UndoSys.TextAdded(textInsert, this, caretPos);
                        caretPos.Pos += textInsert.Length;
                        caret.SetPosition(caretPos, true);
                        ExtendedLines(new List<Line>(){lines[caretPos.Line]});
                        Invalidate();
                        TextEdited();
                        CaretMoved(false);
                        return true;
                    }

                    List<Line> modifiedLines = new List<Line>();
                    int min = Math.Min(caretPos.Line, mouseDownPos.Line);
                    int max = Math.Max(caretPos.Line, mouseDownPos.Line);

                    string oldText = "";
                    for (int i = min; i <= max; i++)
                    {
                        oldText += lines[i].Text;
                        if (i != max)
                            oldText += "\n";
                    }

                    string newText;
                    /*if (!Options.Editor.ReplaceTabsWithSpaces)
                    {
                        newText = "";
                        for (int i = min; i <= max; i++)
                        {
                            lines[i].Indents++;
                            lines[i].Invalidated = true;
                            newText += lines[i].Text;
                        }
                    }*/
                    int spacesCaret = 0;
                    foreach (char t in lines[caretPos.Line].Text)
                    {
                        if (t == ' ')
                            spacesCaret--;
                        else
                            break;
                    }
                    int spacesMarkStart = 0;
                    foreach (char t in lines[mouseDownPos.Line].Text)
                    {
                        if (t == ' ')
                            spacesMarkStart--;
                        else
                            break;
                    }
                    for (int i = min; i <= max; i++)
                    {
                        modifiedLines.Add(lines[i]);
                        lines[i].Invalidated = true;
                        if (e.Shift)
                            lines[i].Indents--;
                        else
                            lines[i].Indents++;
                    }
                    newText = "";
                    for (int i = min; i <= max; i++)
                    {
                        newText += lines[i].Text;
                        if (i != max)
                            newText += "\n";
                    }
                    UndoSys.TextReplaced(oldText, newText, this, new TextPoint(min, 0));

                    spacesCaret += 4 * lines[caretPos.Line].Indents;
                    if (!Options.Editor.ReplaceTabsWithSpaces && spacesCaret != 0) spacesCaret /= Math.Abs(spacesCaret);
                    if (caretPos.Pos + spacesCaret < 0)
                        spacesCaret = -caretPos.Pos;
                    caretPos = new TextPoint(caretPos.Line, caretPos.Pos + spacesCaret);
                    caret.SetPosition(caretPos, true);

                    spacesMarkStart += 4 * lines[mouseDownPos.Line].Indents;
                    if (!Options.Editor.ReplaceTabsWithSpaces && spacesMarkStart != 0)  spacesMarkStart /= Math.Abs(spacesMarkStart);
                    mouseDownPos = new TextPoint(mouseDownPos.Line, mouseDownPos.Pos + spacesMarkStart);

                    ExtendedLines(modifiedLines);
                    Invalidate();
                    TextEdited();
                    CaretMoved(false);
                    return true;
                case Keys.Delete:
                    if (IsReadonly) break;
                    if (TextMarked)
                    {
                        DeleteMarkedText();
                        caretPos = caret.GetPosition(true);
                    }
                        //Li|ne1
                    else if (lines[caretPos.Line].Text.Length > caretPos.Pos)
                    {
                        string removedPart = lines[caretPos.Line].Text.Substring(caretPos.Pos, 1);
                        UndoSys.TextRemoved(removedPart, this, new TextPoint(caretPos.Line, caretPos.Pos));
                        lines[caretPos.Line].Text = lines[caretPos.Line].Text.Remove(caretPos.Pos, 1);
                        lines[caretPos.Line].edited = true;
                        lines[caretPos.Line].Invalidated = true;
                        ShrunkLine(lines[caretPos.Line]);
                        UpdateBlocks();
                        Invalidate();
                        TextEdited();
                    }
                    //Line1|
                    //Line2
                    else if (lines.Count > caretPos.Line + 1)
                    {
                        UndoSys.TextRemoved("\n", this, new TextPoint(caretPos.Line, caretPos.Pos));
                        lines[caretPos.Line].Text += lines[caretPos.Line + 1].Text;
                        lines[caretPos.Line].edited = true;
                        lines.RemoveAt(caretPos.Line + 1);
                        //InvalidateAll = true;
                        for (int i = caretPos.Line; i < lines.Count; i++)
                        {
                            lines[i].Invalidated = true;
                        }
                        ExtendedLines(new List<Line>{lines[caretPos.Line]});
                        UpdateBlocks();
                        Invalidate();
                        TextEdited();
                    }
                    return true;
                case Keys.Back:
                    if (IsReadonly) break;
                    if (TextMarked)
                    {
                        DeleteMarkedText();
                        caretPos = caret.GetPosition(true);
                    }
                    //Li|ne1
                    else if (caretPos.Pos > 0)
                    {
                        string removedPart = lines[caretPos.Line].Text.Substring(
                            caretPos.Pos - 1, 1);
                        lines[caretPos.Line].Text = lines[caretPos.Line].Text.Remove(
                            caretPos.Pos - 1, 1);
                        lines[caretPos.Line].Invalidated = true;
                        lines[caretPos.Line].edited = true;
                        UndoSys.TextRemoved(removedPart, this, new TextPoint(caretPos.Line, caretPos.Pos - 1));
                        caret.SetPosition(new TextPoint(caretPos.Line, caretPos.Pos - 1), true);
                        ShrunkLine(lines[caretPos.Line]);
                        UpdateBlocks();
                        Invalidate();
                        TextEdited();
                    }
                    //Line1
                    //|Line2
                    else if (caretPos.Line > 0)
                    {
                        TextPoint newPos = new TextPoint(caretPos.Line - 1,
                                                         lines[caretPos.Line - 1].Text.Length);
                        lines[caretPos.Line - 1].Text += lines[caretPos.Line].Text;
                        lines.RemoveAt(caretPos.Line);
                        //InvalidateAll = true;
                        for (int l = caretPos.Line - 1; l < lines.Count; l++)
                        {
                            lines[l].Invalidated = true;
                        }
                        UndoSys.TextRemoved("\n", this, new TextPoint(newPos.Line, newPos.Pos));
                        caret.SetPosition(newPos, true);
                        lines[newPos.Line].edited = true;
                        ExtendedLines(new List<Line> { lines[newPos.Line] });
                        UpdateBlocks();
                        Invalidate();
                        TextEdited();
                        CaretMoved();
                        return true;
                    }
                    CaretMoved();
                    return true;
                case Keys.Return:
                    if (IsReadonly) break;
                    DeleteMarkedText();
                    caretPos = caret.GetPosition(true);
                    List<Line> newLines = new List<Line>();
                    Line newLine = new Line(lines[caretPos.Line].Text.Substring(caretPos.Pos));
                    newLines.Add(newLine);
                    Line extraNewLine = null;
                    string undoText = "\n";
                    //If the next char was an }, move that to its own line
                    if (newLine.Text.Length > 0 && newLine.Text[0] == '}')
                    {
                        extraNewLine = new Line(newLine.Text);
                        newLines.Add(extraNewLine);
                        lines.Insert(caretPos.Line + 1, extraNewLine);
                        newLine.Text = "";
                    }
                    string oldNewLineText = newLine.Text;
                    lines.Insert(caretPos.Line + 1, newLine);
                    lines[caretPos.Line].Text = lines[caretPos.Line].Text.Substring(0, caretPos.Pos);
                    lines[caretPos.Line].edited = true;
                    lines[caretPos.Line].Restyle(fonts, lines, caretPos.Line);
                    newLine.Indents = newLine.GetWantedIndents(fonts, lines, caretPos.Line + 1);
                    if (newLine.Text.Length - oldNewLineText.Length >= 0 && oldNewLineText.Length > 0)
                        undoText += newLine.Text.Remove(newLine.Text.Length - oldNewLineText.Length);
                    else
                        undoText += newLine.Text;
                    if (extraNewLine != null)
                    {
                        oldNewLineText = extraNewLine.Text;
                        extraNewLine.Indents = extraNewLine.GetWantedIndents(fonts, lines, caretPos.Line + 2);
                        if (extraNewLine.Text.Length - oldNewLineText.Length >= 0 && oldNewLineText.Length > 0)
                            undoText += "\n" + extraNewLine.Text.Remove(extraNewLine.Text.Length - oldNewLineText.Length);
                        else
                            undoText += "\n" + extraNewLine.Text;
                    }

                    caret.SetPosition(new TextPoint(caretPos.Line + 1, Options.Editor.ReplaceTabsWithSpaces ? newLine.Indents*4 : newLine.Indents), true);
                    //InvalidateAll = true;
                    for (int l = caretPos.Line; l < lines.Count; l++)
                    {
                        lines[l].Invalidated = true;
                    }
                    ShrunkLine(lines[caretPos.Line]);
                    ExtendedLines(newLines);
                    UndoSys.TextAdded(undoText, this, caretPos);
                    UpdateBlocks();
                    Invalidate();
                    TextEdited();
                    CaretMoved();
                    return true;
                case Keys.Right:
                    if (!TextMarked)
                    {
                        TextMarked = shift;
                        mouseDownPos = caretPos;
                    }
                    //if (!shift)
                    //    TextMarked = false;
                    while (true)
                    {
                        if (lines[caretPos.Line].Text.Length > caretPos.Pos)
                        {
                            lines[caretPos.Line].Invalidated = true;

                            int pos = caretPos.Pos + 1;

                            if (ctrl)
                            {
                                List<Token> tokens = new List<Token>();
                                Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text));
                                {
                                    Token token;
                                    while (!((token = lexer.Next()) is EOF))
                                    {
                                        if (token is TWhiteSpace)
                                            continue;
                                        tokens.Add(token);
                                    }
                                }
                                bool moved = false;
                                foreach (Token token in tokens)
                                {
                                    if (token.Pos - 1 >= pos)
                                    {
                                        pos = token.Pos - 1;
                                        moved = true;
                                        break;
                                    }
                                }
                                if (!moved)
                                {
                                    caretPos.Pos = lines[caretPos.Line].Text.Length;
                                    continue;
                                }
                            }

                            caret.SetPosition(new TextPoint(caretPos.Line, pos), true);
                            Invalidate();
                        }
                        else if (lines.Count > caretPos.Line + 1)
                        {
                            lines[caretPos.Line].Invalidated = true;
                            //Skip over any potential hidden lines
                            caret.SetPosition(new TextPoint(caret.GetPosition(false).Line + 1, 0), false);

                            if (ctrl)
                            {
                                caretPos = caret.GetPosition(true);
                                int pos = caretPos.Pos;
                                List<Token> tokens = new List<Token>();
                                Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text));
                                {
                                    Token token;
                                    while (!((token = lexer.Next()) is EOF))
                                    {
                                        if (token is TWhiteSpace)
                                            continue;
                                        tokens.Add(token);
                                    }
                                }
                                if (tokens.Count > 0)
                                {
                                    Token token = tokens[0];
                                    pos = token.Pos - 1;
                                }
                                else
                                    pos = lines[caretPos.Line].Text.Length;
                                caret.SetPosition(new TextPoint(caretPos.Line, pos), true);
                            }
                            Invalidate();
                        }
                        break;
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.Left:
                    if (!TextMarked)
                    {
                        TextMarked = shift;
                        mouseDownPos = caretPos;
                    }
                    //if (!shift)
                    //    TextMarked = false;
                    while (true)
                    {
                        if (caretPos.Pos > 0)
                        {
                            lines[caretPos.Line].Invalidated = true;
                            int pos = caretPos.Pos - 1;

                            if (ctrl)
                            {
                                List<Token> tokens = new List<Token>();
                                Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text));
                                {
                                    Token token;
                                    while (!((token = lexer.Next()) is EOF))
                                    {
                                        if (token is TWhiteSpace)
                                            continue;
                                        tokens.Add(token);
                                    }
                                }
                                bool moved = false;
                                for (int i = tokens.Count - 1; i >= 0; i--)
                                {
                                    Token token = tokens[i];
                                    if (token.Pos - 1 <= pos)
                                    {
                                        pos = token.Pos - 1;
                                        moved = true;
                                        break;
                                    }
                                }
                                if (!moved)
                                {
                                    caretPos.Pos = 0;
                                    continue;
                                }
                            }

                            caret.SetPosition(new TextPoint(caretPos.Line, pos), true);
                            Invalidate();
                        }
                        else if (caretPos.Line > 0)
                        {
                            lines[caretPos.Line].Invalidated = true;
                            //Skip over any potential hidden lines
                            caret.SetPosition(new TextPoint(caret.GetPosition(false).Line - 1, 0), false);
                            caretPos = caret.GetPosition(true);
                            caret.SetPosition(new TextPoint(caretPos.Line, lines[caretPos.Line].Text.Length), true);

                            if (ctrl)
                            {
                                caretPos = caret.GetPosition(true);
                                int pos = caretPos.Pos;
                                List<Token> tokens = new List<Token>();
                                Lexer lexer = new Lexer(new StringReader(lines[caretPos.Line].Text));
                                {
                                    Token token;
                                    while (!((token = lexer.Next()) is EOF))
                                    {
                                        if (token is TWhiteSpace)
                                            continue;
                                        tokens.Add(token);
                                    }
                                }
                                if (tokens.Count > 0)
                                {
                                    Token token = tokens[tokens.Count - 1];
                                    pos = token.Pos - 1 + token.Text.Length;
                                }
                                caret.SetPosition(new TextPoint(caretPos.Line, pos), true);
                            }

                            Invalidate();
                        }
                        break;
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.Up:
                    if (!TextMarked)
                    {
                        TextMarked = shift;
                        mouseDownPos = caretPos;
                    }
                    //if (!shift)
                    //    TextMarked = false;
                    if (caretPos.Line > 0)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        lines[caretPos.Line - 1].Invalidated = true;

                        int oldPos = 0;
                        for (int i = 0; i < caretPos.Pos; i++)
                        {
                            oldPos++;
                            if (lines[caretPos.Line].Text[i] == '\t')
                                oldPos += 3;
                            else if (lines[caretPos.Line].Text[i] > 0xFF)
                                oldPos++;
                        }
                        caret.SetPosition(new TextPoint(caret.GetPosition(false).Line - 1, 0), false);
                        caretPos = caret.GetPosition(true);
                        int newPos = 0;
                        for (newPos = 0; newPos < lines[caretPos.Line].Text.Length; newPos++)
                        {
                            if (oldPos <= 0)
                                break;
                            if (lines[caretPos.Line].Text[newPos] == '\t')
                            {
                                oldPos -= 4;
                                if (oldPos < -2)
                                {
                                    newPos--;
                                }
                            }
                            else if (lines[caretPos.Line].Text[newPos] > 0xFF)
                                oldPos -= 2;
                            else
                                oldPos--;
                        }
                        caret.SetPosition(new TextPoint(caretPos.Line, /*Math.Min(lines[caretPos.Line].Text.Length, oldPos)*/newPos), true);
                        Invalidate();
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.Down:
                    if (!TextMarked)
                    {
                        TextMarked = shift;
                        mouseDownPos = caretPos;
                    }
                    //if (!shift)
                    //    TextMarked = false;
                    if (caretPos.Line + 1 < lines.Count)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        lines[caretPos.Line + 1].Invalidated = true;
                        int oldPos = 0;
                        for (int i = 0; i < caretPos.Pos; i++)
                        {
                            oldPos++;
                            if (lines[caretPos.Line].Text[i] == '\t')
                                oldPos += 3;
                            else if (lines[caretPos.Line].Text[i] > 0xFF)
                                oldPos++;
                        }
                        caret.SetPosition(new TextPoint(caret.GetPosition(false).Line + 1, 0), false);
                        caretPos = caret.GetPosition(true);
                        int newPos = 0;
                        for (newPos = 0; newPos < lines[caretPos.Line].Text.Length; newPos++)
                        {
                            if (oldPos <= 0)
                                break;
                            if (lines[caretPos.Line].Text[newPos] == '\t')
                            {
                                oldPos -= 4;
                                if (oldPos < -2)
                                {
                                    newPos--;
                                }
                            }
                            else if (lines[caretPos.Line].Text[newPos] > 0xFF)
                                oldPos -= 2;
                            else
                                oldPos--;
                        }
                        caret.SetPosition(new TextPoint(caretPos.Line, /*Math.Min(lines[caretPos.Line].Text.Length, oldPos)*/newPos), true);
                        Invalidate();
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.End:
                    if (!TextMarked)
                    {
                        TextMarked = true;
                        mouseDownPos = caretPos;
                    }
                    if (!shift)
                        TextMarked = false;
                    if (caretPos.Pos < lines[caretPos.Line].Text.Length)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        caret.SetPosition(new TextPoint(caretPos.Line, lines[caretPos.Line].Text.Length), true);
                        Invalidate();
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.Home:
                    if (!TextMarked)
                    {
                        TextMarked = true;
                        mouseDownPos = caretPos;
                    }
                    if (!shift)
                        TextMarked = false;
                    if (caretPos.Pos > 0)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        caret.SetPosition(new TextPoint(caretPos.Line, 0), true);
                        Invalidate();
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.PageUp:
                    if (!TextMarked)
                    {
                        TextMarked = true;
                        mouseDownPos = caretPos;
                    }
                    if (!shift)
                        TextMarked = false;
                    if (caretPos.Line > 0)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        int line = caretPos.Line;
                        int subtractedLines = 40;
                        while (line > 0 && subtractedLines > 0)
                        {
                            line--;
                            if (lines[line].LineVisible)
                                subtractedLines--;
                        }
                        int pos = caretPos.Pos;
                        if (pos > lines[line].Text.Length)
                            pos = lines[line].Text.Length;
                        caret.SetPosition(new TextPoint(line, pos), true);
                    }
                    CaretMoved(!shift);
                    return true;
                case Keys.PageDown:
                    if (!TextMarked)
                    {
                        TextMarked = true;
                        mouseDownPos = caretPos;
                    }
                    if (!shift)
                        TextMarked = false;
                    if (caretPos.Line + 1 < lines.Count)
                    {
                        lines[caretPos.Line].Invalidated = true;
                        int line = caretPos.Line;
                        int addedLines = 40;
                        while (line < lines.Count - 1 && addedLines > 0)
                        {
                            line++;
                            if (lines[line].LineVisible)
                                addedLines--;
                        }
                        int pos = caretPos.Pos;
                        if (pos > lines[line].Text.Length)
                            pos = lines[line].Text.Length;
                        caret.SetPosition(new TextPoint(line, pos), true);

                    }
                    CaretMoved(!shift);
                    return true;
            }
            //Handle ctrl commands
            if (e.Modifiers == Keys.Control)
            {
                //Copy
                if (e.KeyValue != 17)
                    e = e;
                if (e.KeyValue == 'C' || e.KeyValue == 'X')
                {
                    Copy(e.KeyValue == 'X');
                    return true;
                }

                //Paste
                if (e.KeyValue == 'V' && !IsReadonly)
                {
                    Paste();
                    return true;
                }

                //Goto line
                if (e.KeyValue == 'G')
                {
                    GotoLineForm dialog = new GotoLineForm(caretPos.Line + 1, lines.Count);
                    if (dialog.ShowDialog(parentForm) == DialogResult.OK)
                    {
                        caret.SetPosition(new TextPoint(dialog.SelectedLine - 1, 0), true);
                        EnsureLineVisible(dialog.SelectedLine - 1);
                        CaretMoved();
                    }
                    return true;
                }

                if (e.KeyValue == 'A')
                {
                    mouseDownPos = new TextPoint(0, 0);
                    caret.SetPosition(new TextPoint(lines.Count - 1, lines[lines.Count - 1].Text.Length), true);
                    TextMarked = true;
                    InvalidateAll = true;
                    CaretMoved(false);
                    return true;
                }

                if (e.KeyValue  == 'F' || e.KeyValue == 'R')
                {
                    //FindAndReplaceForm.form.SetStart(((Form1.OpenFileData)Tag).File, caretPos);
                    OpenFindAndReplace();
                    return true;
                }

                if (e.KeyValue == 'Z')
                {
                    UndoSys.Undo();
                    return true;
                }

                if (e.KeyValue == 'Y')
                {
                    UndoSys.Redo();
                    return true;
                }
            }
            return false;
        }
        private static void ReplaceInvocations(ref string source, List<Macro> macros, List<Macro> currentReplacePath, ErrorCollection errors)
        {
            Lexer lexer = new Lexer(new StringReader(source));
            List<Token> tokens = new List<Token>();
            Token token;
            while (!((token = lexer.Next()) is EOF))
            {
                if (token is TWhiteSpace || token is TTraditionalComment || token is TDocumentationComment || token is TEndOfLineComment)
                    continue;
                tokens.Add(token);
            }

            List<Util.Pair<Util.Pair<TextPoint, TextPoint>, string>> macroSpan = new List<Util.Pair<Util.Pair<TextPoint, TextPoint>, string>>();

            for (int j = 0; j < tokens.Count - 1; j++)
            {
                int t = j;
                if (tokens[t] is TSharp && tokens[t + 1] is TIdentifier)
                {
                    Token sharp = tokens[t];
                    TextPoint start = TextPoint.FromCompilerCoords(tokens[t]);
                    t++;
                    string Name = tokens[t].Text;
                    //Check for parameters
                    t++;
                    bool IsMethod = false;
                    List<string> arguments = new List<string>();
                    TextPoint end;
                    if (tokens[t] is TLParen)
                    {
                        IsMethod = true;
                        int parens = 1;
                        TextPoint argStart = TextPoint.FromCompilerCoords(tokens[t + 1]);
                        while (true)
                        {
                            t++;
                            if (t >= tokens.Count)
                            {
                                errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText214")));
                                t--;
                                break;
                            }

                            if (tokens[t] is TLParen || tokens[t] is TLBrace || tokens[t] is TLBracket)
                                parens++;
                            if (tokens[t] is TRParen || tokens[t] is TRBrace || tokens[t] is TRBracket)
                                parens--;
                            if (parens == 0)
                            {
                                if (!(tokens[t] is TRParen))
                                    errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText215")));
                                if (!(tokens[t - 1] is TLParen))
                                {
                                    TextPoint e = TextPoint.FromCompilerCoords(tokens[t]);
                                    e.Pos++;
                                    arguments.Add(GetText(source, argStart, e));
                                }

                                break;
                            }
                            if (parens > 1)
                                continue;
                            if (tokens[t] is TComma)
                            {
                                TextPoint e = TextPoint.FromCompilerCoords(tokens[t]);
                                e.Pos++;
                                arguments.Add(GetText(source, argStart, e));
                                argStart = e;
                            }
                        }
                        end = TextPoint.FromCompilerCoords(tokens[t]);
                        end.Pos++;
                    }
                    else
                    {
                        end = TextPoint.FromCompilerCoords(tokens[t - 1]);
                        end.Pos += Name.Length;
                    }

                    bool found = false;
                    foreach (Macro macro in macros)
                    {
                        if (macro.Name == Name &&
                            macro.Method == IsMethod &&
                            macro.Parameters.Count == arguments.Count)
                        {
                            found = true;
                            if (currentReplacePath.Contains(macro))
                            {
                                List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                                for (int i = currentReplacePath.IndexOf(macro); i < currentReplacePath.Count; i++)
                                {
                                    subErrors.Add(new ErrorCollection.Error(currentReplacePath[i].token, LocRM.GetString("ErrorText216")));
                                }
                                errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText217"), false, subErrors.ToArray()));
                                break;
                            }
                            string macroText = macro.GetText(arguments);
                            List<Macro> newCurrentPath = new List<Macro>();
                            newCurrentPath.AddRange(currentReplacePath);
                            newCurrentPath.Add(macro);
                            ReplaceInvocations(ref macroText, macros, newCurrentPath, errors);
                            macroSpan.Add(new Util.Pair<Util.Pair<TextPoint, TextPoint>, string>(new Util.Pair<TextPoint, TextPoint>(start, end), macroText));
                        }
                    }
                    if (!found)
                        errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText218")));
                    j = t - 1;
                }
            }

            //Remove macros
            for (int i = macroSpan.Count - 1; i >= 0; i--)
            {
                List<string> lines = source.Split('\n').ToList();
                TextPoint start = macroSpan[i].First.First;
                TextPoint end = macroSpan[i].First.Second;
                string text = macroSpan[i].Second;

                lines[start.Line] = lines[start.Line].Substring(0, start.Pos - 1) + text + lines[end.Line].Substring(end.Pos - 1);
                for (int line = end.Line; line > start.Line; line--)
                {
                    lines.RemoveAt(line);
                }

                StringBuilder builder = new StringBuilder();
                builder.Append(lines[0]);
                for (int j = 0; j < lines.Count; j++)
                {
                    builder.Append("\n" + lines[j]);
                }
                source = builder.ToString();
            }
        }
        public static void Parse(List<string> files, ErrorCollection errors)
        {
            /*
             * #macro <identifier>[(<identifiers>)]
             * anything...#arg1...anything
             *
             * #endmacro
             *
             * #<identifier>(anything_but_comma, #anything_but_hash#)
             *
             *
             */

            //Phase 1: locate all macros
            List<Macro> macros = new List<Macro>();
            for (int i = 0; i < files.Count; i++)
            {
                string source = files[i];

                Lexer lexer = new Lexer(new StringReader(source));
                List<Token> tokens = new List<Token>();
                Token token;
                while (!((token = lexer.Next()) is EOF))
                {
                    if (token is TWhiteSpace || token is TTraditionalComment || token is TDocumentationComment || token is TEndOfLineComment)
                        continue;
                    tokens.Add(token);
                }

                List<Util.Pair<TextPoint, TextPoint>> macroSpan = new List<Util.Pair<TextPoint, TextPoint>>();

                for (int j = 0; j < tokens.Count - 1; j++)
                {
                    int t = j;
                    if (tokens[t] is TSharp && tokens[t + 1].Text == "macro")
                    {
                        Macro macro = new Macro();
                        Token sharp = tokens[t];
                        macro.token = sharp;
                        TextPoint start = TextPoint.FromCompilerCoords(tokens[t]);
                        t += 2;
                        if (t >= tokens.Count || !(tokens[t] is TIdentifier))
                        {
                            errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText206")));
                            continue;
                        }
                        macro.Name = tokens[t].Text;
                        //Find end
                        TextPoint end = new TextPoint(-1, -1);
                        for (int k = t; k < tokens.Count - 1; k++)
                        {
                            if (tokens[k] is TSharp)
                            {
                                if (tokens[k + 1].Text == "macro")
                                {
                                    errors.Add(new ErrorCollection.Error(tokens[k],
                                                                         LocRM.GetString("ErrorText207"),
                                                                         false,
                                                                         new ErrorCollection.Error(sharp,
                                                                                                   LocRM.GetString("ErrorText208"))));
                                }
                                else if (tokens[k + 1].Text == "endmacro")
                                {
                                    end = TextPoint.FromCompilerCoords(tokens[k]);
                                    break;
                                }
                            }
                        }
                        if (end.Line == -1)
                        {
                            errors.Add(new ErrorCollection.Error(sharp, LocRM.GetString("ErrorText209")));
                            continue;
                        }
                        //Check for parameters
                        t++;
                        TextPoint textStart;
                        if (tokens[t] is TLParen)
                        {
                            macro.Method = true;
                            bool needComma = false;
                            while (true)
                            {
                                t++;
                                if (tokens[t] is TRParen)
                                    break;
                                if (tokens[t] is TComma)
                                {
                                    if (!needComma)
                                    {
                                        errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText210")));
                                        break;
                                    }
                                    needComma = false;
                                    t++;
                                }
                                if (tokens[t] is TIdentifier)
                                {
                                    if (needComma)
                                    {
                                        errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText211")));
                                        break;
                                    }
                                    macro.Parameters.Add(tokens[t].Text);
                                    needComma = true;
                                    continue;
                                }
                                if (needComma)
                                    errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText211")));
                                else
                                    errors.Add(new ErrorCollection.Error(tokens[t], LocRM.GetString("ErrorText210")));
                                break;
                            }
                            textStart = TextPoint.FromCompilerCoords(tokens[t]);
                            textStart.Pos++;
                            t++;
                        }
                        else
                        {
                            textStart = TextPoint.FromCompilerCoords(tokens[t - 1]);
                            textStart.Pos += macro.Name.Length;
                        }

                        macro.Text = GetText(source, textStart, end);
                        macroSpan.Add(new Util.Pair<TextPoint, TextPoint>(start, end));
                        macros.Add(macro);
                        j = t;
                    }
                }

                //Remove macros
                List<string> lines = source.Split('\n').ToList();
                for (int j = macroSpan.Count - 1; j >= 0; j--)
                {
                    TextPoint start = macroSpan[j].First;
                    TextPoint end = macroSpan[j].Second;

                    lines[start.Line] = lines[start.Line].Substring(0, start.Pos - 1) + lines[end.Line].Substring(end.Pos + "#endmacro".Length - 1);
                    for (int line = end.Line; line > start.Line; line--)
                    {
                        lines.RemoveAt(line);
                    }
                }

                StringBuilder builder = new StringBuilder();
                builder.Append(lines[0]);
                for (int j = 0; j < lines.Count; j++)
                {
                    builder.Append("\n" + lines[j]);
                }
                source = builder.ToString();

                files[i] = source;
            }

            //Check for dublicate macros
            for (int i = 0; i < macros.Count; i++)
            {
                List<Macro> conflicts = new List<Macro>(){macros[i]};
                for (int j = i + 1; j < macros.Count; j++)
                {
                    if (macros[i].Name == macros[j].Name &&
                        macros[i].Method == macros[j].Method &&
                        macros[i].Parameters.Count == macros[j].Parameters.Count)
                        conflicts.Add(macros[j]);
                }
                if (conflicts.Count > 1)
                {
                    List<ErrorCollection.Error> subErrors = new List<ErrorCollection.Error>();
                    foreach (Macro macro in conflicts)
                    {
                        subErrors.Add(new ErrorCollection.Error(macro.token, LocRM.GetString("ErrorText212")));
                        macros.Remove(macro);
                    }
                    errors.Add(new ErrorCollection.Error(conflicts[0].token, LocRM.GetString("ErrorText213"), false, subErrors.ToArray()));
                    i--;
                }
            }

            //Search for macro invocations

            for (int i = 0; i < files.Count; i++)
            {
                string source = files[i];
                ReplaceInvocations(ref source, macros, new List<Macro>(), errors);
                files[i] = source;
            }
        }
        public void InsertEvent(string name, bool jumpToIt)
        {
            //Look for method with signature
            //void <name>(int sender, <dialogname>* dialog);
            //If found, set caret to that place, if not - append it and set carret

            //Don't assume the code can compile
            string code = ActualCode;
            int lines = 0;
            foreach (char c in code)
            {
                if (c == '\n')
                    lines++;
            }
            TextPoint focusAt = new TextPoint(-1, -1);
            using (StringReader reader = new StringReader(code))
            {
                Lexer lexer = new Lexer(reader);
                List<Token> tokens = new List<Token>();
                Token token = null;
                while ((token = lexer.Next()) != null)
                {
                    if (token is EOF)
                        break;
                    if (token is TWhiteSpace || token is TTraditionalComment || token is TEndOfLineComment)
                        continue;
                    tokens.Add(token);
                }
                for (int i = 0; i < tokens.Count - 11; i++)
                {
                    token = tokens[i];
                    if (token is TVoid)
                    {
                        token = tokens[i + 1];
                        if (token is TIdentifier && token.Text == name && tokens[i + 2] is TLParen)
                        {
                            token = tokens[i + 3];
                            if (token is TIdentifier && token.Text == "int" &&
                                tokens[i + 4] is TIdentifier && tokens[i + 5] is TComma)
                            {
                                token = tokens[i + 6];
                                if (token is TIdentifier && token.Text == DialogIdentiferName &&
                                    tokens[i + 7] is TStar && tokens[i + 8] is TIdentifier &&
                                    tokens[i + 9] is TRParen && tokens[i + 10] is TLBrace)
                                {
                                    focusAt = TextPoint.FromCompilerCoords(tokens[i + 10]);
                                }
                            }

                        }
                    }
                }
            }

            if (focusAt.Line == -1)
            {//Didn't find it. Append it
                jumpToIt = true;//This should not be auto saved. Have to open it.
                string s = "\n\nvoid " + name + "(int sender, " + DialogIdentiferName + "* dialog)\n" +
                           "{\n" +
                           "\t\n" +
                           "}\n";
                Form1.Form.OpenFile(DialogItem, DialogItem.CodeGUINode);
                CodeEditor.Text += s;
                focusAt = new TextPoint(lines + 4, 1);
            }
            else if (jumpToIt)
                Form1.Form.OpenFile(DialogItem, DialogItem.CodeGUINode);
            if (jumpToIt)
                CodeEditor.MoveCaretTo(focusAt);
        }
 public List<string> GetAllTargetMethods()
 {
     List<string> returner = new List<string>();
     using (StringReader reader = new StringReader(ActualCode))
     {
         Lexer lexer = new Lexer(reader);
         List<Token> tokens = new List<Token>();
         Token token = null;
         while ((token = lexer.Next()) != null)
         {
             if (token is EOF)
                 break;
             if (token is TWhiteSpace || token is TTraditionalComment || token is TEndOfLineComment)
                 continue;
             tokens.Add(token);
         }
         for (int i = 0; i < tokens.Count - 11; i++)
         {
             token = tokens[i];
             if (token is TVoid && tokens[i + 1] is TIdentifier && tokens[i + 2] is TLParen)
             {
                 token = tokens[i + 3];
                 if (token is TIdentifier && token.Text == "int" &&
                     tokens[i + 4] is TIdentifier && tokens[i + 5] is TComma)
                 {
                     token = tokens[i + 6];
                     if (token is TIdentifier && token.Text == DialogIdentiferName &&
                         tokens[i + 7] is TStar && tokens[i + 8] is TIdentifier &&
                         tokens[i + 9] is TRParen && tokens[i + 10] is TLBrace)
                     {
                         returner.Add(tokens[i + 1].Text);
                     }
                 }
             }
         }
     }
     return returner;
 }
        private List<AMethodDecl> GetMatchingCurrentMethod(out int commaCount, out TextPoint parenPos, out bool isAsyncInvoke)
        {
            isAsyncInvoke = false;
            commaCount = 0;
            parenPos = new TextPoint(0, 0);
            string text = currentEditor.GetTextWithin(new TextPoint(0, 0), currentEditor.caret.Position);

            Lexer lexer = new Lexer(new StringReader(text));
            List<Token> tokens = new List<Token>();
            Token token;
            bool inString = false;
            while (true)
            {
                try
                {
                    token = lexer.Next();
                    if (token is EOF)
                        break;
                }
                catch (Exception err)
                {
                    continue;
                }
                //We can be in a string if there was an unclosed " on this line
                if (token is TUnknown && token.Text == "\"" || token.Text == "'")
                    inString = true;
                if (token is TWhiteSpace)
                {
                    if (token.Text == "\n")
                        inString = false;
                    continue;
                }
                //If this is true, we have an open block comment with no end, so we're in a comment
                if (token is TCommentBegin)
                    return new List<AMethodDecl>();
                //if (token is TArrow)
                //    token = new TDot(".");

                tokens.Add(token);
            }
            if (inString)
            {
                while (!(token is TUnknown && token.Text == "\"" || token.Text == "'"))
                {
                    token = tokens[tokens.Count - 1];
                    tokens.RemoveAt(tokens.Count - 1);
                }
                /*token = tokens[tokens.Count - 1];
                tokens.RemoveAt(tokens.Count - 1);*/
            }
            if (tokens.Count == 0) return new List<AMethodDecl>();
            //The last entered token can either be an identifier, a dot, or a line comment
            token = tokens[tokens.Count - 1];
            tokens.RemoveAt(tokens.Count - 1);
            if (token is TEndOfLineComment)
                return new List<AMethodDecl>();
            //Remove all other comments
            for (int i = 0; i < tokens.Count; i++)
            {
                if (tokens[i] is TTraditionalComment || tokens[i] is TEndOfLineComment || tokens[i] is TDocumentationComment)
                {
                    tokens.RemoveAt(i);
                    i--;
                }
            }

            //Go back untill you encounter a identifier lparen, and count all commas outside of paranthisis or brackets
            //You can stop if you encounter one of ; { }
            commaCount = 0;
            int openParens = 0;

            while (tokens.Count > 0)
            {
                if (token is TLParen)
                {
                    if (openParens > 0)
                    {
                        openParens--;
                    }
                    else
                    {
                        parenPos = new TextPoint(token.Line - 1, token.Pos - 1);
                        token = tokens[tokens.Count - 1];
                        tokens.RemoveAt(tokens.Count - 1);
                        if (token is TPreloadBank)
                        {
                            return new List<AMethodDecl>(){new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null,
                                                                  new ANamedType(new TIdentifier("void"), null),
                                                                  new TIdentifier("PreloadBank"),
                                                                  new ArrayList
                                                                              {
                                                                                  new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                                                  new ANamedType(
                                                                                                      new TIdentifier(
                                                                                                          "string"),
                                                                                                      null),
                                                                                                  new TIdentifier(
                                                                                                      "bankName"), null),
                                                                                  new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null,
                                                                                                  new ANamedType(
                                                                                                      new TIdentifier(
                                                                                                          "int"), null),
                                                                                                  new TIdentifier(
                                                                                                      "player"), null)
                                                                              },
                                                                  null)};
                        }
                        if (token is TGt)
                        {//Check for invoke<...>
                            int pos = tokens.Count - 1;
                            if (tokens[pos] is TIdentifier)
                            {
                                pos--;
                                if (tokens[pos] is TDot && tokens[pos - 1] is TIdentifier)
                                {
                                    pos -= 2;
                                }
                                if (tokens[pos] is TLt)
                                {
                                    pos--;
                                    if (tokens[pos] is TSyncInvoke || tokens[pos] is TAsyncInvoke)
                                    {
                                        isAsyncInvoke = tokens[pos - 1] is TAsyncInvoke;

                                        token = tokens[tokens.Count - 1];
                                        tokens.RemoveAt(tokens.Count - 1);
                                    }
                                }
                            }
                        }
                        //Check for new exp
                        {
                            int parens = 0;
                            for (int i = tokens.Count - 1; i >= 0; i--)
                            {
                                if (tokens[i] is TRParen || tokens[i] is TRBracket)
                                    parens++;
                                else if (tokens[i] is TLParen || tokens[i] is TLBracket)
                                    parens--;
                                else if (parens > 0)
                                    continue;
                                else if (parens < 0)
                                    break;
                                else if (tokens[i] is TSemicolon || tokens[i] is TRBrace || tokens[i] is TLBrace)
                                    break;
                                else if (tokens[i] is TNew)
                                {
                                    string txt = "";
                                    for (int j = 0; j < tokens.Count; j++)
                                    {
                                        txt += tokens[j].Text + " ";
                                    }
                                    txt += token.Text + ".";
                                    List<StructDescription> targetStructs;
                                    List<EnrichmentDescription> targetEnrichments;
                                    List<NamespaceDescription> targetNamespaces;
                                    List<MethodDescription> delegateTargets;
                                    bool b;
                                    List<StructDescription> l;

                                    ExtractTargetType(txt, out targetStructs, out targetEnrichments, out targetNamespaces,
                                                        out b, out l, out b, out delegateTargets, out b);

                                    List<AMethodDecl> methods = new List<AMethodDecl>();
                                    foreach (StructDescription targetStruct in targetStructs)
                                    {
                                        foreach (MethodDescription constructor in targetStruct.Constructors)
                                        {
                                            methods.Add(constructor.Decl);
                                        }
                                    }

                                    foreach (EnrichmentDescription enrichment in targetEnrichments)
                                    {
                                        foreach (MethodDescription constructor in enrichment.Constructors)
                                        {
                                            methods.Add(constructor.Decl);
                                        }
                                    }

                                    return methods;
                                }
                            }
                        }
                        if (token is TIdentifier)
                        {
                            List<AMethodDecl> methods = new List<AMethodDecl>();
                            string methodName = token.Text;
                            if (tokens.Count == 0)
                                return new List<AMethodDecl>();
                            token = tokens[tokens.Count - 1];
                            tokens.RemoveAt(tokens.Count - 1);
                            //If we are in a method decl, we dont want to show anything
                            if (token is TIdentifier || token is TVoid)
                                return new List<AMethodDecl>();
                            bool isGlobal = false;
                            if (token is TDot || token is TArrow)
                            {//It is a struct method.. fetch the method
                                //bool b1, b2, b3;
                                //string namespacePrefix;
                                //MethodDescription delegateTarget;
                                //StructDescription target = GetTargetStruct(token, tokens, out isGlobal, out b1, out namespacePrefix, out b2, out delegateTarget, out b3);

                                string strText = "";
                                {
                                    int parens = 0;
                                    for (int i = text.Length - 1; i >= 0; i--)
                                    {
                                        if (parens == -1)
                                        {
                                            if (text[i] == '.')
                                            {
                                                strText = text.Substring(0, i + 1);
                                                break;
                                            }
                                            if (text.Substring(i, 2) == "->")
                                            {
                                                strText = text.Substring(0, i + 2);
                                                break;
                                            }
                                        }
                                        if (parens < -1)
                                            return new List<AMethodDecl>();
                                        if (text[i] == ')')
                                            parens++;
                                        if (text[i] == '(')
                                            parens--;
                                    }
                                }
                                List<StructDescription> targetStructs;
                                List<EnrichmentDescription> targetEnrichments;
                                List<NamespaceDescription> targetNamespaces;
                                List<MethodDescription> delegateTargets;
                                bool b;
                                bool dynamicArray;
                                List<StructDescription> l;
                                ExtractTargetType(strText, out targetStructs, out targetEnrichments, out targetNamespaces,
                                                    out b, out l, out b, out delegateTargets, out dynamicArray);

                                if (dynamicArray && methodName == "Resize")
                                {
                                    methods.Add(new AMethodDecl(new APublicVisibilityModifier(), null, null, null,
                                                                    null, null, new AVoidType(new TVoid("void")),
                                                                    new TIdentifier("Resize"),
                                                                    new ArrayList()
                                                                        {
                                                                            new AALocalDecl(
                                                                                new APublicVisibilityModifier(), null,
                                                                                null, null, null,
                                                                                new ANamedType(
                                                                                    new TIdentifier("int"), null),
                                                                                new TIdentifier("size"), null)
                                                                        },
                                                                    new AABlock(new ArrayList(), new TRBrace("}"))));
                                }
                                foreach (StructDescription str in targetStructs)
                                {
                                    StructDescription targetStruct = str;
                                    StructDescription initTarget = str;
                                    while (targetStruct != null)
                                    {
                                        foreach (MethodDescription method in targetStruct.Methods)
                                        {
                                            if (!method.IsDelegate && method.Name == methodName)
                                                methods.Add(method.Decl);
                                        }
                                        targetStruct = targetStruct.Base;
                                        if (targetStruct == initTarget)
                                            break;
                                    }
                                }

                                foreach (EnrichmentDescription enrichment in targetEnrichments)
                                {
                                    foreach (MethodDescription method in enrichment.Methods)
                                    {
                                        if (!method.IsDelegate && method.Name == methodName)
                                            methods.Add(method.Decl);
                                    }
                                }
                                foreach (MethodDescription method in delegateTargets)
                                {
                                    methods.Add(method.Decl);
                                }

                                //Go back past all dot identifier, and see if you find a new

                                if (targetNamespaces.Count > 0)
                                {
                                    bool foundNewToken = false;
                                    while (tokens.Count > 0)
                                    {
                                        token = tokens[tokens.Count - 1];
                                        tokens.RemoveAt(tokens.Count - 1);

                                        if (token is TIdentifier || token is TDot)
                                            continue;

                                        if (token is TNew)
                                            foundNewToken = true;
                                        break;
                                    }

                                    if (foundNewToken)
                                    {
                                        foreach (NamespaceDescription ns in targetNamespaces)
                                        {
                                            foreach (StructDescription str in ns.Structs)
                                            {
                                                if (str.Name == methodName)
                                                {
                                                    foreach (MethodDescription method in str.Constructors)
                                                    {
                                                        methods.Add(method.Decl);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        foreach (NamespaceDescription ns in targetNamespaces)
                                        {
                                            foreach (MethodDescription method in ns.Methods)
                                            {
                                                if (!method.IsDelegate && method.Name == methodName)
                                                    methods.Add(method.Decl);
                                            }
                                        }
                                    }
                                }
                                if (!isGlobal || methods.Count > 0)
                                    return methods;
                            }
                            if (token is TNew)
                            {//Find matching constructors
                                foreach (SourceFileContents file in Compiler.ParsedSourceFiles)
                                {
                                    foreach (StructDescription str in file.Structs)
                                    {
                                        if (str.Name == methodName)
                                        {
                                            foreach (MethodDescription constructor in str.Constructors)
                                            {
                                                methods.Add(constructor.Decl);
                                            }
                                            return methods;
                                        }
                                    }
                                }

                            }

                            object openFileData = currentEditor.Tag is Form1.OpenFileData
                                                      ? ((Form1.OpenFileData)currentEditor.Tag).File
                                                      : (object)((DialogData)currentEditor.Tag).DialogItem;
                            SourceFileContents currentSourceFile = null;
                            foreach (SourceFileContents sourceFileContents in Compiler.ParsedSourceFiles)
                            {
                                if (openFileData == sourceFileContents.Item && !sourceFileContents.IsDialogDesigner)
                                {
                                    currentSourceFile = sourceFileContents;
                                    break;
                                }
                            }
                            if (currentSourceFile == null)
                                return new List<AMethodDecl>();
                            if (!isGlobal)
                            {
                                //Current struct
                                int line = CurrentEditor.caret.Position.Line;
                                foreach (StructDescription structDescription in currentSourceFile.Structs)
                                {
                                    if (structDescription.LineFrom <= line && line <= structDescription.LineTo)
                                    {
                                        StructDescription target = structDescription;
                                        StructDescription initTarget = target;
                                        while (target != null)
                                        {
                                            foreach (MethodDescription method in structDescription.Methods)
                                            {
                                                if (!method.IsDelegate && method.Name == methodName)
                                                    methods.Add(method.Decl);
                                            }
                                            target = target.Base;
                                            if (target == initTarget)
                                                break;
                                        }
                                    }
                                }
                                //Current enrichment
                                foreach (EnrichmentDescription enrichment in currentSourceFile.Enrichments)
                                {
                                    if (enrichment.LineFrom <= line && line <= enrichment.LineTo)
                                    {
                                        foreach (MethodDescription method in enrichment.Methods)
                                        {
                                            if (!method.IsDelegate && method.Name == methodName)
                                                methods.Add(method.Decl);
                                        }
                                    }
                                }
                            }
                            if (methods.Count == 0)
                            {
                                //It is a global method
                                foreach (SourceFileContents sourceFile in Compiler.ParsedSourceFiles)
                                {
                                    /*if (!currentSourceFile.CanSeeOther(sourceFile))
                                        continue;*/

                                    foreach (MethodDescription method in sourceFile.Methods)
                                    {
                                        if (method.Visibility is APrivateVisibilityModifier &&
                                            sourceFile.Namespace != currentSourceFile.Namespace)
                                            continue;

                                        if (!method.IsDelegate && method.Name == methodName)
                                            methods.Add(method.Decl);
                                    }
                                }
                                foreach (AMethodDecl method in Compiler.libraryData.Methods)
                                {
                                    if (method.GetName().Text == methodName)
                                        methods.Add(method);
                                }
                            }
                            return methods;
                        }
                        else
                        {
                            commaCount = 0;
                            continue;
                        }
                    }
                }
                if (token is TRParen || token is TRBracket)
                    openParens++;
                if (token is TLBracket)
                {
                    if (openParens > 0)
                        openParens--;
                    else
                        commaCount = 0;
                }
                if (token is TComma && openParens == 0)
                    commaCount++;
                if (token is TSemicolon || token is TLBrace || token is TRBrace)
                    return new List<AMethodDecl>();
                token = tokens[tokens.Count - 1];
                tokens.RemoveAt(tokens.Count - 1);
            }
            return new List<AMethodDecl>();
        }
        private bool ExtractMatchData(bool spacePressed = false)
        {
            currentRebuildData.targetEnrichments = new List<EnrichmentDescription>();
            currentRebuildData.targetStructs = new List<StructDescription>();
            currentRebuildData.namespacePrefixes = new List<NamespaceDescription>();
            currentRebuildData.suggestArrayLength = false;
            currentRebuildData.onlySuggestVariablesInsideMethods = false;
            currentRebuildData.onlySuggestMethods = false;
            currentRebuildData.onlySuggestInitKeywords = false;
            currentRebuildData.onlySuggestDelegates = false;
            currentRebuildData.isDelegateInvoke = false;
            currentRebuildData.staticStructs = new List<StructDescription>();
            currentRebuildData.isDynamicArray = false;
            currentRebuildData.targetTypedefs = new List<TypedefDescription>();
            string text = currentEditor.GetTextWithin(new TextPoint(0, 0), currentEditor.caret.Position);
            //Last typed character must be an identifier letter or a .
            if (!spacePressed)
            if (text.Length == 0 || !(text[text.Length - 1] == '.' || text[text.Length - 1] == '>' || Util.IsIdentifierLetter(text[text.Length - 1]) || /*text[text.Length - 1] == '#' ||*/ text[text.Length - 1] > 0xFF))
                return false;
            Lexer lexer = new Lexer(new StringReader(text));
            List<Token> tokens = new List<Token>();
            Token token, lastToken = null;
            bool inString = false;
            bool inEnum = false;
            while (true)
            {
                try
                {
                    token = lexer.Next();
                    if (token is EOF)
                        break;
                }
                catch (Exception err)
                {
                    continue;
                }
                lastToken = token;
                if (token is TEnum)
                    inEnum = true;
                if (token is TRBrace)
                    inEnum = false;
                //We can be in a string if there was an unclosed " on this line
                if (token is TUnknown && token.Text == "\"" || token.Text == "'")
                    inString = true;
                if (token is TWhiteSpace)
                {
                    if (token.Text == "\n")
                        inString = false;
                    continue;
                }
                //If this is true, we have an open block comment with no end, so we're in a comment
                if (token is TCommentBegin)
                    return false;

                if (token is TArrow)
                    token = new TDot(".");

                tokens.Add(token);
            }
            if (inString) return false;
            if (inEnum) return false;
            if (spacePressed && (lastToken == null || !(lastToken is TDot || lastToken is TIdentifier)))
                tokens.Add(new TIdentifier(""));

            //The last entered token can either be an identifier, a dot, or a line comment
            token = tokens[tokens.Count - 1];
            tokens.RemoveAt(tokens.Count - 1);
            if (token is TEndOfLineComment)
                return false;
            //Remove all other comments
            for (int i = 0; i < tokens.Count; i++)
            {
                if (tokens[i] is TTraditionalComment || tokens[i] is TEndOfLineComment || tokens[i] is TDocumentationComment)
                {
                    tokens.RemoveAt(i);
                    i--;
                }
            }

            //Set the current search text
            if (token is TDot) currentRebuildData.caseSensitiveMatchText = currentRebuildData.matchText = "";
            else
            {
                currentRebuildData.matchText = token.Text.ToLower();
                currentRebuildData.caseSensitiveMatchText = token.Text;
            }
            //If this token is a dot, or the previous is a dot, find the type of whats before the dot
            if (token is TIdentifier && tokens.Count > 0 && tokens[tokens.Count - 1] is TDot)
            {
                token = tokens[tokens.Count - 1];
                tokens.RemoveAt(tokens.Count - 1);
            }
            bool isGlobal = false;
            if (token is TDot)
            {
                List<MethodDescription> delegateTargets;
                ExtractTargetType(text, out currentRebuildData.targetStructs, out currentRebuildData.targetEnrichments,
                                    out currentRebuildData.namespacePrefixes, out currentRebuildData.isDelegateInvoke,
                                    out currentRebuildData.staticStructs, out currentRebuildData.isGlobal, out delegateTargets, out currentRebuildData.isDynamicArray);
                /*MethodDescription methodDescription;
                currentRebuildData.targetStruct = GetTargetStruct(token, tokens, out isGlobal,
                                                                  out currentRebuildData.suggestArrayLength,
                                                                  out currentRebuildData.namespacePrefix,
                                                                  out currentRebuildData.isDelegateInvoke,
                                                                  out methodDescription,
                                                                  out currentRebuildData.staticStruct);*/

                if (currentRebuildData.isDelegateInvoke)
                {
                    currentRebuildData.suggestTypes = false;
                    currentRebuildData.suggestVariables = false;
                    currentRebuildData.suggestKeywords = false;
                    return true;
                }

                if (tokens.Count > 2 && tokens[tokens.Count - 1] is TLt && (tokens[tokens.Count - 2] is TAsyncInvoke || tokens[tokens.Count - 2] is TSyncInvoke))
                {
                    currentRebuildData.onlySuggestMethods = true;
                }

                if (currentRebuildData.targetStructs.Count > 0 || currentRebuildData.staticStructs.Count > 0 || currentRebuildData.targetEnrichments.Count > 0 || currentRebuildData.suggestArrayLength)
                {
                    currentRebuildData.suggestTypes = false;
                    currentRebuildData.suggestVariables = true;
                    currentRebuildData.suggestKeywords = false;
                    return true;
                }
                if (currentRebuildData.isGlobal)
                {
                    if (currentRebuildData.namespacePrefixes.Count > 0)
                    //tokens.Clear();
                    {
                        currentRebuildData.suggestKeywords = false;
                        currentRebuildData.suggestTypes = true;
                        currentRebuildData.suggestVariables = true;
                        return true;
                    }
                    else
                    {
                        currentRebuildData.suggestKeywords = true;
                        currentRebuildData.suggestTypes = true;
                        currentRebuildData.suggestVariables = false;
                        return true;
                    }
                }
                if (currentRebuildData.namespacePrefixes.Count > 0)
                {
                    currentRebuildData.suggestKeywords = false;
                    currentRebuildData.suggestTypes = true;
                    currentRebuildData.suggestVariables = true;
                    return true;
                }
                if (currentRebuildData.isDynamicArray)
                    return true;
                return false;
            }
            if (isGlobal || token is TIdentifier)
            {
                //Ensure that we are writing a type, expression or keyword
                /*
                 * If no previous: decl
                 * If previous was a string, and the one before that was include: includeDecl -> decl
                 * If previous was a { } or a ;: stm -> stm, block->stm, fieldDecl->decl, structDecl->decl
                 * If previous was a , + - * / % ! < > = == <= >= != += -= *= /= %= ( & | ^ && || << >> ): rightHandSide, methodParams, if -> stm
                 */
                if (tokens.Count == 0)
                {
                    currentRebuildData.suggestKeywords = true;
                    currentRebuildData.suggestTypes = true;
                    currentRebuildData.suggestVariables = false;
                    return true;
                }
                token = tokens[tokens.Count - 1];
                tokens.RemoveAt(tokens.Count - 1);

                if (token is TIdentifier && tokens.Count > 0 && (tokens[tokens.Count - 1] is TNamespace || tokens[tokens.Count - 1] is TUsing))
                {
                    currentRebuildData.suggestKeywords = true;
                    currentRebuildData.suggestTypes = true;
                    currentRebuildData.suggestVariables = false;
                    return true;
                }
                if (token is TStringLiteral)
                {
                    if (tokens.Count == 0)
                        return false;
                    token = tokens[tokens.Count - 1];
                    tokens.RemoveAt(tokens.Count - 1);
                    if (token is TInclude)
                    {
                        currentRebuildData.suggestKeywords = true;
                        currentRebuildData.suggestTypes = true;
                        currentRebuildData.suggestVariables = false;
                        return true;
                    }
                    return false;
                }
                if (token is TLt && tokens.Count > 0 && (tokens[tokens.Count - 1] is TSyncInvoke || tokens[tokens.Count - 1] is TSyncInvoke))
                {
                    currentRebuildData.suggestKeywords = false;
                    currentRebuildData.suggestTypes = false;
                    currentRebuildData.suggestVariables = true;
                    currentRebuildData.onlySuggestMethods = true;
                    return true;
                }
                if (token is TLt && tokens.Count > 0 && (tokens[tokens.Count - 1] is TDelegate))
                {
                    currentRebuildData.suggestKeywords = false;
                    currentRebuildData.suggestTypes = false;
                    currentRebuildData.suggestVariables = false;
                    currentRebuildData.onlySuggestMethods = false;
                    currentRebuildData.onlySuggestDelegates = true;
                    return true;
                }
                if (token is TNew)
                {
                    currentRebuildData.suggestKeywords = false;
                    currentRebuildData.suggestTypes = true;
                    currentRebuildData.suggestVariables = false;
                    return true;
                }
                {
                    //locals can be declared as const <type> name..
                    if (token is TConst)
                    {
                        currentRebuildData.suggestKeywords = false;
                        currentRebuildData.suggestTypes = true;
                        currentRebuildData.suggestVariables = false;
                        return true;
                    }
                    if (token is TNative || token is TStatic)
                    {
                        currentRebuildData.suggestKeywords = false;
                        currentRebuildData.suggestTypes = true;
                        currentRebuildData.suggestVariables = false;
                        return true;
                    }
                    if (token is TReturn)
                    {
                        currentRebuildData.suggestKeywords = false;
                        currentRebuildData.suggestTypes = false;
                        currentRebuildData.suggestVariables = true;
                        return true;
                    }
                    //Check last letter in previous token
                    switch (token.Text[token.Text.Length - 1])
                    {
                        case '{'://y y y
                        case '}':
                        case ';':
                        case ':':
                            currentRebuildData.onlySuggestVariablesInsideMethods = true;
                            currentRebuildData.suggestKeywords = true;
                            currentRebuildData.suggestTypes = true;
                            currentRebuildData.suggestVariables = true;
                            return true;
                        case ','://n y y
                        case '(':
                        case '[':
                        case '<':
                            currentRebuildData.suggestKeywords = false;
                            currentRebuildData.suggestTypes = true;
                            currentRebuildData.suggestVariables = true;
                            return true;
                        case '+'://n n y
                        case '-':
                        case '*':
                        case '/':
                        case '%':
                        case '!':
                        case '>':
                        case '=':
                        case '&':
                        case '|':
                        case '^':
                        case '?':
                        case ')':
                            currentRebuildData.suggestKeywords = false;
                            currentRebuildData.suggestTypes = true;
                            currentRebuildData.suggestVariables = true;
                            return true;
                    }
                    return false;
                }
            }
            else
            {
                //Token was not a dot or identifier
                //Could for example be if the current token is a number
                return false;
            }
        }
        public void TextRemoved(string text, MyEditor editor, TextPoint position)
        {
            AddEditorSignal(editor);

            redoList.Clear();
            //If this and the two previous can be joined into 1 token, join them in 1 undo (if they follow eachother)
            UndoItem item = new UndoItem(text, editor, position, UndoType.TextRemoved);
            if (undoList.Count > 0)
            {
                UndoItem lastItem = undoList[undoList.Count - 1];
                if (FollowEachother(item, lastItem))
                {
                    string joined = item.text + lastItem.text;
                    Lexer lexer = new Lexer(new StringReader(joined));
                    List<Token> tokens = new List<Token>();
                    while (!(lexer.Peek() is EOF))
                    {
                        tokens.Add(lexer.Next());
                    }
                    if (tokens.Count == 1 || tokens.All(elm => elm is TWhiteSpace))
                    {
                        lastItem.text = joined;
                        lastItem.position = item.position;
                        item = lastItem;

                        if (undoList.Count > 1)
                        {
                            lastItem = undoList[undoList.Count - 2];
                            if (FollowEachother(item, lastItem))
                            {
                                joined = item.text + lastItem.text;
                                lexer = new Lexer(new StringReader(joined));
                                tokens = new List<Token>();
                                while (!(lexer.Peek() is EOF))
                                {
                                    tokens.Add(lexer.Next());
                                }
                                if (tokens.Count == 1 || tokens.All(elm => elm is TWhiteSpace))
                                {
                                    lastItem.text = joined;
                                    lastItem.position = item.position;
                                    undoList.RemoveAt(undoList.Count - 1);
                                }
                            }
                        }
                        return;
                    }
                }
            }
            undoList.Add(item);
        }