/// <summary>
        /// Perform constructor-specific completion
        /// </summary>
        private ValaCompletionDataList CompleteConstructor(string lineText, int line, int column)
        {
            ProjectInformation parser = Parser;
            Match match = initializationRegex.Match(lineText);
            ValaCompletionDataList list = new ValaCompletionDataList();

            ThreadPool.QueueUserWorkItem(delegate {
                if (match.Success)
                {
                    // variable initialization
                    if (match.Groups["typename"].Success || "var" != match.Groups["typename"].Value)
                    {
                        // simultaneous declaration and initialization
                        parser.GetConstructorsForType(match.Groups["typename"].Value, Document.FileName, line, column, list);
                    }
                    else if (match.Groups["variable"].Success)
                    {
                        // initialization of previously declared variable
                        parser.GetConstructorsForExpression(match.Groups["variable"].Value, Document.FileName, line, column, list);
                    }
                    if (0 == list.Count)
                    {
                        // Fallback to known types
                        parser.GetTypesVisibleFrom(Document.FileName, line, column, list);
                    }
                }
            });

            return(list);
        }        // CompleteConstructor
        public override ICompletionDataList HandleCodeCompletion(
            CodeCompletionContext completionContext, char completionChar)
        {
            string             lineText = null;
            ProjectInformation parser   = Parser;
            var loc = Editor.Document.OffsetToLocation(completionContext.TriggerOffset);
            int line = loc.Line, column = loc.Column;

            switch (completionChar)
            {
            case '.':             // foo.[complete]
                lineText = Editor.GetLineText(line);
                if (column > lineText.Length)
                {
                    column = lineText.Length;
                }
                lineText = lineText.Substring(0, column - 1);

                string itemName = GetTrailingSymbol(lineText);

                if (string.IsNullOrEmpty(itemName))
                {
                    return(null);
                }

                return(GetMembersOfItem(itemName, line, column));

            case '\t':
            case ' ':
                lineText = Editor.GetLineText(line);
                if (0 == lineText.Length)
                {
                    return(null);
                }
                if (column > lineText.Length)
                {
                    column = lineText.Length;
                }
                lineText = lineText.Substring(0, column - 1).Trim();

                if (lineText.EndsWith("new"))
                {
                    return(CompleteConstructor(lineText, line, column));
                }
                else if (lineText.EndsWith("is"))
                {
                    ValaCompletionDataList list = new ValaCompletionDataList();
                    ThreadPool.QueueUserWorkItem(delegate {
                        parser.GetTypesVisibleFrom(Document.FileName, line, column, list);
                    });
                    return(list);
                }
                else if (0 < lineText.Length)
                {
                    char lastNonWS = lineText[lineText.Length - 1];
                    if (0 <= Array.IndexOf(operators, lastNonWS) ||
                        (1 == lineText.Length && 0 > Array.IndexOf(allowedChars, lastNonWS)))
                    {
                        return(GlobalComplete(completionContext));
                    }
                }

                break;

            default:
                if (0 <= Array.IndexOf(operators, completionChar))
                {
                    return(GlobalComplete(completionContext));
                }
                break;
            }

            return(null);
        }