public bool TryGetChild(char letter, out ACNode child)
 {
     return this.children.TryGetValue(letter, out child);
 }
 public ACTree(List<string> words)
 {
     root = new ACNode("");
     foreach(string word in words)
     {
         ACNode parent = root;
         ACNode child;
         int cnt = 1;
         foreach(char letter in word.ToCharArray())
         {
             if(!parent.TryGetChild(letter, out child))
             {
                 string value = (cnt < word.Length) ? "" : word;
                 child = new ACNode(value);
                 parent.Add(letter, child);
             }
             parent = child;
             cnt++;
         }
     }
 }
 public void Add(char letter, ACNode child)
 {
     this.children.Add (letter, child);
 }
        //private readonly Regex methodExp = new Regex(@"(?<=\.)[A-Za-z_]\w*", RegexOptions.RightToLeft);
        private void EvaluateIntelliSense()
        {
            if (editor.SelectionLength > 0)
            {
                HideISAC();
                return;
            }

            var currentLineIndex     = editor.TextArea.Caret.Line - 1;
            var line                 = editor.Document.Lines[currentLineIndex];
            var text                 = editor.Document.GetText(line.Offset, line.Length);
            var lineOffset           = editor.TextArea.Caret.Column - 1;
            var caretOffset          = editor.CaretOffset;
            var ForwardShowAC        = false;
            var ForwardShowIS        = false;
            var ISFuncNameStr        = string.Empty;
            var ISFuncDescriptionStr = string.Empty;
            var ForceReSet           = currentLineIndex != LastShowedLine;
            var ForceISKeepsClosed   = ForceReSet;
            var xPos                 = int.MaxValue;

            LastShowedLine = currentLineIndex;
            var quotationCount = 0;
            var MethodAC       = false;

            for (var i = 0; i < lineOffset; ++i)
            {
                if (text[i] == '"')
                {
                    if (i != 0)
                    {
                        if (text[i - 1] != '\\')
                        {
                            quotationCount++;
                        }
                    }
                }

                if (quotationCount % 2 == 0)
                {
                    if (text[i] == '/')
                    {
                        if (i != 0)
                        {
                            if (text[i - 1] == '/')
                            {
                                HideISAC();
                                return;
                            }
                        }
                    }
                }
            }

            foreach (var c in text)
            {
                if (c == '#')
                {
                    string[] prep = { "define", "pragma", "file", "if" };
                    acEntrys = ACNode.ConvertFromStringArray(prep, false, "#").ToArray();
                    // HideISAC();
                    break;
                }

                if (!char.IsWhiteSpace(c))
                {
                    break;
                }
            }

            var mc = multilineCommentRegex.Matches(editor.Text,
                                                   0); //it hurts me to do it here..but i have no other choice...
            var mlcCount = mc.Count;

            for (var i = 0; i < mlcCount; ++i)
            {
                if (caretOffset >= mc[i].Index)
                {
                    if (caretOffset <= mc[i].Index + mc[i].Length)
                    {
                        HideISAC();
                        return;
                    }
                }
                else
                {
                    break;
                }
            }

            if (lineOffset > 0)
            {
                #region IS

                var ISMatches  = ISFindRegex.Matches(text);
                var scopeLevel = 0;
                for (var i = lineOffset - 1; i >= 0; --i)
                {
                    if (text[i] == ')')
                    {
                        scopeLevel++;
                    }
                    else if (text[i] == '(')
                    {
                        scopeLevel--;
                        if (scopeLevel >= 0)
                        {
                            continue;
                        }

                        var FoundMatch  = false;
                        var searchIndex = i;
                        for (var j = 0; j < ISMatches.Count; ++j)
                        {
                            if (searchIndex >= ISMatches[j].Index &&
                                searchIndex <= ISMatches[j].Index + ISMatches[j].Length)
                            {
                                FoundMatch = true;
                                var testString  = ISMatches[j].Groups["name"].Value;
                                var classString = ISMatches[j].Groups["class"].Value;
                                if (classString.Length > 0)
                                {
                                    var methodString = ISMatches[j].Groups["method"].Value;
                                    var found        = false;

                                    // Match for static methods.
                                    var staticMethodMap = methodMaps.FirstOrDefault(e => e.Name == classString);
                                    var staticMethod    =
                                        staticMethodMap?.Methods.FirstOrDefault(e => e.Name == methodString);
                                    if (staticMethod != null)
                                    {
                                        xPos = ISMatches[j].Groups["method"].Index +
                                               ISMatches[j].Groups["method"].Length;
                                        ForwardShowIS        = true;
                                        ISFuncNameStr        = staticMethod.FullName;
                                        ISFuncDescriptionStr = staticMethod.CommentString;
                                        ForceReSet           = true;
                                        found = true;
                                    }

                                    // Try to find declaration
                                    if (!found)
                                    {
                                        var pattern =
                                            $@"\b((?<class>[a-zA-Z_]([a-zA-Z0-9_]?)+))\s+({classString})\s*(;|=)";
                                        var findDecl   = new Regex(pattern, RegexOptions.Compiled);
                                        var match      = findDecl.Match(editor.Text);
                                        var classMatch = match.Groups["class"].Value;
                                        if (classMatch.Length > 0)
                                        {
                                            var methodMap = methodMaps.FirstOrDefault(e => e.Name == classMatch);
                                            var method    =
                                                methodMap?.Methods.FirstOrDefault(e => e.Name == methodString);
                                            if (method != null)
                                            {
                                                xPos = ISMatches[j].Groups["method"].Index +
                                                       ISMatches[j].Groups["method"].Length;
                                                ForwardShowIS        = true;
                                                ISFuncNameStr        = method.FullName;
                                                ISFuncDescriptionStr = method.CommentString;
                                                ForceReSet           = true;
                                                found = true;
                                            }
                                        }
                                    }

                                    // Match the first found
                                    if (!found)
                                    {
                                        // Match any methodmap, since the ide is not aware of the types
                                        foreach (var methodMap in methodMaps)
                                        {
                                            var method =
                                                methodMap.Methods.FirstOrDefault(e => e.Name == methodString);

                                            if (method == null)
                                            {
                                                continue;
                                            }

                                            xPos = ISMatches[j].Groups["method"].Index +
                                                   ISMatches[j].Groups["method"].Length;
                                            ForwardShowIS        = true;
                                            ISFuncNameStr        = method.FullName;
                                            ISFuncDescriptionStr = method.CommentString;
                                            ForceReSet           = true;
                                        }
                                    }
                                }
                                else
                                {
                                    var func = funcs.FirstOrDefault(e => e.Name == testString);
                                    if (func != null)
                                    {
                                        xPos = ISMatches[j].Groups["name"].Index +
                                               ISMatches[j].Groups["name"].Length;
                                        ForwardShowIS        = true;
                                        ISFuncNameStr        = func.FullName;
                                        ISFuncDescriptionStr = func.CommentString;
                                        ForceReSet           = true;
                                    }
                                }

                                break;
                            }
                        }

                        if (FoundMatch)
                        {
                            // ReSharper disable once RedundantAssignment
                            scopeLevel--; //i have no idea why this works...
                            break;
                        }
                    }
                }

                #endregion

                #region AC

                if (IsValidFunctionChar(text[lineOffset - 1]) && quotationCount % 2 == 0)
                {
                    var IsNextCharValid = true;
                    if (text.Length > lineOffset)
                    {
                        if (IsValidFunctionChar(text[lineOffset]) || text[lineOffset] == '(')
                        {
                            IsNextCharValid = false;
                        }
                    }

                    if (IsNextCharValid)
                    {
                        var endOffset = lineOffset - 1;
                        for (var i = endOffset; i >= 0; --i)
                        {
                            if (!IsValidFunctionChar(text[i]))
                            {
                                if (text[i] == '.')
                                {
                                    MethodAC = true;
                                }

                                break;
                            }

                            endOffset = i;
                        }

                        var testString = text.Substring(endOffset, lineOffset - 1 - endOffset + 1);
                        if (testString.Length > 0)
                        {
                            if (MethodAC)
                            {
                                for (var i = 0; i < isEntrys.Length; ++i)
                                {
                                    if (isEntrys[i].EntryName.StartsWith(testString,
                                                                         StringComparison.InvariantCultureIgnoreCase))
                                    {
                                        if (testString != isEntrys[i].EntryName)
                                        {
                                            ForwardShowAC = true;
                                            MethodAutoCompleteBox.SelectedIndex = i;
                                            MethodAutoCompleteBox.ScrollIntoView(MethodAutoCompleteBox.SelectedItem);
                                            break;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                for (var i = 0; i < acEntrys.Length; ++i)
                                {
                                    if (acEntrys[i].EntryName.StartsWith(testString,
                                                                         StringComparison.InvariantCultureIgnoreCase))
                                    {
                                        if (testString != acEntrys[i].EntryName)
                                        {
                                            ForwardShowAC = true;
                                            AutoCompleteBox.SelectedIndex = i;
                                            AutoCompleteBox.ScrollIntoView(AutoCompleteBox.SelectedItem);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                #endregion
            }

            if (!ForwardShowAC)
            {
                if (ForceISKeepsClosed)
                {
                    ForwardShowIS = false;
                }
            }

            if (ForwardShowAC | ForwardShowIS)
            {
                if (ForwardShowAC)
                {
                    ShowAC(!MethodAC);
                }
                else
                {
                    HideAC();
                }

                if (ForwardShowIS)
                {
                    ShowIS(ISFuncNameStr, ISFuncDescriptionStr);
                }
                else
                {
                    HideIS();
                }

                if (ForceReSet && ISAC_Open)
                {
                    SetISACPosition(xPos);
                }

                ShowISAC(xPos);
            }
            else
            {
                HideISAC();
            }
        }