AddMember() public method

public AddMember ( IMember member ) : ICompletionData
member IMember
return ICompletionData
		void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func<IType, IType> typePred = null, Predicate<IMember> memberPred = null, Action<ICompletionData, IType> callback = null, bool onlyAddConstructors = false)
		{
			var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);

			if (currentType != null) {
				for (var ct = ctx.CurrentTypeDefinition; ct != null; ct = ct.DeclaringTypeDefinition) {
					foreach (var nestedType in ct.GetNestedTypes ()) {
						if (!lookup.IsAccessible(nestedType.GetDefinition(), true))
							continue;
						if (onlyAddConstructors) {
							if (!nestedType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
								continue;
						}

						if (typePred == null) {
							if (onlyAddConstructors)
								wrapper.AddConstructors(nestedType, false, IsAttributeContext(node));
							else
								wrapper.AddType(nestedType, false, IsAttributeContext(node));
							continue;
						}

						var type = typePred(nestedType);
						if (type != null) {
							var a2 = onlyAddConstructors ? wrapper.AddConstructors(type, false, IsAttributeContext(node)) : wrapper.AddType(type, false, IsAttributeContext(node));
							if (a2 != null && callback != null) {
								callback(a2, type);
							}
						}
						continue;
					}
				}

				if (this.currentMember != null && !(node is AstType)) {
					var def = ctx.CurrentTypeDefinition;
					if (def == null && currentType != null)
						def = Compilation.MainAssembly.GetTypeDefinition(currentType.FullTypeName);
					if (def != null) {
						bool isProtectedAllowed = true;

						foreach (var member in def.GetMembers (m => currentMember.IsStatic ? m.IsStatic : true)) {
							if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
								continue;
							}
							if (member.SymbolKind == SymbolKind.Operator) {
								continue;
							}
							if (member.IsExplicitInterfaceImplementation) {
								continue;
							}
							if (!lookup.IsAccessible(member, isProtectedAllowed)) {
								continue;
							}
							if (memberPred == null || memberPred(member)) {
								wrapper.AddMember(member);
							}
						}
						var declaring = def.DeclaringTypeDefinition;
						while (declaring != null) {
							foreach (var member in declaring.GetMembers (m => m.IsStatic)) {
								if (memberPred == null || memberPred(member)) {
									wrapper.AddMember(member);
								}
							}
							declaring = declaring.DeclaringTypeDefinition;
						}
					}
				}
				if (ctx.CurrentTypeDefinition != null) {
					foreach (var p in ctx.CurrentTypeDefinition.TypeParameters) {
						wrapper.AddTypeParameter(p);
					}
				}
			}
			var scope = ctx.CurrentUsingScope;

			for (var n = scope; n != null; n = n.Parent) {
				foreach (var pair in n.UsingAliases) {
					wrapper.AddAlias(pair.Key);
				}
				foreach (var alias in n.ExternAliases) {
					wrapper.AddAlias(alias);
				}
				foreach (var u in n.Usings) {
					foreach (var type in u.Types) {
						if (!lookup.IsAccessible(type, false))
							continue;

						IType addType = typePred != null ? typePred(type) : type;

						if (onlyAddConstructors && addType != null) {
							if (!addType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
								continue;
						}

						if (addType != null) {
							var a = onlyAddConstructors ? wrapper.AddConstructors(addType, false, IsAttributeContext(node)) : wrapper.AddType(addType, false, IsAttributeContext(node));
							if (a != null && callback != null) {
								callback(a, type);
							}
						}
					}
				}

				foreach (var type in n.Namespace.Types) {
					if (!lookup.IsAccessible(type, false))
						continue;
					IType addType = typePred != null ? typePred(type) : type;

					if (onlyAddConstructors && addType != null) {
						if (!addType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
							continue;
					}

					if (addType != null) {
						var a2 = onlyAddConstructors ? wrapper.AddConstructors(addType, false, IsAttributeContext(node)) : wrapper.AddType(addType, false);
						if (a2 != null && callback != null) {
							callback(a2, type);
						}
					}
				}
			}

			for (var n = scope; n != null; n = n.Parent) {
				foreach (var curNs in n.Namespace.ChildNamespaces) {
					wrapper.AddNamespace(lookup, curNs);
				}
			}

			if (node is AstType && node.Parent is Constraint && IncludeKeywordsInCompletionList) {
				wrapper.AddCustom("new()");
			}

			if (AutomaticallyAddImports) {
				state = GetState();
				ICompletionData[] importData;

				var namespaces = new List<INamespace>();
				for (var n = ctx.CurrentUsingScope; n != null; n = n.Parent) {
					namespaces.Add(n.Namespace);
					foreach (var u in n.Usings)
						namespaces.Add(u);
				}

				if (this.CompletionEngineCache != null && ListEquals(namespaces, CompletionEngineCache.namespaces)) {
					importData = CompletionEngineCache.importCompletion;
				} else {
					// flatten usings
					var importList = new List<ICompletionData>();
					var dict = new Dictionary<string, Dictionary<string, ICompletionData>>();
					foreach (var type in Compilation.GetAllTypeDefinitions ()) {
						if (!lookup.IsAccessible(type, false))
							continue;
						if (namespaces.Any(n => n.FullName == type.Namespace))
							continue;
						bool useFullName = false;
						foreach (var ns in namespaces) {
							if (ns.GetTypeDefinition(type.Name, type.TypeParameterCount) != null) {
								useFullName = true;
								break;
							}
						}

						if (onlyAddConstructors) {
							if (!type.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
								continue;
						}
						var data = factory.CreateImportCompletionData(type, useFullName, onlyAddConstructors);
						Dictionary<string, ICompletionData> createdDict;
						if (!dict.TryGetValue(type.Name, out createdDict)) {
							createdDict = new Dictionary<string, ICompletionData>();
							dict.Add(type.Name, createdDict);
						}
						ICompletionData oldData;
						if (!createdDict.TryGetValue(type.Namespace, out oldData)) {
							importList.Add(data);
							createdDict.Add(type.Namespace, data);
						} else {
							oldData.AddOverload(data); 
						}
					}

					importData = importList.ToArray();
					if (CompletionEngineCache != null) {
						CompletionEngineCache.namespaces = namespaces;
						CompletionEngineCache.importCompletion = importData;
					}
				}
				foreach (var data in importData) {
					wrapper.Result.Add(data);
				}


			}

		}
		IEnumerable<ICompletionData> CreateCompletionData(TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state, Func<IType, IType> typePred = null)
		{
			if (resolveResult == null /*			|| resolveResult.IsError*/) {
				return null;
			}

			var lookup = new MemberLookup(
				ctx.CurrentTypeDefinition,
				Compilation.MainAssembly
			);

			if (resolveResult is NamespaceResolveResult) {
				var nr = (NamespaceResolveResult)resolveResult;
				var namespaceContents = new CompletionDataWrapper(this);

				foreach (var cl in nr.Namespace.Types) {
					if (!lookup.IsAccessible(cl, false))
						continue;
					IType addType = typePred != null ? typePred(cl) : cl;
					if (addType != null)
						namespaceContents.AddType(addType, false);
				}

				foreach (var ns in nr.Namespace.ChildNamespaces) {
					namespaceContents.AddNamespace(lookup, ns);
				}
				return namespaceContents.Result;
			}
			IType type = resolveResult.Type;

			if (type.Namespace == "System" && type.Name == "Void")
				return null;

			if (resolvedNode.Parent is PointerReferenceExpression && (type is PointerType)) {
				resolveResult = new OperatorResolveResult(((PointerType)type).ElementType, System.Linq.Expressions.ExpressionType.Extension, resolveResult);
			}

			//var typeDef = resolveResult.Type.GetDefinition();
			var result = new CompletionDataWrapper(this);
			bool includeStaticMembers = false;

			if (resolveResult is LocalResolveResult) {
				if (resolvedNode is IdentifierExpression) {
					var mrr = (LocalResolveResult)resolveResult;
					includeStaticMembers = mrr.Variable.Name == mrr.Type.Name;
				}
			}
			if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) {
				foreach (var field in type.GetFields ()) {
					if (!lookup.IsAccessible(field, false))
						continue;
					result.AddMember(field);
				}
				return result.Result;
			}

			bool isProtectedAllowed = resolveResult is ThisResolveResult ? true : lookup.IsProtectedAccessAllowed(type);
			bool skipNonStaticMembers = (resolveResult is TypeResolveResult);

			if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) {
				var mrr = (MemberResolveResult)resolveResult;
				includeStaticMembers = mrr.Member.Name == mrr.Type.Name;

				TypeResolveResult trr;
				if (state.IsVariableReferenceWithSameType(
					resolveResult,
					((IdentifierExpression)resolvedNode).Identifier,
					out trr
				)) {
					if (currentMember != null && mrr.Member.IsStatic ^ currentMember.IsStatic) {
						skipNonStaticMembers = true;

						if (trr.Type.Kind == TypeKind.Enum) {
							foreach (var field in trr.Type.GetFields ()) {
								if (lookup.IsAccessible(field, false))
									result.AddMember(field);
							}
							return result.Result;
						}
					}
				}
				// ADD Aliases
				var scope = ctx.CurrentUsingScope;

				for (var n = scope; n != null; n = n.Parent) {
					foreach (var pair in n.UsingAliases) {
						if (pair.Key == mrr.Member.Name) {
							foreach (var r in CreateCompletionData (location, pair.Value, resolvedNode, state)) {
								if (r is IEntityCompletionData && ((IEntityCompletionData)r).Entity is IMember) {
									result.AddMember((IMember)((IEntityCompletionData)r).Entity);
								} else {
									result.Add(r);
								}
							}
						}
					}
				}				


			}
			if (resolveResult is TypeResolveResult && (resolvedNode is IdentifierExpression || resolvedNode is MemberReferenceExpression)) {
				includeStaticMembers = true;
			}

			//			Console.WriteLine ("type:" + type +"/"+type.GetType ());
			//			Console.WriteLine ("current:" + ctx.CurrentTypeDefinition);
			//			Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed + " static: "+ includeStaticMembers);
			//			Console.WriteLine (resolveResult);
			//			Console.WriteLine ("node:" + resolvedNode);
			//			Console.WriteLine (currentMember !=  null ? currentMember.IsStatic : "currentMember == null");

			if (resolvedNode.Annotation<ObjectCreateExpression>() == null) {
				//tags the created expression as part of an object create expression.
				/*				
				var filteredList = new List<IMember>();
				foreach (var member in type.GetMembers ()) {
					filteredList.Add(member);
				}
				
				foreach (var member in filteredList) {
					//					Console.WriteLine ("add:" + member + "/" + member.IsStatic);
					result.AddMember(member);
				}*/
				foreach (var member in lookup.GetAccessibleMembers (resolveResult)) {
					if (member.SymbolKind == SymbolKind.Indexer || member.SymbolKind == SymbolKind.Operator || member.SymbolKind == SymbolKind.Constructor || member.SymbolKind == SymbolKind.Destructor) {
						continue;
					}
					if (resolvedNode is BaseReferenceExpression && member.IsAbstract) {
						continue;
					}
					if (member is IType) {
						if (resolveResult is TypeResolveResult || includeStaticMembers) {
							if (!lookup.IsAccessible(member, isProtectedAllowed))
								continue;
							result.AddType((IType)member, false);
							continue;
						}
					}
					bool memberIsStatic = member.IsStatic;
					if (!includeStaticMembers && memberIsStatic && !(resolveResult is TypeResolveResult)) {
						//						Console.WriteLine ("skip static member: " + member.FullName);
						continue;
					}

					var field = member as IField;
					if (field != null) {
						memberIsStatic |= field.IsConst;
					}
					if (!memberIsStatic && skipNonStaticMembers) {
						continue;
					}

					if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
						continue;
					}
					if (member.SymbolKind == SymbolKind.Operator) {
						continue;
					}

					if (member is IMember) {
						result.AddMember((IMember)member);
					}
				}
			}

			if (!(resolveResult is TypeResolveResult || includeStaticMembers)) {
				foreach (var meths in state.GetExtensionMethods (type)) {
					foreach (var m in meths) {
						if (!lookup.IsAccessible(m, isProtectedAllowed))
							continue;
						result.AddMember(new ReducedExtensionMethod(m));
					}
				}
			}

			//			IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null);
			//			CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location);
			//			col.HideExtensionParameter = !resolveResult.StaticResolve;
			//			col.NamePrefix = expressionResult.Expression;
			//			bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints);
			//			if (objects != null) {
			//				foreach (object obj in objects) {
			//					if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj))
			//						continue;
			//					if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace))
			//						continue;
			//					if (showOnlyTypes && !(obj is IType))
			//						continue;
			//					CompletionData data = col.Add (obj);
			//					if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) {
			//						string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length);
			//						data.SetText (newText);
			//					}
			//				}
			//			}

			return result.Result;
		}
		IEnumerable<ICompletionData> HandleObjectInitializer(CompilationUnit unit, AstNode n)
		{
			var p = n.Parent;
			while (p != null && !(p is ObjectCreateExpression)) {
				p = p.Parent;
			}
			var parent = (ArrayInitializerExpression)n.Parent;
			if (parent.IsSingleElement)
				parent = (ArrayInitializerExpression)parent.Parent;
			if (p != null) {
				var contextList = new CompletionDataWrapper(this);
				var initializerResult = ResolveExpression(p, unit);
				if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) {
					// check 3 cases:
					// 1) New initalizer { xpr
					// 2) Object initializer { prop = val1, field = val2, xpr
					// 3) Array initializer { new Foo (), a, xpr
					// in case 1 all object/array initializer options should be given - in the others not.

					AstNode prev = null;
					if (parent.Elements.Count > 1) {
						prev = parent.Elements.First();
						if (prev is ArrayInitializerExpression && ((ArrayInitializerExpression)prev).IsSingleElement) 
							prev = ((ArrayInitializerExpression)prev).Elements.FirstOrDefault();
					}

					if (prev != null && !(prev is NamedExpression)) {
						AddContextCompletion(contextList, GetState(), n, unit);
						// case 3)
						return contextList.Result;
					}

					foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) {
						contextList.AddMember(m);
					}

					if (prev != null && (prev is NamedExpression)) {
						// case 2)
						return contextList.Result;
					}

					// case 1)

					// check if the object is a list, if not only provide object initalizers
					var list = typeof(System.Collections.IList).ToTypeReference().Resolve(Compilation);
					if (initializerResult.Item1.Type.Kind != TypeKind.Array && list != null) {
						var def = initializerResult.Item1.Type.GetDefinition(); 
						if (def != null && !def.IsDerivedFrom(list.GetDefinition()))
							return contextList.Result;
					}

					AddContextCompletion(contextList, GetState(), n, unit);
					return contextList.Result;
				}
			}
			return null;
		}
		static void AddAttributeProperties(CompletionDataWrapper wrapper, ResolveResult resolved)
		{
			if (resolved == null || resolved.Type.Kind == TypeKind.Unknown)
				return;

			foreach (var property in resolved.Type.GetProperties (p => p.Accessibility == Accessibility.Public)) {
				var data = wrapper.AddMember(property);
				if (data != null)
					data.DisplayFlags |= DisplayFlags.NamedArgument;
			}
			foreach (var field in resolved.Type.GetFields (p => p.Accessibility == Accessibility.Public)) {
				var data = wrapper.AddMember(field);
				if (data != null)
					data.DisplayFlags |= DisplayFlags.NamedArgument;
			}
			foreach (var constructor in resolved.Type.GetConstructors (p => p.Accessibility == Accessibility.Public)) {
				foreach (var p in constructor.Parameters) {
					wrapper.AddNamedParameterVariable(p);
				}
			}
		}
		IEnumerable<ICompletionData> HandleObjectInitializer(CompilationUnit unit, AstNode n)
		{
			var p = n.Parent;
			while (p != null && !(p is ObjectCreateExpression)) {
				p = p.Parent;
			}
			var parent = (ArrayInitializerExpression)n.Parent;
			if (parent.IsSingleElement)
				parent = (ArrayInitializerExpression)parent.Parent;
			if (p != null) {
				var contextList = new CompletionDataWrapper(this);
				var initializerResult = ResolveExpression(p, unit);
				if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) {
					// check 3 cases:
					// New initalizer { xpr
					// Object initializer { prop = val1, field = val2, xpr
					// Array initializer { new Foo (), a, xpr
					// in case 1 all object/array initializer options should be given - in the others not.

					AstNode prev = null;
					if (parent.Elements.Count > 1) {
						prev = parent.Elements.First();
						if (prev is ArrayInitializerExpression && ((ArrayInitializerExpression)prev).IsSingleElement) 
							prev = ((ArrayInitializerExpression)prev).Elements.FirstOrDefault();
					}

					if (prev != null && !(prev is NamedExpression)) {
						AddContextCompletion(contextList, GetState(), n, unit);
						return contextList.Result;
					}

					foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) {
						contextList.AddMember(m);
					}

					if (prev != null && (prev is NamedExpression))
						return contextList.Result;

					AddContextCompletion(contextList, GetState(), n, unit);
					return contextList.Result;

				}
			}
			return null;
		}
		void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func<IType, IType> typePred = null, Predicate<IMember> memberPred = null, Action<ICompletionData, IType> callback = null)
		{
			var lookup = new MemberLookup(
				ctx.CurrentTypeDefinition,
				Compilation.MainAssembly
			);
			if (currentType != null) {
				for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) {
					foreach (var nestedType in ct.NestedTypes) {
						string name = nestedType.Name;
						if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) {
							name = name.Substring(0, name.Length - "Attribute".Length);
						}

						if (typePred == null) {
							wrapper.AddType(nestedType, name);
							continue;
						}

						var type = typePred(nestedType.Resolve(ctx));
						if (type != null) {
							var a2 = wrapper.AddType(type, name);
							if (a2 != null && callback != null) {
								callback(a2, type);
							}
						}
						continue;
					}
				}
				if (this.currentMember != null && !(node is AstType)) {
					var def = ctx.CurrentTypeDefinition ?? Compilation.MainAssembly.GetTypeDefinition(currentType);
					if (def != null) {
						bool isProtectedAllowed = true;
						foreach (var member in def.GetMembers ()) {
							if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
								continue;
							}
							if (member.EntityType == EntityType.Operator) {
								continue;
							}
							if (member.IsExplicitInterfaceImplementation) {
								continue;
							}
							if (!lookup.IsAccessible(member, isProtectedAllowed)) {
								continue;
							}

							if (memberPred == null || memberPred(member)) {
								wrapper.AddMember(member);
							}
						}
						var declaring = def.DeclaringTypeDefinition;
						while (declaring != null) {
							foreach (var member in declaring.GetMembers (m => m.IsStatic)) {
								if (memberPred == null || memberPred(member)) {
									wrapper.AddMember(member);
								}
							}
							declaring = declaring.DeclaringTypeDefinition;
						}
					}
				}
				foreach (var p in currentType.TypeParameters) {
					wrapper.AddTypeParameter(p);
				}
			}
			var scope = CSharpParsedFile.GetUsingScope(location).Resolve(Compilation);
			
			for (var n = scope; n != null; n = n.Parent) {
				foreach (var pair in n.UsingAliases) {
					wrapper.AddNamespace(pair.Key);
				}
				foreach (var u in n.Usings) {
					foreach (var type in u.Types) {
						if (!lookup.IsAccessible(type, false))
							continue;

						IType addType = typePred != null ? typePred(type) : type;
						if (addType != null) {
							string name = type.Name;
							if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) {
								name = name.Substring(0, name.Length - "Attribute".Length);
							}
							var a = wrapper.AddType(addType, name);
							if (a != null && callback != null) {
								callback(a, type);
							}
						}
					}
				}
				
				foreach (var type in n.Namespace.Types) {
					if (!lookup.IsAccessible(type, false))
						continue;
					IType addType = typePred != null ? typePred(type) : type;
					if (addType != null) {
						var a2 = wrapper.AddType(addType, addType.Name);
						if (a2 != null && callback != null) {
							callback(a2, type);
						}
					}
				}
				
				foreach (var curNs in n.Namespace.ChildNamespaces) {
					wrapper.AddNamespace(curNs.Name);
				}
			}
		}
        IEnumerable<ICompletionData> HandleObjectInitializer(SyntaxTree unit, AstNode n)
        {
            var p = n.Parent;
            while (p != null && !(p is ObjectCreateExpression)) {
                p = p.Parent;
            }
            var parent = n.Parent as ArrayInitializerExpression;
            if (parent == null)
                return null;
            if (parent.IsSingleElement)
                parent = (ArrayInitializerExpression)parent.Parent;
            if (p != null) {
                var contextList = new CompletionDataWrapper(this);
                var initializerResult = ResolveExpression(p);
                if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) {
                    // check 3 cases:
                    // 1) New initalizer { xpr
                    // 2) Object initializer { prop = val1, field = val2, xpr
                    // 3) Array initializer { new Foo (), a, xpr
                    // in case 1 all object/array initializer options should be given - in the others not.

                    AstNode prev = null;
                    if (parent.Elements.Count > 1) {
                        prev = parent.Elements.First();
                        if (prev is ArrayInitializerExpression && ((ArrayInitializerExpression)prev).IsSingleElement)
                            prev = ((ArrayInitializerExpression)prev).Elements.FirstOrDefault();
                    }

                    if (prev != null && !(prev is NamedExpression)) {
                        AddContextCompletion(contextList, GetState(), n);
                        // case 3)
                        return contextList.Result;
                    }

                    var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
                    bool isProtectedAllowed = ctx.CurrentTypeDefinition != null ?
                        ctx.CurrentTypeDefinition.IsDerivedFrom(initializerResult.Item1.Type.GetDefinition()) :
                            false;

                    foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.EntityType == EntityType.Field)) {
                        if (lookup.IsAccessible (m, isProtectedAllowed))
                            contextList.AddMember(m);
                    }
                    foreach (IProperty m in initializerResult.Item1.Type.GetMembers (m => m.EntityType == EntityType.Property)) {
                        if (m.CanSet && lookup.IsAccessible (m.Setter, isProtectedAllowed))
                            contextList.AddMember(m);
                    }

                    if (prev != null && (prev is NamedExpression)) {
                        // case 2)
                        return contextList.Result;
                    }

                    // case 1)

                    // check if the object is a list, if not only provide object initalizers
                    var list = typeof(System.Collections.IList).ToTypeReference().Resolve(Compilation);
                    if (initializerResult.Item1.Type.Kind != TypeKind.Array && list != null) {
                        var def = initializerResult.Item1.Type.GetDefinition();
                        if (def != null && !def.IsDerivedFrom(list.GetDefinition()))
                            return contextList.Result;
                    }

                    AddContextCompletion(contextList, GetState(), n);
                    return contextList.Result;
                }
            }
            return null;
        }
		IEnumerable<ICompletionData> HandleObjectInitializer(CompilationUnit unit, AstNode n)
		{
			var p = n.Parent;
			while (p != null && !(p is ObjectCreateExpression)) {
				p = p.Parent;
			}
			if (p != null) {
				var contextList = new CompletionDataWrapper(this);
				var initializerResult = ResolveExpression(p, unit);
				if (initializerResult != null && initializerResult.Item1.Type.Kind != TypeKind.Unknown) {

					foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) {
						contextList.AddMember(m);
					}
					var enumerableType = typeof(IEnumerable<>).ToTypeReference().Resolve(ctx);
					// check if we may be in a collection initializer, or enumerable initializer
					if (enumerableType.Kind == TypeKind.Unknown || !initializerResult.Item1.Type.GetDefinition().IsDerivedFrom(enumerableType.GetDefinition())) {
						return contextList.Result;
					}
				}
			}
			return null;
		}
Beispiel #9
0
        IEnumerable<ICompletionData> CreateCompletionData(TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state)
        {
            if (resolveResult == null /*|| resolveResult.IsError*/)
                return null;

            if (resolveResult is NamespaceResolveResult) {
                var nr = (NamespaceResolveResult)resolveResult;
                var namespaceContents = new CompletionDataWrapper (this);

                foreach (var cl in nr.Namespace.Types) {
                    namespaceContents.AddType (cl, cl.Name);
                }

                foreach (var ns in nr.Namespace.ChildNamespaces) {
                    namespaceContents.AddNamespace (ns.Name);
                }
                return namespaceContents.Result;
            }

            IType type = resolveResult.Type;
            var typeDef = resolveResult.Type.GetDefinition ();
            var lookup = new MemberLookup (ctx.CurrentTypeDefinition, Compilation.MainAssembly);
            var result = new CompletionDataWrapper (this);
            bool isProtectedAllowed = false;
            bool includeStaticMembers = false;

            if (resolveResult is LocalResolveResult) {
                isProtectedAllowed = currentType != null && typeDef != null ? typeDef.GetAllBaseTypeDefinitions ().Any (bt => bt.Equals (currentType)) : false;
                if (resolvedNode is IdentifierExpression) {
                    var mrr = (LocalResolveResult)resolveResult;
                    includeStaticMembers = mrr.Variable.Name == mrr.Type.Name;
                }
            } else {
                isProtectedAllowed = currentType != null && typeDef != null ? currentType.Resolve (ctx).GetDefinition ().GetAllBaseTypeDefinitions ().Any (bt => bt.Equals (typeDef)) : false;
            }
            if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) {
                foreach (var field in type.GetFields ()) {
                    result.AddMember (field);
                }
                foreach (var m in type.GetMethods ()) {
                    if (m.Name == "TryParse")
                        result.AddMember (m);
                }
                return result.Result;
            }

            if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) {
                var mrr = (MemberResolveResult)resolveResult;
                includeStaticMembers = mrr.Member.Name == mrr.Type.Name;
            }

            //			Console.WriteLine ("type:" + type +"/"+type.GetType ());
            //			Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed);
            //			Console.WriteLine (resolveResult);
            //			Console.WriteLine (currentMember !=  null ? currentMember.IsStatic : "currentMember == null");

            if (resolvedNode.Annotation<ObjectCreateExpression> () == null) { //tags the created expression as part of an object create expression.
                foreach (var member in type.GetMembers ()) {
                    if (!lookup.IsAccessible (member, isProtectedAllowed)) {
                        //					Console.WriteLine ("skip access: " + member.FullName);
                        continue;
                    }
                    if (resolvedNode is BaseReferenceExpression && member.IsAbstract)
                        continue;

                    if (!includeStaticMembers && member.IsStatic && !(resolveResult is TypeResolveResult)) {
                        //					Console.WriteLine ("skip static member: " + member.FullName);
                        continue;
                    }
                    if (!member.IsStatic && (resolveResult is TypeResolveResult)) {
                        //					Console.WriteLine ("skip non static member: " + member.FullName);
                        continue;
                    }
                    //				Console.WriteLine ("add : "+ member.FullName + " --- " + member.IsStatic);
                    result.AddMember (member);
                }
            }

            if (resolveResult is TypeResolveResult || includeStaticMembers) {
                foreach (var nested in type.GetNestedTypes ()) {
                    result.AddType (nested, nested.Name);
                }

            } else {
                foreach (var meths in state.GetAllExtensionMethods (type)) {
                    foreach (var m in meths) {
                        result.AddMember (m);
                    }
                }
            }

            //			IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null);
            //			CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location);
            //			col.HideExtensionParameter = !resolveResult.StaticResolve;
            //			col.NamePrefix = expressionResult.Expression;
            //			bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints);
            //			if (objects != null) {
            //				foreach (object obj in objects) {
            //					if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj))
            //						continue;
            //					if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace))
            //						continue;
            //					if (showOnlyTypes && !(obj is IType))
            //						continue;
            //					CompletionData data = col.Add (obj);
            //					if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) {
            //						string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length);
            //						data.SetText (newText);
            //					}
            //				}
            //			}

            return result.Result;
        }
        void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func<IType, IType> typePred = null, Predicate<IMember> memberPred = null, Action<ICompletionData, IType> callback = null, bool onlyAddConstructors = false)
        {
            var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);

            if (currentType != null) {
                for (var ct = ctx.CurrentTypeDefinition; ct != null; ct = ct.DeclaringTypeDefinition) {
                    foreach (var nestedType in ct.GetNestedTypes ()) {
                        if (!lookup.IsAccessible (nestedType.GetDefinition (), true))
                            continue;
                        if (onlyAddConstructors) {
                            if (!nestedType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
                                continue;
                        }

                        if (typePred == null) {
                            if (onlyAddConstructors)
                                wrapper.AddConstructors (nestedType, false, IsAttributeContext(node));
                            else
                                wrapper.AddType(nestedType, false, IsAttributeContext(node));
                            continue;
                        }

                        var type = typePred(nestedType);
                        if (type != null) {
                            var a2 = onlyAddConstructors ? wrapper.AddConstructors(type, false, IsAttributeContext(node)) : wrapper.AddType(type, false, IsAttributeContext(node));
                            if (a2 != null && callback != null) {
                                callback(a2, type);
                            }
                        }
                        continue;
                    }
                }

                if (this.currentMember != null && !(node is AstType)) {
                    var def = ctx.CurrentTypeDefinition;
                    if (def == null && currentType != null)
                        def = Compilation.MainAssembly.GetTypeDefinition(currentType.FullTypeName);
                    if (def != null) {
                        bool isProtectedAllowed = true;

                        foreach (var member in def.GetMembers (m => currentMember.IsStatic ? m.IsStatic : true)) {
                            if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
                                continue;
                            }
                            if (member.SymbolKind == SymbolKind.Operator) {
                                continue;
                            }
                            if (member.IsExplicitInterfaceImplementation) {
                                continue;
                            }
                            if (!lookup.IsAccessible(member, isProtectedAllowed)) {
                                continue;
                            }
                            if (memberPred == null || memberPred(member)) {
                                wrapper.AddMember(member);
                            }
                        }
                        var declaring = def.DeclaringTypeDefinition;
                        while (declaring != null) {
                            foreach (var member in declaring.GetMembers (m => m.IsStatic)) {
                                if (memberPred == null || memberPred(member)) {
                                    wrapper.AddMember(member);
                                }
                            }
                            declaring = declaring.DeclaringTypeDefinition;
                        }
                    }
                }
                if (ctx.CurrentTypeDefinition != null) {
                    foreach (var p in ctx.CurrentTypeDefinition.TypeParameters) {
                        wrapper.AddTypeParameter(p);
                    }
                }
            }
            var scope = ctx.CurrentUsingScope;

            for (var n = scope; n != null; n = n.Parent) {
                foreach (var pair in n.UsingAliases) {
                    wrapper.AddAlias(pair.Key);
                }
                foreach (var alias in n.ExternAliases) {
                    wrapper.AddAlias(alias);
                }
                foreach (var u in n.Usings) {
                    foreach (var type in u.Types) {
                        if (!lookup.IsAccessible(type, false))
                            continue;

                        IType addType = typePred != null ? typePred(type) : type;

                        if (onlyAddConstructors && addType != null) {
                            if (!addType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
                                continue;
                        }

                        if (addType != null) {
                            var a = onlyAddConstructors ? wrapper.AddConstructors(addType, false, IsAttributeContext(node)) : wrapper.AddType(addType, false, IsAttributeContext(node));
                            if (a != null && callback != null) {
                                callback(a, type);
                            }
                        }
                    }
                }

                foreach (var type in n.Namespace.Types) {
                    if (!lookup.IsAccessible(type, false))
                        continue;
                    IType addType = typePred != null ? typePred(type) : type;

                    if (onlyAddConstructors && addType != null) {
                        if (!addType.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
                            continue;
                    }

                    if (addType != null) {
                        var a2 = onlyAddConstructors ? wrapper.AddConstructors(addType, false, IsAttributeContext(node)) : wrapper.AddType(addType, false);
                        if (a2 != null && callback != null) {
                            callback(a2, type);
                        }
                    }
                }

                foreach (var curNs in n.Namespace.ChildNamespaces) {
                    wrapper.AddNamespace(lookup, curNs);
                }
            }

            if (node is AstType && node.Parent is Constraint && IncludeKeywordsInCompletionList) {
                wrapper.AddCustom ("new()");
            }

            if (AutomaticallyAddImports) {
                state = GetState();
                foreach (var type in Compilation.GetAllTypeDefinitions ()) {
                    if (!lookup.IsAccessible (type, false))
                        continue;
                    var resolveResult = state.LookupSimpleNameOrTypeName(type.Name, type.TypeArguments, NameLookupMode.Expression);
                    if (resolveResult.Type.GetDefinition () == type)
                        continue;

                    if (onlyAddConstructors) {
                        if (!type.GetConstructors().Any(c => lookup.IsAccessible(c, true)))
                            continue;
                    }

                    wrapper.AddTypeImport(type, !resolveResult.IsError, onlyAddConstructors);
                }
            }
        }
Beispiel #11
0
        void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Predicate<IType> typePred = null, Predicate<IMember> memberPred = null)
        {
            var currentMember = ctx.CurrentMember;
            if (currentType != null) {
                for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) {
                    foreach (var nestedType in ct.NestedTypes) {
                        if (typePred == null || typePred (nestedType.Resolve (ctx))) {
                            string name = nestedType.Name;
                            if (node is Attribute && name.EndsWith ("Attribute") && name.Length > "Attribute".Length)
                                name = name.Substring (0, name.Length - "Attribute".Length);
                            wrapper.AddType (nestedType, name);
                        }
                    }
                }
                if (this.currentMember != null) {
                    var def = ctx.CurrentTypeDefinition ?? Compilation.MainAssembly.GetTypeDefinition (currentType);
                    foreach (var member in def.GetMembers ()) {
                        if (memberPred == null || memberPred (member))
                            wrapper.AddMember (member);
                    }
                    var declaring = def.DeclaringTypeDefinition;
                    while (declaring != null) {
                        foreach (var member in declaring.GetMembers (m => m.IsStatic)) {
                            if (memberPred == null || memberPred (member))
                                wrapper.AddMember (member);
                        }
                        declaring = declaring.DeclaringTypeDefinition;
                    }
                }
                foreach (var p in currentType.TypeParameters) {
                    wrapper.AddTypeParameter (p);
                }
            }

            for (var n = state.CurrentUsingScope; n != null; n = n.Parent) {
                foreach (var pair in n.UsingAliases) {
                    wrapper.AddNamespace (pair.Key);
                }
                foreach (var u in n.Usings) {
                    foreach (var type in u.Types) {
                        if (typePred == null || typePred (type)) {
                            string name = type.Name;
                            if (node is Attribute && name.EndsWith ("Attribute") && name.Length > "Attribute".Length)
                                name = name.Substring (0, name.Length - "Attribute".Length);
                            wrapper.AddType (type, name);
                        }
                    }
                }

                foreach (var type in n.Namespace.Types) {
                    if (typePred == null || typePred (type))
                        wrapper.AddType (type, type.Name);
                }

                foreach (var curNs in n.Namespace.ChildNamespaces) {
                    wrapper.AddNamespace (curNs.Name);
                }
            }
        }
Beispiel #12
0
        IEnumerable<ICompletionData> MagicKeyCompletion(char completionChar, bool controlSpace)
        {
            switch (completionChar) {
            // Magic key completion
            case ':':
            case '.':
                if (IsInsideCommentOrString ())
                    return Enumerable.Empty<ICompletionData> ();
                var expr = GetExpressionBeforeCursor ();
                if (expr == null)
                    return null;
                // do not complete <number>. (but <number>.<number>.)
                if (expr.Item2 is PrimitiveExpression) {
                    var pexpr = (PrimitiveExpression)expr.Item2;
                    if (!(pexpr.Value is string || pexpr.Value is char) && !pexpr.LiteralValue.Contains ('.'))
                        return null;
                }

                var resolveResult = ResolveExpression (expr.Item1, expr.Item2, expr.Item3);

                if (resolveResult == null)
                    return null;
                if (expr.Item2 is AstType)
                    return CreateTypeAndNamespaceCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
                return CreateCompletionData (location, resolveResult.Item1, expr.Item2, resolveResult.Item2);
            case '#':
                if (IsInsideCommentOrString ())
                    return null;
                return GetDirectiveCompletionData ();

            // XML doc completion
            case '<':
                if (IsInsideDocComment ())
                    return GetXmlDocumentationCompletionData ();
                if (controlSpace)
                    return DefaultControlSpaceItems ();
                return null;
            case '>':
                if (!IsInsideDocComment ())
                    return null;
                string lineText = document.GetText (document.GetLineByNumber (location.Line));
                int startIndex = Math.Min (location.Column - 1, lineText.Length - 1);

                while (startIndex >= 0 && lineText [startIndex] != '<') {
                    --startIndex;
                    if (lineText [startIndex] == '/') { // already closed.
                        startIndex = -1;
                        break;
                    }
                }

                if (startIndex >= 0) {
                    int endIndex = startIndex;
                    while (endIndex <= location.Column && endIndex < lineText.Length && !Char.IsWhiteSpace (lineText [endIndex])) {
                        endIndex++;
                    }
                    string tag = endIndex - startIndex - 1 > 0 ? lineText.Substring (startIndex + 1, endIndex - startIndex - 2) : null;
                    if (!string.IsNullOrEmpty (tag) && commentTags.IndexOf (tag) >= 0)
                        document.Insert (offset, "</" + tag + ">");
                }
                return null;

            // Parameter completion
            case '(':
                if (IsInsideCommentOrString ())
                    return null;
                var invoke = GetInvocationBeforeCursor (true);
                if (invoke == null)
                    return null;
                if (invoke.Item2 is TypeOfExpression)
                    return CreateTypeList ();
                var invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
                if (invocationResult == null)
                    return null;
                var methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
                if (methodGroup != null)
                    return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, 0, controlSpace);

                if (controlSpace)
                    return DefaultControlSpaceItems (invoke);

                return null;
            case '=':
                return controlSpace ? DefaultControlSpaceItems () : null;
            case ',':
                int cpos2;
                if (!GetParameterCompletionCommandOffset (out cpos2))
                    return null;
            //	completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2);
            //	int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1;
            //				return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter);
                break;

            // Completion on space:
            case ' ':
                if (IsInsideCommentOrString ())
                    return null;

                int tokenIndex = offset;
                string token = GetPreviousToken (ref tokenIndex, false);
                // check propose name, for context <variable name> <ctrl+space> (but only in control space context)
                //IType isAsType = null;
                var isAsExpression = GetExpressionAt (offset);
                if (controlSpace && isAsExpression != null && isAsExpression.Item2 is VariableDeclarationStatement && token != "new") {
                    var parent = isAsExpression.Item2 as VariableDeclarationStatement;
                    var proposeNameList = new CompletionDataWrapper (this);

                    foreach (var possibleName in GenerateNameProposals (parent.Type)) {
                        if (possibleName.Length > 0)
                            proposeNameList.Result.Add (factory.CreateLiteralCompletionData (possibleName.ToString ()));
                    }

                    AutoSelect = false;
                    AutoCompleteEmptyMatch = false;
                    return proposeNameList.Result;
                }
            //				int tokenIndex = offset;
            //				string token = GetPreviousToken (ref tokenIndex, false);
            //				if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
            //					resolver = CreateResolver ();
            //					ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType);
            //					IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType;
            //					if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ","))
            //						return CreateCtrlSpaceCompletionData (completionContext, result);
            //				}
                if (token == "=") {
                    int j = tokenIndex;
                    string prevToken = GetPreviousToken (ref j, false);
                    if (prevToken == "=" || prevToken == "+" || prevToken == "-") {
                        token = prevToken + token;
                        tokenIndex = j;
                    }
                }
                switch (token) {
                case "(":
                case ",":
                    int cpos;
                    if (!GetParameterCompletionCommandOffset (out cpos))
                        break;
                    int currentParameter = GetCurrentParameterIndex (cpos, 0) - 1;
                    if (currentParameter < 0)
                        return null;
                    invoke = GetInvocationBeforeCursor (token == "(");
                    if (invoke == null)
                        return null;
                    invocationResult = ResolveExpression (invoke.Item1, invoke.Item2, invoke.Item3);
                    if (invocationResult == null)
                        return null;
                    methodGroup = invocationResult.Item1 as MethodGroupResolveResult;
                    if (methodGroup != null)
                        return CreateParameterCompletion (methodGroup, invocationResult.Item2, invoke.Item2, currentParameter, controlSpace);
                    return null;
                case "=":
                case "==":
                    GetPreviousToken (ref tokenIndex, false);

                    var expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
                    if (expressionOrVariableDeclaration == null)
                        return null;

                    resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
                    if (resolveResult == null)
                        return null;
                    if (resolveResult.Item1.Type.Kind == TypeKind.Enum) {
                        var wrapper = new CompletionDataWrapper (this);
                        AddContextCompletion (wrapper, resolveResult.Item2, expressionOrVariableDeclaration.Item2);
                        AddEnumMembers (wrapper, resolveResult.Item1.Type, resolveResult.Item2);
                        AutoCompleteEmptyMatch = false;
                        return wrapper.Result;
                    }
            //
            //					if (resolvedType.FullName == DomReturnType.Bool.FullName) {
            //						CompletionDataList completionList = new ProjectDomCompletionDataList ();
            //						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
            //						completionList.AutoCompleteEmptyMatch = false;
            //						cdc.Add ("true", "md-keyword");
            //						cdc.Add ("false", "md-keyword");
            //						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
            //						return completionList;
            //					}
            //					if (resolvedType.ClassType == ClassType.Delegate && token == "=") {
            //						CompletionDataList completionList = new ProjectDomCompletionDataList ();
            //						string parameterDefinition = AddDelegateHandlers (completionList, resolvedType);
            //						string varName = GetPreviousMemberReferenceExpression (tokenIndex);
            //						completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType));
            //
            //						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
            //						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
            //						foreach (var data in completionList) {
            //							if (data is MemberCompletionData)
            //								((MemberCompletionData)data).IsDelegateExpected = true;
            //						}
            //						return completionList;
            //					}
                    return null;
                case "+=":
                case "-=":
                    GetPreviousToken (ref tokenIndex, false);

                    expressionOrVariableDeclaration = GetExpressionAt (tokenIndex);
                    if (expressionOrVariableDeclaration == null)
                        return null;

                    resolveResult = ResolveExpression (expressionOrVariableDeclaration.Item1, expressionOrVariableDeclaration.Item2, expressionOrVariableDeclaration.Item3);
                    if (resolveResult == null)
                        return null;

                    var mrr = resolveResult.Item1 as MemberResolveResult;
                    if (mrr != null) {
                        var evt = mrr.Member as IEvent;
                        if (evt == null)
                            return null;
                        var delegateType = evt.ReturnType;
                        if (delegateType.Kind != TypeKind.Delegate)
                            return null;

                        var wrapper = new CompletionDataWrapper (this);
                        if (currentType != null) {
            //							bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
                            foreach (var method in currentType.Methods) {
                                if (MatchDelegate (delegateType, method) /*&& method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) {
                                    wrapper.AddMember (method);
            //									data.SetText (data.CompletionText + ";");
                                }
                            }
                        }
                        if (token == "+=") {
                            string parameterDefinition = AddDelegateHandlers (wrapper, delegateType);
                            string varName = GetPreviousMemberReferenceExpression (tokenIndex);
                            wrapper.Result.Add (factory.CreateEventCreationCompletionData (varName, delegateType, evt, parameterDefinition, currentMember, currentType));
                        }

                        return wrapper.Result;
                    }
                    return null;
                case ":":
                    if (currentMember == null) {
                        var wrapper = new CompletionDataWrapper (this);
                        AddTypesAndNamespaces (wrapper, GetState (), null, t => currentType != null ? !currentType.Equals (t) : true);
                        return wrapper.Result;
                    }
                    return null;
                }

                var keywordCompletion = HandleKeywordCompletion (tokenIndex, token);
                if (keywordCompletion == null && controlSpace)
                    goto default;
                return keywordCompletion;
            // Automatic completion
            default:
                if (IsInsideCommentOrString ())
                    return null;
                if (IsInLinqContext (offset)) {
                    tokenIndex = offset;
                    token = GetPreviousToken (ref tokenIndex, false); // token last typed
                    if (linqKeywords.Contains (token)) {
                        if (token == "from") // after from no auto code completion.
                            return null;
                        return DefaultControlSpaceItems ();
                    }
                    var dataList = new CompletionDataWrapper (this);
                    AddKeywords (dataList, linqKeywords);
                    return dataList.Result;
                }

                if (currentType != null && currentType.Kind == TypeKind.Enum)
                    return HandleEnumContext ();

                var contextList = new CompletionDataWrapper (this);
                var identifierStart = GetExpressionAtCursor ();
                if (identifierStart != null && identifierStart.Item2 is TypeParameterDeclaration)
                    return null;

                if (identifierStart != null && identifierStart.Item2 is VariableInitializer && location <= ((VariableInitializer)identifierStart.Item2).NameToken.EndLocation) {
                    return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null;
                }
                if (!(char.IsLetter (completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null || !(identifierStart.Item2 is ArrayInitializerExpression))) {
                    return controlSpace ? HandleAccessorContext () ?? DefaultControlSpaceItems (identifierStart) : null;
                }
                char prevCh = offset > 2 ? document.GetCharAt (offset - 2) : ';';
                char nextCh = offset < document.TextLength ? document.GetCharAt (offset) : ' ';
                const string allowedChars = ";,[](){}+-*/%^?:&|~!<>=";
                if (!Char.IsWhiteSpace (nextCh) && allowedChars.IndexOf (nextCh) < 0)
                    return null;
                if (!(Char.IsWhiteSpace (prevCh) || allowedChars.IndexOf (prevCh) >= 0))
                    return null;
                // Do not pop up completion on identifier identifier (should be handled by keyword completion).
                tokenIndex = offset - 1;
                token = GetPreviousToken (ref tokenIndex, false);
                int prevTokenIndex = tokenIndex;
                var prevToken2 = GetPreviousToken (ref prevTokenIndex, false);
                if (identifierStart == null && !string.IsNullOrEmpty (token) && !(IsInsideComment (tokenIndex) || IsInsideString (tokenIndex)) && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
                    char last = token [token.Length - 1];
                    if (char.IsLetterOrDigit (last) || last == '_' || token == ">") {
                        return HandleKeywordCompletion (tokenIndex, token);
                    }
                }

                if (identifierStart == null)
                    return HandleAccessorContext () ?? DefaultControlSpaceItems ();

                CSharpResolver csResolver;
                AstNode n = identifierStart.Item2;
                // Handle foreach (type name _
                if (n is IdentifierExpression) {
                    var prev = n.GetPrevNode () as ForeachStatement;
                    if (prev != null && prev.InExpression.IsNull) {
                        if (controlSpace) {
                            contextList.AddCustom ("in");
                            return contextList.Result;
                        }
                        return null;
                    }
                }

                if (n is Identifier && n.Parent is ForeachStatement) {
                    if (controlSpace)
                        return DefaultControlSpaceItems ();
                    return null;
                }
                if (n is ArrayInitializerExpression) {
                    // check for new [] {...} expression -> no need to resolve the type there
                    var parent = n.Parent as ArrayCreateExpression;
                    if (parent != null && parent.Type.IsNull)
                        return DefaultControlSpaceItems ();

                    var initalizerResult = ResolveExpression (identifierStart.Item1, n.Parent, identifierStart.Item3);

                    var concreteNode = identifierStart.Item3.GetNodeAt<IdentifierExpression> (location);
                    // check if we're on the right side of an initializer expression
                    if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) {
                        return DefaultControlSpaceItems ();
                    }

                    if (initalizerResult != null && initalizerResult.Item1.Type.Kind != TypeKind.Unknown) {

                        foreach (var property in initalizerResult.Item1.Type.GetProperties ()) {
                            if (!property.IsPublic)
                                continue;
                            contextList.AddMember (property);
                        }
                        foreach (var field in initalizerResult.Item1.Type.GetFields ()) {
                            if (!field.IsPublic)
                                continue;
                            contextList.AddMember (field);
                        }
                        return contextList.Result;
                    }
                    Console.WriteLine ("blub");
                    return DefaultControlSpaceItems ();
                }
                if (n != null/* && !(identifierStart.Item2 is TypeDeclaration)*/) {
                    csResolver = new CSharpResolver (ctx);
                    var nodes = new List<AstNode> ();
                    nodes.Add (n);
                    if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute)
                        nodes.Add (n.Parent);
                    var navigator = new NodeListResolveVisitorNavigator (nodes);
                    var visitor = new ResolveVisitor (csResolver, identifierStart.Item1, navigator);
                    visitor.Scan (identifierStart.Item3);
                    try {
                        csResolver = visitor.GetResolverStateBefore (n);
                    } catch (Exception) {
                        csResolver = GetState ();
                    }
                    // add attribute properties.
                    if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
                        var resolved = visitor.GetResolveResult (n.Parent);
                        if (resolved != null && resolved.Type != null) {
                            foreach (var property in resolved.Type.GetProperties (p => p.Accessibility == Accessibility.Public)) {
                                contextList.AddMember (property);
                            }
                            foreach (var field in resolved.Type.GetFields (p => p.Accessibility == Accessibility.Public)) {
                                contextList.AddMember (field);
                            }
                        }
                    }
                } else {
                    csResolver = GetState ();
                }

                // identifier has already started with the first letter
                offset--;

                AddContextCompletion (contextList, csResolver, identifierStart.Item2);
                return contextList.Result;
            //				if (stub.Parent is BlockStatement)

            //				result = FindExpression (dom, completionContext, -1);
            //				if (result == null)
            //					return null;
            //				 else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) {
            //					triggerWordLength = 1;
            //					bool autoSelect = true;
            //					IType returnType = null;
            //					if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) {
            //						ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
            //						NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
            //						if (dataProvider != null) {
            //							int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
            //							foreach (var method in dataProvider.Methods) {
            //								if (i < method.Parameters.Count) {
            //									returnType = dom.GetType (method.Parameters [i].ReturnType);
            //									autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate;
            //									break;
            //								}
            //							}
            //						}
            //					}
            //					// Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature
            //					//if (result.ExpressionContext == ExpressionContext.TypeName)
            //					//	autoSelect = false;
            //					CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result);
            //					AddEnumMembers (dataList, returnType);
            //					dataList.AutoSelect = autoSelect;
            //					return dataList;
            //				} else {
            //					result = FindExpression (dom, completionContext, 0);
            //					tokenIndex = offset;
            //
            //					// check foreach case, unfortunately the expression finder is too dumb to handle full type names
            //					// should be overworked if the expression finder is replaced with a mcs ast based analyzer.
            //					var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter
            //					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname
            //
            //					// read return types to '(' token
            //					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType
            //					if (possibleForeachToken == ">") {
            //						while (possibleForeachToken != null && possibleForeachToken != "(") {
            //							possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
            //						}
            //					} else {
            //						possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // (
            //						if (possibleForeachToken == ".")
            //							while (possibleForeachToken != null && possibleForeachToken != "(")
            //								possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
            //					}
            //					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach
            //
            //					if (possibleForeachToken == "foreach") {
            //						result.ExpressionContext = ExpressionContext.ForeachInToken;
            //					} else {
            //						return null;
            //						//								result.ExpressionContext = ExpressionContext.IdentifierExpected;
            //					}
            //					result.Expression = "";
            //					result.Region = DomRegion.Empty;
            //
            //					return CreateCtrlSpaceCompletionData (completionContext, result);
            //				}
            //				break;
            }
            return null;
        }
        void AddTypesAndNamespaces(CompletionDataWrapper wrapper, CSharpResolver state, AstNode node, Func<IType, IType> typePred = null, Predicate<IMember> memberPred = null, Action<ICompletionData, IType> callback = null)
        {
            var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);

            if (currentType != null) {
                for (var ct = ctx.CurrentTypeDefinition; ct != null; ct = ct.DeclaringTypeDefinition) {
                    foreach (var nestedType in ct.GetNestedTypes ()) {
                        if (!lookup.IsAccessible (nestedType.GetDefinition (), true))
                            continue;

                        if (typePred == null) {
                            wrapper.AddType(nestedType, false, IsAttributeContext(node));
                            continue;
                        }

                        var type = typePred(nestedType);
                        if (type != null) {
                            var a2 = wrapper.AddType(type, false, IsAttributeContext(node));
                            if (a2 != null && callback != null) {
                                callback(a2, type);
                            }
                        }
                        continue;
                    }
                }
                if (this.currentMember != null && !(node is AstType)) {
                    var def = ctx.CurrentTypeDefinition;
                    if (def == null && currentType != null)
                        def = Compilation.MainAssembly.GetTypeDefinition(currentType.FullTypeName);
                    if (def != null) {
                        bool isProtectedAllowed = true;

                        foreach (var member in def.GetMembers (m => currentMember.IsStatic ? m.IsStatic : true)) {
                            if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
                                continue;
                            }
                            if (member.EntityType == EntityType.Operator) {
                                continue;
                            }
                            if (member.IsExplicitInterfaceImplementation) {
                                continue;
                            }
                            if (!lookup.IsAccessible(member, isProtectedAllowed)) {
                                continue;
                            }
                            if (memberPred == null || memberPred(member)) {
                                wrapper.AddMember(member);
                            }
                        }
                        var declaring = def.DeclaringTypeDefinition;
                        while (declaring != null) {
                            foreach (var member in declaring.GetMembers (m => m.IsStatic)) {
                                if (memberPred == null || memberPred(member)) {
                                    wrapper.AddMember(member);
                                }
                            }
                            declaring = declaring.DeclaringTypeDefinition;
                        }
                    }
                }
                if (ctx.CurrentTypeDefinition != null) {
                    foreach (var p in ctx.CurrentTypeDefinition.TypeParameters) {
                        wrapper.AddTypeParameter(p);
                    }
                }
            }
            var scope = ctx.CurrentUsingScope;

            for (var n = scope; n != null; n = n.Parent) {
                foreach (var pair in n.UsingAliases) {
                    wrapper.AddAlias(pair.Key);
                }
                foreach (var alias in n.ExternAliases) {
                    wrapper.AddAlias(alias);
                }
                foreach (var u in n.Usings) {
                    foreach (var type in u.Types) {
                        if (!lookup.IsAccessible(type, false))
                            continue;

                        IType addType = typePred != null ? typePred(type) : type;
                        if (addType != null) {
                            var a = wrapper.AddType(addType, false, IsAttributeContext(node));
                            if (a != null && callback != null) {
                                callback(a, type);
                            }
                        }
                    }
                }

                foreach (var type in n.Namespace.Types) {
                    if (!lookup.IsAccessible(type, false))
                        continue;
                    IType addType = typePred != null ? typePred(type) : type;
                    if (addType != null) {
                        var a2 = wrapper.AddType(addType, false);
                        if (a2 != null && callback != null) {
                            callback(a2, type);
                        }
                    }
                }

                foreach (var curNs in n.Namespace.ChildNamespaces) {
                    wrapper.AddNamespace(lookup, curNs);
                }
            }

            if (node is AstType && node.Parent is Constraint) {
                wrapper.AddCustom ("new()");
            }
        }
		IEnumerable<ICompletionData> HandleObjectInitializer(SyntaxTree unit, AstNode n)
		{
			var p = n.Parent;
			while (p != null && !(p is ObjectCreateExpression)) {
				p = p.Parent;
			}
			var parent = n.Parent as ArrayInitializerExpression;
			if (parent == null)
				return null;
			if (parent.IsSingleElement)
				parent = (ArrayInitializerExpression)parent.Parent;
			if (p != null) {
				var contextList = new CompletionDataWrapper(this);
				var initializerResult = ResolveExpression(p);
				IType initializerType = null;

				if (initializerResult.Result is DynamicInvocationResolveResult) {
					var dr = (DynamicInvocationResolveResult)initializerResult.Result;
					var constructor = (dr.Target as MethodGroupResolveResult).Methods.FirstOrDefault();
					if (constructor != null)
						initializerType = constructor.DeclaringType;
				} else {
					initializerType = initializerResult != null ? initializerResult.Result.Type : null;
				}


				if (initializerType != null && initializerType.Kind != TypeKind.Unknown) {
					// check 3 cases:
					// 1) New initalizer { xpr
					// 2) Object initializer { prop = val1, field = val2, xpr
					// 3) Array initializer { new Foo (), a, xpr
					// in case 1 all object/array initializer options should be given - in the others not.

					AstNode prev = null;
					if (parent.Elements.Count > 1) {
						prev = parent.Elements.First();
						if (prev is ArrayInitializerExpression && ((ArrayInitializerExpression)prev).IsSingleElement)
							prev = ((ArrayInitializerExpression)prev).Elements.FirstOrDefault();
					}

					if (prev != null && !(prev is NamedExpression)) {
						AddContextCompletion(contextList, GetState(), n);
						// case 3)
						return contextList.Result;
					}
					var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
					bool isProtectedAllowed = ctx.CurrentTypeDefinition != null && initializerType.GetDefinition() != null ? 
					                          ctx.CurrentTypeDefinition.IsDerivedFrom(initializerType.GetDefinition()) : 
					                          false;
					foreach (var m in initializerType.GetMembers (m => m.SymbolKind == SymbolKind.Field)) {
						var f = m as IField;
						if (f != null && (f.IsReadOnly || f.IsConst))
							continue;
						if (lookup.IsAccessible(m, isProtectedAllowed)) {
							var data = contextList.AddMember(m);
							if (data != null)
								data.DisplayFlags |= DisplayFlags.NamedArgument;
						}
					}

					foreach (IProperty m in initializerType.GetMembers (m => m.SymbolKind == SymbolKind.Property)) {
						if (m.CanSet && lookup.IsAccessible(m.Setter, isProtectedAllowed)) {
							var data = contextList.AddMember(m);
							if (data != null)
								data.DisplayFlags |= DisplayFlags.NamedArgument;
						}
					}

					if (prev != null && (prev is NamedExpression)) {
						// case 2)
						return contextList.Result;
					}

					// case 1)

					// check if the object is a list, if not only provide object initalizers
					var list = typeof(System.Collections.IList).ToTypeReference().Resolve(Compilation);
					if (initializerType.Kind != TypeKind.Array && list != null) {
						var def = initializerType.GetDefinition(); 
						if (def != null && !def.IsDerivedFrom(list.GetDefinition()))
							return contextList.Result;
					}

					AddContextCompletion(contextList, GetState(), n);
					return contextList.Result;
				}
			}
			return null;
		}
        static void AddAttributeProperties(CompletionDataWrapper wrapper, ResolveResult resolved)
        {
            if (resolved == null || resolved.Type.Kind == TypeKind.Unknown)
                return;

            foreach (var property in resolved.Type.GetProperties (p => p.Accessibility == Accessibility.Public)) {
                wrapper.AddMember(property);
            }
            foreach (var field in resolved.Type.GetFields (p => p.Accessibility == Accessibility.Public)) {
                wrapper.AddMember(field);
            }
        }
		IEnumerable<ICompletionData> MagicKeyCompletion(char completionChar, bool controlSpace, out bool isComplete)
		{
			isComplete = false;
			ExpressionResolveResult resolveResult;
			switch (completionChar) {
				// Magic key completion
				case ':':
					var text = GetMemberTextToCaret();
					var lexer = new MiniLexer(text.Item1);
					lexer.Parse();
					if (lexer.IsInSingleComment ||
						lexer.IsInChar ||
						lexer.IsInMultiLineComment ||
						lexer.IsInPreprocessorDirective) {
						return Enumerable.Empty<ICompletionData>();
					}

					if (lexer.IsInString || lexer.IsInVerbatimString)
						return HandleStringFormatItems();
					return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
				case '"':
					text = GetMemberTextToCaret();
					lexer = new MiniLexer(text.Item1);
					lexer.Parse();
					if (lexer.IsInSingleComment ||
						lexer.IsInChar ||
						lexer.IsInMultiLineComment ||
						lexer.IsInPreprocessorDirective) {
						return Enumerable.Empty<ICompletionData>();
					}

					if (lexer.IsInString || lexer.IsInVerbatimString)
						return HandleToStringFormatItems();
					return Enumerable.Empty<ICompletionData>();
				case '.':
					if (IsInsideCommentStringOrDirective()) {
						return Enumerable.Empty<ICompletionData>();
					}
					return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
				case '#':
					if (!IsInPreprocessorDirective())
						return null;
					return GetDirectiveCompletionData();
					// XML doc completion
				case '<':
					if (IsInsideDocComment()) {
						return GetXmlDocumentationCompletionData();
					}
					if (controlSpace) {
						return DefaultControlSpaceItems(ref isComplete);
					}
					return null;
				case '>':
					if (!IsInsideDocComment()) {
						if (offset > 2 && document.GetCharAt(offset - 2) == '-' && !IsInsideCommentStringOrDirective()) {
							return HandleMemberReferenceCompletion(GetExpressionBeforeCursor());
						}
						return null;
					}
					return null;

					// Parameter completion
				case '(':
					if (IsInsideCommentStringOrDirective()) {
						return null;
					}
					var invoke = GetInvocationBeforeCursor(true);
					if (invoke == null) {
						if (controlSpace)
							return DefaultControlSpaceItems(ref isComplete, invoke);
						return null;
					}
					if (invoke.Node is TypeOfExpression) {
						return CreateTypeList();
					}
					var invocationResult = ResolveExpression(invoke);
					if (invocationResult == null) {
						return null;
					}
					var methodGroup = invocationResult.Result as MethodGroupResolveResult;
					if (methodGroup != null) {
						return CreateParameterCompletion(
							methodGroup,
							invocationResult.Resolver,
							invoke.Node,
							invoke.Unit,
							0,
							controlSpace
						);
					}

					if (controlSpace) {
						return DefaultControlSpaceItems(ref isComplete, invoke);
					}
					return null;
				case '=':
					return controlSpace ? DefaultControlSpaceItems(ref isComplete) : null;
				case ',':
					int cpos2;
					if (!GetParameterCompletionCommandOffset(out cpos2)) { 
						return null;
					}
					//	completionContext = CompletionWidget.CreateCodeCompletionContext (cpos2);
					//	int currentParameter2 = MethodParameterDataProvider.GetCurrentParameterIndex (CompletionWidget, completionContext) - 1;
					//				return CreateParameterCompletion (CreateResolver (), location, ExpressionContext.MethodBody, provider.Methods, currentParameter);	
					break;

					// Completion on space:
				case ' ':
					int tokenIndex = offset;
					string token = GetPreviousToken(ref tokenIndex, false);
					if (IsInsideCommentStringOrDirective()) {
						return null;
					}
					// check propose name, for context <variable name> <ctrl+space> (but only in control space context)
					//IType isAsType = null;
					var isAsExpression = GetExpressionAt(offset);
					if (controlSpace && isAsExpression != null && isAsExpression.Node is VariableDeclarationStatement && token != "new") {
						var parent = isAsExpression.Node as VariableDeclarationStatement;
						var proposeNameList = new CompletionDataWrapper(this);
						if (parent.Variables.Count != 1)
							return DefaultControlSpaceItems(ref isComplete, isAsExpression, controlSpace);

						foreach (var possibleName in GenerateNameProposals (parent.Type)) {
							if (possibleName.Length > 0) {
								proposeNameList.Result.Add(factory.CreateLiteralCompletionData(possibleName.ToString()));
							}
						}

						AutoSelect = false;
						AutoCompleteEmptyMatch = false;
						isComplete = true;
						return proposeNameList.Result;
					}
					//				int tokenIndex = offset;
					//				string token = GetPreviousToken (ref tokenIndex, false);
					//				if (result.ExpressionContext == ExpressionContext.ObjectInitializer) {
					//					resolver = CreateResolver ();
					//					ExpressionContext exactContext = new NewCSharpExpressionFinder (dom).FindExactContextForObjectInitializer (document, resolver.Unit, Document.FileName, resolver.CallingType);
					//					IReturnType objectInitializer = ((ExpressionContext.TypeExpressionContext)exactContext).UnresolvedType;
					//					if (objectInitializer != null && objectInitializer.ArrayDimensions == 0 && objectInitializer.PointerNestingLevel == 0 && (token == "{" || token == ","))
					//						return CreateCtrlSpaceCompletionData (completionContext, result); 
					//				}
					if (token == "=") {
						int j = tokenIndex;
						string prevToken = GetPreviousToken(ref j, false);
						if (prevToken == "=" || prevToken == "+" || prevToken == "-" || prevToken == "!") {
							token = prevToken + token;
							tokenIndex = j;
						}
					}
					switch (token) {
						case "(":
						case ",":
							int cpos;
							if (!GetParameterCompletionCommandOffset(out cpos)) { 
								break;
							}
							int currentParameter = GetCurrentParameterIndex(cpos - 1, this.offset) - 1;
							if (currentParameter < 0) {
								return null;
							}
							invoke = GetInvocationBeforeCursor(token == "(");
							if (invoke == null) {
								return null;
							}
							invocationResult = ResolveExpression(invoke);
							if (invocationResult == null) {
								return null;
							}
							methodGroup = invocationResult.Result as MethodGroupResolveResult;
							if (methodGroup != null) {
								return CreateParameterCompletion(
									methodGroup,
									invocationResult.Resolver,
									invoke.Node,
									invoke.Unit,
									currentParameter,
									controlSpace);
							}
							return null;
						case "=":
						case "==":
						case "!=":
							GetPreviousToken(ref tokenIndex, false);
							var expressionOrVariableDeclaration = GetExpressionAt(tokenIndex);
							if (expressionOrVariableDeclaration == null) {
								return null;
							}
							resolveResult = ResolveExpression(expressionOrVariableDeclaration);
							if (resolveResult == null) {
								return null;
							}
							if (resolveResult.Result.Type.Kind == TypeKind.Enum) {
								var wrapper = new CompletionDataWrapper(this);
								AddContextCompletion(
									wrapper,
									resolveResult.Resolver,
									expressionOrVariableDeclaration.Node);
								AddEnumMembers(wrapper, resolveResult.Result.Type, resolveResult.Resolver);
								AutoCompleteEmptyMatch = false;
								return wrapper.Result;
							}
							//				
							//					if (resolvedType.FullName == DomReturnType.Bool.FullName) {
							//						CompletionDataList completionList = new ProjectDomCompletionDataList ();
							//						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
							//						completionList.AutoCompleteEmptyMatch = false;
							//						cdc.Add ("true", "md-keyword");
							//						cdc.Add ("false", "md-keyword");
							//						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
							//						return completionList;
							//					}
							//					if (resolvedType.ClassType == ClassType.Delegate && token == "=") {
							//						CompletionDataList completionList = new ProjectDomCompletionDataList ();
							//						string parameterDefinition = AddDelegateHandlers (completionList, resolvedType);
							//						string varName = GetPreviousMemberReferenceExpression (tokenIndex);
							//						completionList.Add (new EventCreationCompletionData (document, varName, resolvedType, null, parameterDefinition, resolver.CallingMember, resolvedType));
							//						
							//						CompletionDataCollector cdc = new CompletionDataCollector (this, dom, completionList, Document.CompilationUnit, resolver.CallingType, location);
							//						resolver.AddAccessibleCodeCompletionData (result.ExpressionContext, cdc);
							//						foreach (var data in completionList) {
							//							if (data is MemberCompletionData) 
							//								((MemberCompletionData)data).IsDelegateExpected = true;
							//						}
							//						return completionList;
							//					}
							return null;
						case "+=":
						case "-=":
							GetPreviousToken(ref tokenIndex, false);

							expressionOrVariableDeclaration = GetExpressionAt(tokenIndex);
							if (expressionOrVariableDeclaration == null) {
								return null;
							}

							resolveResult = ResolveExpression(expressionOrVariableDeclaration);
							if (resolveResult == null) {
								return null;
							}


							var mrr = resolveResult.Result as MemberResolveResult;
							if (mrr != null) {
								var evt = mrr.Member as IEvent;
								if (evt == null) {
									return null;
								}
								var delegateType = evt.ReturnType;
								if (delegateType.Kind != TypeKind.Delegate) {
									return null;
								}

								var wrapper = new CompletionDataWrapper(this);
								if (currentType != null) {
									//							bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
									foreach (var method in ctx.CurrentTypeDefinition.Methods) {
										if (MatchDelegate(delegateType, method) /*										&& method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) {
											wrapper.AddMember(method);
											//									data.SetText (data.CompletionText + ";");
										}
									}
								}
								if (token == "+=") {
									string parameterDefinition = AddDelegateHandlers(
										wrapper,
										delegateType
									);
									string varName = GetPreviousMemberReferenceExpression(tokenIndex);
									wrapper.Result.Add(
										factory.CreateEventCreationCompletionData(
											varName,
											delegateType,
											evt,
											parameterDefinition,
											currentMember,
											currentType)
									);
								}

								return wrapper.Result;
							}
							return null;
						case ":":
							if (currentMember == null) {
								token = GetPreviousToken(ref tokenIndex, false);
								token = GetPreviousToken(ref tokenIndex, false);
								if (token == "enum")
									return HandleEnumContext();
								var wrapper = new CompletionDataWrapper(this);
								AddTypesAndNamespaces(
									wrapper,
									GetState(),
									null,
									t =>  {
										if (currentType != null && currentType.ReflectionName.Equals(t.ReflectionName))
											return null;
										var def = t.GetDefinition();
										if (def != null && t.Kind != TypeKind.Interface && (def.IsSealed ||def.IsStatic))
											return null;
										return t;
									}
								);
								return wrapper.Result;
							}
							return null;
					}

					var keywordCompletion = HandleKeywordCompletion(tokenIndex, token);
					if (keywordCompletion == null && controlSpace) {
						goto default;
					}
					return keywordCompletion;
					// Automatic completion
				default:
					if (IsInsideCommentStringOrDirective()) {
						tokenIndex = offset;
						token = GetPreviousToken(ref tokenIndex, false);
						if (IsInPreprocessorDirective() && (token.Length == 1 && char.IsLetter(completionChar) || controlSpace)) {
							while (token != null && document.GetCharAt(tokenIndex - 1) != '#') {
								token = GetPreviousToken(ref tokenIndex, false);
							}
							if (token != null)
								return HandleKeywordCompletion(tokenIndex, token);
						}
						return null;
					}
					char prevCh = offset > 2 ? document.GetCharAt(offset - 2) : ';';
					char nextCh = offset < document.TextLength ? document.GetCharAt(offset) : ' ';
					const string allowedChars = ";,.[](){}+-*/%^?:&|~!<>=";

					if ((!Char.IsWhiteSpace(nextCh) && allowedChars.IndexOf(nextCh) < 0) || !(Char.IsWhiteSpace(prevCh) || allowedChars.IndexOf(prevCh) >= 0)) {
						if (!controlSpace)
							return null;
					}

					if (IsInLinqContext(offset)) {
						if (!controlSpace && !(char.IsLetter(completionChar) || completionChar == '_')) {
							return null;
						}
						tokenIndex = offset;
						token = GetPreviousToken(ref tokenIndex, false);
						// token last typed
						if (!char.IsWhiteSpace(completionChar) && !linqKeywords.Contains(token)) {
							token = GetPreviousToken(ref tokenIndex, false);
						}
						// token last typed

						if (linqKeywords.Contains(token)) {
							if (token == "from") {
								// after from no auto code completion.
								return null;
							}
							return DefaultControlSpaceItems(ref isComplete);
						}
						var dataList = new CompletionDataWrapper(this);
						AddKeywords(dataList, linqKeywords);
						return dataList.Result;
					}
					if (currentType != null && currentType.Kind == TypeKind.Enum) {
						if (!char.IsLetter(completionChar))
							return null;
						return HandleEnumContext();
					}
					var contextList = new CompletionDataWrapper(this);
					var identifierStart = GetExpressionAtCursor();
					if (!(char.IsLetter(completionChar) || completionChar == '_') && (!controlSpace || identifierStart == null)) {
						return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(ref isComplete, identifierStart) : null;
					}

					if (identifierStart != null) {
						if (identifierStart.Node is TypeParameterDeclaration) {
							return null;
						}

						if (identifierStart.Node is MemberReferenceExpression) {
							return HandleMemberReferenceCompletion(
								new ExpressionResult(
									((MemberReferenceExpression)identifierStart.Node).Target,
									identifierStart.Unit
								)
							);
						}

						if (identifierStart.Node is Identifier) {
							if (identifierStart.Node.Parent is GotoStatement)
								return null;

							// May happen in variable names
							return controlSpace ? DefaultControlSpaceItems(ref isComplete, identifierStart) : null;
						}
						if (identifierStart.Node is VariableInitializer && location <= ((VariableInitializer)identifierStart.Node).NameToken.EndLocation) {
							return controlSpace ? HandleAccessorContext() ?? DefaultControlSpaceItems(ref isComplete, identifierStart) : null;
						}
						if (identifierStart.Node is CatchClause) {
							if (((CatchClause)identifierStart.Node).VariableNameToken.IsInside(location)) {
								return null;
							}
						}
						if (identifierStart.Node is AstType && identifierStart.Node.Parent is CatchClause) {
							return HandleCatchClauseType(identifierStart);
						}

						var pDecl = identifierStart.Node as ParameterDeclaration;
						if (pDecl != null && pDecl.Parent is LambdaExpression) {
							return null;
						}
					}


					// Do not pop up completion on identifier identifier (should be handled by keyword completion).
					tokenIndex = offset - 1;
					token = GetPreviousToken(ref tokenIndex, false);
					if (token == "class" || token == "interface" || token == "struct" || token == "enum" || token == "namespace") {
						// after these always follows a name
						return null;
					}
					var keywordresult = HandleKeywordCompletion(tokenIndex, token);
					if (keywordresult != null) {
						return keywordresult;
					}

					if ((!Char.IsWhiteSpace(nextCh) && allowedChars.IndexOf(nextCh) < 0) || !(Char.IsWhiteSpace(prevCh) || allowedChars.IndexOf(prevCh) >= 0)) {
						if (controlSpace)
							return DefaultControlSpaceItems(ref isComplete, identifierStart);
					}

					int prevTokenIndex = tokenIndex;
					var prevToken2 = GetPreviousToken(ref prevTokenIndex, false);
					if (prevToken2 == "delegate") {
						// after these always follows a name
						return null;
					}

					if (identifierStart == null && !string.IsNullOrEmpty(token) && !IsInsideCommentStringOrDirective() && (prevToken2 == ";" || prevToken2 == "{" || prevToken2 == "}")) {
						char last = token [token.Length - 1];
						if (char.IsLetterOrDigit(last) || last == '_' || token == ">") {
							return HandleKeywordCompletion(tokenIndex, token);
						}
					}
					if (identifierStart == null) {
						var accCtx = HandleAccessorContext();
						if (accCtx != null) {
							return accCtx;
						}
						return DefaultControlSpaceItems(ref isComplete, null, controlSpace);
					}
					CSharpResolver csResolver;
					AstNode n = identifierStart.Node;
					if (n.Parent is NamedArgumentExpression)
						n = n.Parent;

					if (n != null && n.Parent is AnonymousTypeCreateExpression) {
						AutoSelect = false;
					}

					// new { b$ } 
					if (n is IdentifierExpression && n.Parent is AnonymousTypeCreateExpression)
						return null;

					// Handle foreach (type name _
					if (n is IdentifierExpression) {
						var prev = n.GetPrevNode() as ForeachStatement;
						while (prev != null && prev.EmbeddedStatement is ForeachStatement)
							prev = (ForeachStatement)prev.EmbeddedStatement;
						if (prev != null && prev.InExpression.IsNull) {
							if (IncludeKeywordsInCompletionList)
								contextList.AddCustom("in");
							return contextList.Result;
						}
					}
					// Handle object/enumerable initialzer expressions: "new O () { P$"
					if (n is IdentifierExpression && n.Parent is ArrayInitializerExpression && !(n.Parent.Parent is ArrayCreateExpression)) {
						var result = HandleObjectInitializer(identifierStart.Unit, n);
						if (result != null)
							return result;
					}

					if (n != null && n.Parent is InvocationExpression ||
						n.Parent is ParenthesizedExpression && n.Parent.Parent is InvocationExpression) {
						if (n.Parent is ParenthesizedExpression)
							n = n.Parent;
						var invokeParent = (InvocationExpression)n.Parent;
						var invokeResult = ResolveExpression(
							invokeParent.Target
						);
						var mgr = invokeResult != null ? invokeResult.Result as MethodGroupResolveResult : null;
						if (mgr != null) {
							int idx = 0;
							foreach (var arg in invokeParent.Arguments) {
								if (arg == n) {
									break;
								}
								idx++;
							}

							foreach (var method in mgr.Methods) {
								if (idx < method.Parameters.Count && method.Parameters [idx].Type.Kind == TypeKind.Delegate) {
									AutoSelect = false;
									AutoCompleteEmptyMatch = false;
								}
								foreach (var p in method.Parameters) {
									contextList.AddNamedParameterVariable(p);
								}
							}
							idx++;
							foreach (var list in mgr.GetEligibleExtensionMethods (true)) {
								foreach (var method in list) {
									if (idx < method.Parameters.Count && method.Parameters [idx].Type.Kind == TypeKind.Delegate) {
										AutoSelect = false;
										AutoCompleteEmptyMatch = false;
									}
								}
							}
						}
					}

					if (n != null && n.Parent is ObjectCreateExpression) {
						var invokeResult = ResolveExpression(n.Parent);
						var mgr = invokeResult != null ? invokeResult.Result as ResolveResult : null;
						if (mgr != null) {
							foreach (var constructor in mgr.Type.GetConstructors ()) {
								foreach (var p in constructor.Parameters) {
									contextList.AddVariable(p);
								}
							}
						}
					}

					if (n is IdentifierExpression) {
						var bop = n.Parent as BinaryOperatorExpression;
						Expression evaluationExpr = null;

						if (bop != null && bop.Right == n && (bop.Operator == BinaryOperatorType.Equality || bop.Operator == BinaryOperatorType.InEquality)) {
							evaluationExpr = bop.Left;
						}
						// check for compare to enum case 
						if (evaluationExpr != null) {
							resolveResult = ResolveExpression(evaluationExpr);
							if (resolveResult != null && resolveResult.Result.Type.Kind == TypeKind.Enum) {
								var wrapper = new CompletionDataWrapper(this);
								AddContextCompletion(
									wrapper,
									resolveResult.Resolver,
									evaluationExpr
								);
								AddEnumMembers(wrapper, resolveResult.Result.Type, resolveResult.Resolver);
								AutoCompleteEmptyMatch = false;
								return wrapper.Result;
							}
						}
					}

					if (n is Identifier && n.Parent is ForeachStatement) {
						if (controlSpace) {
							return DefaultControlSpaceItems(ref isComplete);
						}
						return null;
					}

					if (n is ArrayInitializerExpression) {
						// check for new [] {...} expression -> no need to resolve the type there
						var parent = n.Parent as ArrayCreateExpression;
						if (parent != null && parent.Type.IsNull) {
							return DefaultControlSpaceItems(ref isComplete);
						}

						var initalizerResult = ResolveExpression(n.Parent);

						var concreteNode = identifierStart.Unit.GetNodeAt<IdentifierExpression>(location);
						// check if we're on the right side of an initializer expression
						if (concreteNode != null && concreteNode.Parent != null && concreteNode.Parent.Parent != null && concreteNode.Identifier != "a" && concreteNode.Parent.Parent is NamedExpression) {
							return DefaultControlSpaceItems(ref isComplete);
						}
						if (initalizerResult != null && initalizerResult.Result.Type.Kind != TypeKind.Unknown) { 

							foreach (var property in initalizerResult.Result.Type.GetProperties ()) {
								if (!property.IsPublic) {
									continue;
								}
								var data = contextList.AddMember(property);
								if (data != null)
									data.DisplayFlags |= DisplayFlags.NamedArgument;
							}
							foreach (var field in initalizerResult.Result.Type.GetFields ()) {       
								if (!field.IsPublic) {
									continue;
								}
								var data = contextList.AddMember(field);
								if (data != null)
									data.DisplayFlags |= DisplayFlags.NamedArgument;
							}
							return contextList.Result;
						}
						return DefaultControlSpaceItems(ref isComplete);
					}

					if (IsAttributeContext(n)) {
						// add attribute targets
						if (currentType == null) {
							contextList.AddCustom("assembly");
							contextList.AddCustom("module");
							contextList.AddCustom("type");
						} else {
							contextList.AddCustom("param");
							contextList.AddCustom("field");
							contextList.AddCustom("property");
							contextList.AddCustom("method");
							contextList.AddCustom("event");
						}
						contextList.AddCustom("return");
					}
					if (n is MemberType) {
						resolveResult = ResolveExpression(
							((MemberType)n).Target
						);
						return CreateTypeAndNamespaceCompletionData(
							location,
							resolveResult.Result,
							((MemberType)n).Target,
							resolveResult.Resolver
						);
					}
					if (n != null/*					 && !(identifierStart.Item2 is TypeDeclaration)*/) {
						csResolver = new CSharpResolver(ctx);
						var nodes = new List<AstNode>();
						nodes.Add(n);
						if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
							nodes.Add(n.Parent);
						}
						var astResolver = CompletionContextProvider.GetResolver(csResolver, identifierStart.Unit);
						astResolver.ApplyNavigator(new NodeListResolveVisitorNavigator(nodes));
						try {
							csResolver = astResolver.GetResolverStateBefore(n);
						} catch (Exception) {
							csResolver = GetState();
						}
						// add attribute properties.
						if (n.Parent is ICSharpCode.NRefactory.CSharp.Attribute) {
							var rr = ResolveExpression(n.Parent);
							if (rr != null)
								AddAttributeProperties(contextList, rr.Result);
						}
					} else {
						csResolver = GetState();
					}
					// identifier has already started with the first letter
					offset--;
					AddContextCompletion(
						contextList,
						csResolver,
						identifierStart.Node
					);
					return contextList.Result;
					//				if (stub.Parent is BlockStatement)

					//				result = FindExpression (dom, completionContext, -1);
					//				if (result == null)
					//					return null;
					//				 else if (result.ExpressionContext != ExpressionContext.IdentifierExpected) {
					//					triggerWordLength = 1;
					//					bool autoSelect = true;
					//					IType returnType = null;
					//					if ((prevCh == ',' || prevCh == '(') && GetParameterCompletionCommandOffset (out cpos)) {
					//						ctx = CompletionWidget.CreateCodeCompletionContext (cpos);
					//						NRefactoryParameterDataProvider dataProvider = ParameterCompletionCommand (ctx) as NRefactoryParameterDataProvider;
					//						if (dataProvider != null) {
					//							int i = dataProvider.GetCurrentParameterIndex (CompletionWidget, ctx) - 1;
					//							foreach (var method in dataProvider.Methods) {
					//								if (i < method.Parameters.Count) {
					//									returnType = dom.GetType (method.Parameters [i].ReturnType);
					//									autoSelect = returnType == null || returnType.ClassType != ClassType.Delegate;
					//									break;
					//								}
					//							}
					//						}
					//					}
					//					// Bug 677531 - Auto-complete doesn't always highlight generic parameter in method signature
					//					//if (result.ExpressionContext == ExpressionContext.TypeName)
					//					//	autoSelect = false;
					//					CompletionDataList dataList = CreateCtrlSpaceCompletionData (completionContext, result);
					//					AddEnumMembers (dataList, returnType);
					//					dataList.AutoSelect = autoSelect;
					//					return dataList;
					//				} else {
					//					result = FindExpression (dom, completionContext, 0);
					//					tokenIndex = offset;
					//					
					//					// check foreach case, unfortunately the expression finder is too dumb to handle full type names
					//					// should be overworked if the expression finder is replaced with a mcs ast based analyzer.
					//					var possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // starting letter
					//					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varname
					//				
					//					// read return types to '(' token
					//					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // varType
					//					if (possibleForeachToken == ">") {
					//						while (possibleForeachToken != null && possibleForeachToken != "(") {
					//							possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
					//						}
					//					} else {
					//						possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // (
					//						if (possibleForeachToken == ".")
					//							while (possibleForeachToken != null && possibleForeachToken != "(")
					//								possibleForeachToken = GetPreviousToken (ref tokenIndex, false);
					//					}
					//					possibleForeachToken = GetPreviousToken (ref tokenIndex, false); // foreach
					//				
					//					if (possibleForeachToken == "foreach") {
					//						result.ExpressionContext = ExpressionContext.ForeachInToken;
					//					} else {
					//						return null;
					//						//								result.ExpressionContext = ExpressionContext.IdentifierExpected;
					//					}
					//					result.Expression = "";
					//					result.Region = DomRegion.Empty;
					//				
					//					return CreateCtrlSpaceCompletionData (completionContext, result);
					//				}
					//				break;
			}
			return null;

		}
 void AddExtensionMethods(CompletionDataWrapper result, Conversions conv, List<IType> baseTypes, string namespaceName)
 {
     if (ctx.CurrentUsingScope == null || ctx.CurrentUsingScope.AllExtensionMethods == null)
         return;
     foreach (var meths in ctx.CurrentUsingScope.AllExtensionMethods) {
         foreach (var m in meths) {
             var pt = m.Parameters.First ().Type;
             string reflectionName = pt is ParameterizedType ? ((ParameterizedType)pt).GetDefinition ().ReflectionName : pt.ReflectionName;
             if (baseTypes.Any (bt => (bt is ParameterizedType ? ((ParameterizedType)bt).GetDefinition ().ReflectionName : bt.ReflectionName) == reflectionName)) {
                 result.AddMember (m);
             }
         }
     }
 }