CompletionDataList CreateTypeCompletionData (DomLocation location, IType callingType, ExpressionContext context, IReturnType returnType, IReturnType returnTypeUnresolved)
		{
			CompletionDataList result = new ProjectDomCompletionDataList ();
			// "var o = new " needs special treatment.
			if (returnType == null && returnTypeUnresolved != null && returnTypeUnresolved.FullName == "var")
				returnType = returnTypeUnresolved = DomReturnType.Object;

			//	ExpressionContext.TypeExpressionContext tce = context as ExpressionContext.TypeExpressionContext;

			CompletionDataCollector col = new CompletionDataCollector (dom, result, Document.CompilationUnit, callingType, location);
			IType type = null;
			if (returnType != null)
				type = dom.GetType (returnType);
			if (type == null)
				type = dom.SearchType (Document.CompilationUnit, (MonoDevelop.Projects.Dom.INode)Document.CompilationUnit ?? callingType, returnTypeUnresolved);
			
			// special handling for nullable types: Bug 674516 - new completion for nullables should not include "Nullable"
			if (type is InstantiatedType && ((InstantiatedType)type).UninstantiatedType.FullName == "System.Nullable" && ((InstantiatedType)type).GenericParameters.Count == 1) {
				var genericParameter = ((InstantiatedType)type).GenericParameters[0];
				returnType = returnTypeUnresolved = Document.CompilationUnit.ShortenTypeName (genericParameter, location);
				type = dom.SearchType (Document.CompilationUnit, (MonoDevelop.Projects.Dom.INode)Document.CompilationUnit ?? callingType, genericParameter);
			}
			
			if (type == null || !(type.IsAbstract || type.ClassType == ClassType.Interface)) {
				if (type == null || type.ConstructorCount == 0 || type.Methods.Any (c => c.IsConstructor && c.IsAccessibleFrom (dom, callingType, type, callingType != null && dom.GetInheritanceTree (callingType).Any (x => x.FullName == type.FullName)))) {
					if (returnTypeUnresolved != null) {
						col.FullyQualify = true;
						CompletionData unresovedCompletionData = col.Add (returnTypeUnresolved);
						col.FullyQualify = false;
						// don't set default completion string for arrays, since it interferes with: 
						// string[] arr = new string[] vs new { "a"}
						if (returnTypeUnresolved.ArrayDimensions == 0)
							result.DefaultCompletionString = StripGenerics (unresovedCompletionData.CompletionText);
					} else {
						CompletionData unresovedCompletionData = col.Add (returnType);
						if (returnType.ArrayDimensions == 0)
							result.DefaultCompletionString = StripGenerics (unresovedCompletionData.CompletionText);
					}
				}
			}
			
			//				if (tce != null && tce.Type != null) {
			//					result.DefaultCompletionString = StripGenerics (col.AddCompletionData (result, tce.Type).CompletionString);
			//				} 
			//			else {
			//			}
			if (type == null)
				return result;
			HashSet<string> usedNamespaces = new HashSet<string> (GetUsedNamespaces ());
			if (type.FullName == DomReturnType.Object.FullName) 
				AddPrimitiveTypes (col);
			
			foreach (IType curType in dom.GetSubclasses (type)) {
				if (context != null && context.FilterEntry (curType))
					continue;
				if ((curType.TypeModifier & TypeModifier.HasOnlyHiddenConstructors) == TypeModifier.HasOnlyHiddenConstructors)
					continue;
				if (usedNamespaces.Contains (curType.Namespace)) {
					if (curType.ConstructorCount > 0) {
						if (!(curType.Methods.Any (c => c.IsConstructor && c.IsAccessibleFrom (dom, curType, callingType, callingType != null && dom.GetInheritanceTree (callingType).Any (x => x.FullName == curType.FullName)))))
							continue;
					}
					col.Add (curType);
				} else {
					string nsName = curType.Namespace;
					int idx = nsName.IndexOf ('.');
					if (idx >= 0)
						nsName = nsName.Substring (0, idx);
					col.Add (new Namespace (nsName));
				}
			}
			
			// add aliases
			if (returnType != null) {
				foreach (IUsing u in Document.CompilationUnit.Usings) {
					foreach (KeyValuePair<string, IReturnType> alias in u.Aliases) {
						if (alias.Value.ToInvariantString () == returnType.ToInvariantString ())
							result.Add (alias.Key, "md-class");
					}
				}
			}
			return result;
		}
			internal void SetContext (ExpressionContext context)
			{
				this.contexts.Add (context);
				this.expectedType = null;
			}
		public CompletionDataList CreateParameterCompletion (NRefactoryResolver resolver, DomLocation location, ExpressionContext context, IEnumerable<IMethod> possibleMethods, int parameter)
		{
			CompletionDataList completionList = new ProjectDomCompletionDataList ();
			var addedEnums = new HashSet<string> ();
			var addedDelegates = new HashSet<string> ();
			IType resolvedType = null;
			foreach (var method in possibleMethods) {
				if (method.Parameters.Count <= parameter)
					continue;
				resolvedType = dom.GetType (method.Parameters [parameter].ReturnType);
				if (resolvedType == null)
					continue;
				switch (resolvedType.ClassType) {
				case MonoDevelop.Projects.Dom.ClassType.Enum:
					if (addedEnums.Contains (resolvedType.DecoratedFullName))
						continue;
					addedEnums.Add (resolvedType.DecoratedFullName);
					AddEnumMembers (completionList, resolvedType);
					break;
				case MonoDevelop.Projects.Dom.ClassType.Delegate:
					if (addedDelegates.Contains (resolvedType.DecoratedFullName))
						continue;
					addedDelegates.Add (resolvedType.DecoratedFullName);
					string parameterDefinition = AddDelegateHandlers (completionList, resolvedType, false, addedDelegates.Count == 1);
					string varName = "Handle" + method.Parameters [parameter].ReturnType.Name + method.Parameters [parameter].Name;
					completionList.Add (new EventCreationCompletionData (textEditorData, varName, resolvedType, null, parameterDefinition, resolver.Unit.GetMemberAt (location), resolvedType) { AddSemicolon = false });
					break;
				}
			}
			if (addedEnums.Count + addedDelegates.Count == 0)
				return null;
			CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
			completionList.AutoCompleteEmptyMatch = false;
			completionList.AutoSelect = false;
			resolver.AddAccessibleCodeCompletionData (ExpressionContext.MethodBody, cdc);
			if (addedDelegates.Count > 0) {
				foreach (var data in completionList) {
					if (data is MemberCompletionData) 
						((MemberCompletionData)data).IsDelegateExpected = true;
				}
			}
			return completionList;
		}
		public CompletionDataList CreatePossibleEnumCompletion (NRefactoryResolver resolver, DomLocation location, ExpressionContext context, IEnumerable<IMethod> possibleMethods, int parameter)
		{
			CompletionDataList completionList = new ProjectDomCompletionDataList ();
			var addedEnums = new HashSet<string> ();
			IType resolvedType = null;
			foreach (var method in possibleMethods) {
				if (method.Parameters.Count <= parameter)
					continue;
				resolvedType = dom.GetType (method.Parameters [parameter].ReturnType);
				if (resolvedType == null || resolvedType.ClassType != ClassType.Enum)
					continue;
				if (addedEnums.Contains (resolvedType.DecoratedFullName))
					continue;
				addedEnums.Add (resolvedType.DecoratedFullName);
				AddEnumMembers (completionList, resolvedType);
			}
			if (addedEnums.Count == 0)
				return null;
			CompletionDataCollector cdc = new CompletionDataCollector (dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
			completionList.AutoCompleteEmptyMatch = false;
			//completionList.AutoSelect = false;
			resolver.AddAccessibleCodeCompletionData (context, cdc);
			return completionList;
		}
        CompletionDataList CreateTypeCompletionData(DomLocation location, IType callingType, ExpressionContext context, IReturnType returnType, IReturnType returnTypeUnresolved)
        {
            CompletionDataList result = new ProjectDomCompletionDataList ();
            // "var o = new " needs special treatment.
            if (returnType == null && returnTypeUnresolved != null && returnTypeUnresolved.FullName == "var")
                returnType = returnTypeUnresolved = DomReturnType.Object;

            //	ExpressionContext.TypeExpressionContext tce = context as ExpressionContext.TypeExpressionContext;

            CompletionDataCollector col = new CompletionDataCollector (result, Document.CompilationUnit, location);
            IType type = null;
            if (returnType != null)
                type = dom.GetType (returnType);
            if (type == null)
                type = dom.SearchType (new SearchTypeRequest (Document.CompilationUnit, returnTypeUnresolved, null));

            if (type == null || !(type.IsAbstract || type.ClassType == ClassType.Interface)) {
                if (type == null || type.ConstructorCount == 0 || type.Methods.Any (c => c.IsConstructor && c.IsAccessibleFrom (dom, callingType, type, callingType != null && dom.GetInheritanceTree (callingType).Any (x => x.FullName == type.FullName)))) {
                    if (returnTypeUnresolved != null) {
                        col.FullyQualify = true;
                        ICompletionData unresovedCompletionData = col.Add (returnTypeUnresolved);
                        col.FullyQualify = false;
                        result.DefaultCompletionString = StripGenerics (unresovedCompletionData.CompletionText);
                    } else {
                        ICompletionData unresovedCompletionData = col.Add (returnType);
                        result.DefaultCompletionString = StripGenerics (unresovedCompletionData.CompletionText);
                    }
                }
            }
            //				if (tce != null && tce.Type != null) {
            //					result.DefaultCompletionString = StripGenerics (col.AddCompletionData (result, tce.Type).CompletionString);
            //				}
            //			else {
            //			}

            if (type == null)
                return result;
            HashSet<string> usedNamespaces = new HashSet<string> (GetUsedNamespaces ());
            if (type.FullName == DomReturnType.Object.FullName)
                AddPrimitiveTypes (col);
            foreach (IType curType in dom.GetSubclasses (type)) {
                if (context != null && context.FilterEntry (curType))
                    continue;
                if ((curType.TypeModifier & TypeModifier.HasOnlyHiddenConstructors) == TypeModifier.HasOnlyHiddenConstructors)
                    continue;
                if (usedNamespaces.Contains (curType.Namespace)) {
                    if (curType.ConstructorCount > 0) {
                        if (!(curType.Methods.Any (c => c.IsConstructor && c.IsAccessibleFrom (dom, curType, callingType, callingType != null && dom.GetInheritanceTree (callingType).Any (x => x.FullName == curType.FullName)))))
                            continue;
                    }
                    col.Add (curType);
                } else {
                    string nsName = curType.Namespace;
                    int idx = nsName.IndexOf ('.');
                    if (idx >= 0)
                        nsName = nsName.Substring (0, idx);
                    col.Add (new Namespace (nsName));
                }
            }

            // add aliases
            if (returnType != null) {
                foreach (IUsing u in Document.CompilationUnit.Usings) {
                    foreach (KeyValuePair<string, IReturnType> alias in u.Aliases) {
                        if (alias.Value.ToInvariantString () == returnType.ToInvariantString ())
                            result.Add (alias.Key, "md-class");
                    }
                }
            }
            return result;
        }
 void AddContentsFromOuterClass(IType outer, ExpressionContext context, FSharpTextEditorCompletion.CompletionDataCollector col)
 {
     if (outer == null)
         return;
     foreach (IMember member in outer.Members) {
         if (member is IType || member.IsStatic || member.IsConst) {
             col.Add (member);
         }
     }
     AddContentsFromOuterClass (outer.DeclaringType, context, col);
 }
        void AddContentsFromClassAndMembers(ExpressionContext context, FSharpTextEditorCompletion.CompletionDataCollector col)
        {
            IMethod method = callingMember as IMethod;
            if (method != null && method.Parameters != null) {
                AddParameterList (col, method.Parameters);
            }
            IProperty property = callingMember as IProperty;
            if (property != null && property.Parameters != null)
                AddParameterList (col, property.Parameters);
            if (CallingType == null)
                return;
            AddContentsFromOuterClass (CallingType.DeclaringType, context, col);
            IType callingType = CallingType is InstantiatedType ? ((InstantiatedType)CallingType).UninstantiatedType : CallingType;
            //bool isInStatic = CallingMember != null ? CallingMember.IsStatic : false;

            if (CallingMember == null || !CallingMember.IsStatic) {
                foreach (TypeParameter parameter in callingType.TypeParameters) {
                    col.Add (parameter.Name, "md-literal");
                }
            }

            if (context != ExpressionContext.TypeDeclaration && CallingMember != null) {
                bool includeProtected = DomType.IncludeProtected (dom, CallingType, CallingMember.DeclaringType);
                foreach (IType type in dom.GetInheritanceTree (CallingType)) {
                    foreach (IMember member in type.Members) {
                        if (!(member is IType) && CallingMember.IsStatic && !(member.IsStatic || member.IsConst))
                            continue;
                        if (member.IsAccessibleFrom (dom, CallingType, CallingMember, includeProtected)) {
                            if (context.FilterEntry (member))
                                continue;
                            col.Add (member);
                        }
                    }
                }
            }
        }
        public FSharpTextEditorCompletion.CompletionDataCollector AddAccessibleCodeCompletionData(ExpressionContext context, FSharpTextEditorCompletion.CompletionDataCollector col)
        {
            if (context != ExpressionContext.Global && context != ExpressionContext.TypeName) {
                AddContentsFromClassAndMembers (context, col);

                if (lookupTableVisitor != null && lookupTableVisitor.Variables != null) {
                    int callingMemberline = CallingMember != null ? CallingMember.Location.Line : 0;
                    // local variables could be outside members (LINQ initializers)
                    foreach (KeyValuePair<string, List<LocalLookupVariable>> pair in lookupTableVisitor.Variables) {
                        if (pair.Value != null && pair.Value.Count > 0) {
                            foreach (LocalLookupVariable v in pair.Value) {
                                if (new DomLocation (callingMemberline + v.StartPos.Line - 2, v.StartPos.Column) <= this.resolvePosition && (v.EndPos.IsEmpty || new DomLocation (callingMemberline + v.EndPos.Line - 2, v.EndPos.Column) >= this.resolvePosition)) {
                                    col.Add (new LocalVariable (CallingMember, pair.Key, ConvertTypeReference (v.TypeRef), DomRegion.Empty));
                                }
                            }
                        }
                    }
                }

                if (CallingMember is IProperty) {
                    IProperty property = (IProperty)callingMember;
                    if (property.HasSet && editor != null && property.SetRegion.Contains (resolvePosition.Line, editor.CursorColumn))
                        col.Add ("value");
                }

                if (CallingMember is IEvent)
                    col.Add ("value");
            }

            List<string> namespaceList = new List<string> ();
            namespaceList.Add ("");

            List<string> namespaceDeclList = new List<string> ();
            namespaceDeclList.Add ("");
            if (unit != null) {
                foreach (IUsing u in unit.Usings) {
                    foreach (string alias in u.Aliases.Keys) {
                        col.Add (alias);
                    }
                    if (u.Namespaces == null)
                        continue;
                    bool isNamespaceDecl = u.IsFromNamespace && u.Region.Contains (this.resolvePosition);
                    if (u.IsFromNamespace && !isNamespaceDecl)
                        continue;
                    foreach (string ns in u.Namespaces) {
                        namespaceList.Add (ns);
                        if (isNamespaceDecl)
                            namespaceDeclList.Add (ns);
                    }
                }

                foreach (object o in dom.GetNamespaceContents (namespaceList, true, true)) {
                    if (context.FilterEntry (o))
                        continue;
                    if (o is Namespace) {
                        Namespace ns = o as Namespace;
                        bool skip = true;
                        foreach (string str in namespaceDeclList) {
                            if (dom.NamespaceExists (str.Length > 0 ? str + "." + ns.Name : ns.Name)) {
                                skip = false;
                                break;
                            }
                        }
                        if (skip)
                            continue;
                    }

                    //IMember member = o as IMember;
                    //if (member != null && completionList.Find (member.Name) != null)
                    //	continue;
                    if (context == ExpressionContext.Attribute) {
                        IType t = o as IType;
                        if (t != null && !t.IsBaseType (attributeType))
                            continue;
                    }
                    ICompletionData data = col.Add (o);
                    if (data != null && context == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) {
                        string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length);
                        data.SetText (newText);
                    }
                }
                CodeTemplateService.AddCompletionDataForMime ("text/x-csharp", col.CompletionList);
            }
            return col;
        }
		public ExpressionResult (string expression, DomRegion region, ExpressionContext expressionContext = null) : this (expression, region, new [] {expressionContext})
		{
		}
		public ExpressionResult (string expression, ExpressionContext expressionContext) : this (expression, DomRegion.Empty, expressionContext)
		{
		}