public static string FindAttributeName (MonoDevelop.Ide.Gui.TextEditor editor, ICompilationUnit unit, string fileName)
		{
			string documentToCursor = editor.GetText (0, editor.CursorPosition);
			int pos = -1;
			for (int i = documentToCursor.Length - 1; i >= 0; i--) {
				if (documentToCursor[i] == '[') {
					pos = i;
					break;
				}
			}
			if (pos <= 0)
				return null;
			pos++;
			StringBuilder result = new StringBuilder ();
			while (pos < documentToCursor.Length) {
				char ch = documentToCursor[pos];
				if (!(Char.IsLetterOrDigit (ch) || ch == '_'))
					break;
				result.Append (ch);
				pos++;
			}
			return result.ToString ();
		}
 internal static string GetIndentString(MonoDevelop.Ide.Gui.TextEditor editor, int pos)
 {
     string ch = editor.GetText (pos - 1, pos);
     int nwpos = pos;
     while (ch.Length > 0 && ch != "\n" && ch != "\r") {
         if (ch[0] != ' ' && ch[0] != '\t')
             nwpos = pos;
         pos--;
         ch = editor.GetText (pos - 1, pos);
     }
     return editor.GetText (pos, nwpos - 1);
 }
		public static string GetWordBeforeCaret (MonoDevelop.Ide.Gui.TextEditor editor)
		{
			int offset = editor.CursorPosition;
			int start  = FindPrevWordStart (editor, offset);
			return editor.GetText (start, offset);
		}
        public ExpressionContext FindExactContextForObjectInitializer(MonoDevelop.Ide.Gui.TextEditor editor, ICompilationUnit unit, string fileName, IType callingType)
        {
            string documentToCursor = editor.GetText (0, editor.CursorPosition);

            //			int pos = -1;

            // create a table with all opening brackets
            Dictionary<int, int> brackets = new Dictionary<int, int> ();
            Stack<int> bracketStack = new Stack<int> ();
            for (int i = 0; i < documentToCursor.Length; i++) {
                char ch = documentToCursor[i];
                switch (ch) {
                case '/':
                    if (i + 1 < documentToCursor.Length) {
                        if (documentToCursor[i + 1] == '/') {
                            while (i < documentToCursor.Length) {
                                if (documentToCursor[i] == '\n')
                                    break;
                                i++;
                            }
                        } else if (documentToCursor[i + 1] == '*') {
                            while (i + 1 < documentToCursor.Length) {
                                if (documentToCursor[i] == '*' && documentToCursor[i + 1] == '/')
                                    break;
                                i++;
                            }
                        }
                    }
                    break;
                case '(':
                case '{':
                case '[':
                    bracketStack.Push (i);
                    break;
                case ')':
                case '}':
                case ']':
                    if (bracketStack.Count > 0)
                        brackets[i] = bracketStack.Pop ();
                    break;
                }
            }
            bool foundCurlyBrace = false;
            for (int i = documentToCursor.Length - 1; i >= 0; i--) {
                if (documentToCursor[i] == '{') {
                    foundCurlyBrace = true;
                }
                if (documentToCursor[i] == ')' || documentToCursor[i] == '}' || documentToCursor[i] == ']') {
                    int newPos;
                    if (brackets.TryGetValue (i, out newPos)) {
                        i = newPos;
                        // we've had a  Property = new Name (), expression, now search for the '='
                        // otherwise the "new Name" would be falsly taken as object initializer
                        if (!foundCurlyBrace) {
                            while (i >= 0) {
                                if (documentToCursor[i] == '=' || documentToCursor[i] == ';')
                                    break;
                                i--;
                            }
                        }
                        continue;
                    }
                }
                if (i + 4 < documentToCursor.Length && documentToCursor.Substring (i, 4) == "new ") {
                    bool skip = false;
                    for (int j2 = i; j2 < documentToCursor.Length; j2++) {
                        if (documentToCursor[j2] == '{')
                            break;
                        if (documentToCursor[j2] == ',') {
                            skip = true;
                            break;
                        }
                    }

                    if (skip)
                        continue;

                    int j = i + 4;
                    while (j < documentToCursor.Length && Char.IsWhiteSpace (documentToCursor[j]))
                        j++;
            //					int start = j;
                    while (j < documentToCursor.Length && (Char.IsLetterOrDigit (documentToCursor[j]) || documentToCursor[j] == '_' || documentToCursor[j] == '.'))
                        j++;

                    ExpressionResult firstExprs = FindExpression (documentToCursor, j);
                    if (firstExprs.Expression != null) {
                        IReturnType unresolvedReturnType = NRefactoryResolver.ParseReturnType (firstExprs);
                        if (unresolvedReturnType != null) {
                            IType resolvedType = projectContent.SearchType (new SearchTypeRequest (unit, unresolvedReturnType, callingType));
                            return ExpressionContext.TypeDerivingFrom (resolvedType != null ? new DomReturnType (resolvedType) : null, unresolvedReturnType, true);
                        }
                    }

                }
            }
            return null;
        }
        public ExpressionContext FindExactContextForNewCompletion(MonoDevelop.Ide.Gui.TextEditor editor, ICompilationUnit unit, string fileName, IType callingType, int cursorPos)
        {
            // find expression on left hand side of the assignment
            string documentToCursor = editor.GetText (0, cursorPos);
            int pos = -1;
            for (int i = documentToCursor.Length - 1; i >= 0; i--) {
                if (documentToCursor[i] == '=') {
                    if (i > 0 && (documentToCursor[i - 1] == '+' || documentToCursor[i - 1] == '-'))
                        i--;
                    pos = i;
                    break;
                }
            }
            if (pos <= 0)
                return null;

            // check if new +=/-=/= is right before "new"
            for (int i = pos; i < cursorPos; i++) {
                char ch = documentToCursor[i];
                if (Char.IsWhiteSpace (ch))
                    continue;
                if (ch != '=' && ch != '+' && ch != '-' && ch != 'n' && ch != 'e' && ch != 'w')
                    return null;
            }
            int lastWs = pos - 1;
            while (lastWs > 0 && Char.IsWhiteSpace (documentToCursor[lastWs]))
                lastWs--;
            while (lastWs > 0 && !Char.IsWhiteSpace (documentToCursor[lastWs]))
                lastWs--;
            ExpressionResult firstExprs = FindExpression (documentToCursor, lastWs);

            if (firstExprs.Expression != null) {
                IReturnType unresolvedReturnType = NRefactoryResolver.ParseReturnType (firstExprs);
                if (unresolvedReturnType != null) {
                    IType resolvedType = projectContent.SearchType (new SearchTypeRequest (unit, unresolvedReturnType, callingType));
                    return ExpressionContext.TypeDerivingFrom (resolvedType != null ? new DomReturnType (resolvedType) : null, unresolvedReturnType, true);
                }

            }

            ExpressionResult lhsExpr = FindExpression (documentToCursor, pos);
            if (lhsExpr.Expression != null) {
                NRefactoryResolver resolver = new NRefactoryResolver (projectContent, unit, ICSharpCode.NRefactory.SupportedLanguage.CSharp, editor, fileName);

                ResolveResult rr = resolver.Resolve (lhsExpr, new DomLocation (editor.CursorLine, editor.CursorColumn));
                //ResolveResult rr = ParserService.Resolve (lhsExpr, currentLine.LineNumber, pos, editor.FileName, editor.Text);

                if (rr != null && rr.ResolvedType != null) {
                    ExpressionContext context;
                    IType c;
                    /*					if (rr.ResolvedType.IsArrayReturnType) {
                        // when creating an array, all classes deriving from the array's element type are allowed
                        IReturnType elementType = rr.ResolvedType.CastToArrayReturnType().ArrayElementType;
                        c = elementType != null ? dom.GetType (elementType) : null;
                        context = ExpressionContext.TypeDerivingFrom(elementType, false);
                    } else */					{
                        // when creating a normal instance, all non-abstract classes deriving from the type
                        // are allowed
                        c = projectContent.GetType (rr.ResolvedType);
                        context = ExpressionContext.TypeDerivingFrom (rr.ResolvedType, null, true);
                    }
                    if (c != null && !context.FilterEntry (c)) {
                        // Try to suggest an entry (List<int> a = new => suggest List<int>).

                        string suggestedClassName = null;
                        /*LanguageProperties.CSharp.CodeGenerator.GenerateCode(
                            CodeGenerator.ConvertType(
                                rr.ResolvedType,
                                new ClassFinder(ParserService.GetParseInformation(editor.FileName), editor.ActiveTextAreaControl.Caret.Line + 1, editor.ActiveTextAreaControl.Caret.Column + 1)
                            ), "");*/						if (suggestedClassName != c.Name) {
                            // create an IType instance that includes the type arguments in its name
                            //context.DefaultItem = new RenamedClass (c, suggestedClassName);
                        } else {
                            context.DefaultItem = c;
                        }
                    }
                    return context;
                }
            }
            return null;
        }