private IEnumerable<ISymbol> GetAttributeNamedParameters(
     SemanticModel semanticModel,
     int position,
     AttributeSyntax attribute,
     CancellationToken cancellationToken)
 {
     var within = semanticModel.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
     var attributeType = semanticModel.GetTypeInfo(attribute, cancellationToken).Type as INamedTypeSymbol;
     return attributeType.GetAttributeNamedParameters(semanticModel.Compilation, within);
 }
        private IEnumerable<ImmutableArray<IParameterSymbol>> GetParameterLists(
            SemanticModel semanticModel,
            int position,
            AttributeSyntax attribute,
            CancellationToken cancellationToken)
        {
            var within = semanticModel.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
            var attributeType = semanticModel.GetTypeInfo(attribute, cancellationToken).Type as INamedTypeSymbol;
            if (within != null && attributeType != null)
            {
                return attributeType.InstanceConstructors.Where(c => c.IsAccessibleWithin(within))
                                                         .Select(c => c.Parameters);
            }

            return SpecializedCollections.EmptyEnumerable<ImmutableArray<IParameterSymbol>>();
        }
		ParameterHintingResult HandleElementAccessExpression(SemanticModel semanticModel, ElementAccessExpressionSyntax node, CancellationToken cancellationToken)
		{
			var within = semanticModel.GetEnclosingNamedTypeOrAssembly(node.SpanStart, cancellationToken);

			var targetTypeInfo = semanticModel.GetTypeInfo (node.Expression);
			ITypeSymbol type = targetTypeInfo.Type;
			if (type == null)
				return ParameterHintingResult.Empty;

			var result = new ParameterHintingResult(node.SpanStart);
			if (type.TypeKind == TypeKind.Array) {
				result.AddData (factory.CreateArrayDataProvider ((IArrayTypeSymbol)type));
				return result;
			}

			var addedProperties = new List<IPropertySymbol> ();
			for (;type != null; type = type.BaseType) {
				foreach (var indexer in type.GetMembers ().OfType<IPropertySymbol> ().Where (p => p.IsIndexer)) {
					if (addedProperties.Any (added => SignatureComparer.HaveSameSignature (indexer, added, true)))
						continue;

					if (indexer.IsAccessibleWithin (within)) {
						addedProperties.Add (indexer); 
						result.AddData (factory.CreateIndexerParameterDataProvider (indexer, node));
					}
				}
			}
			return result;
		}
		ParameterHintingResult HandleObjectCreationExpression (SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken)
		{
			// var info = semanticModel.GetSymbolInfo(node, cancellationToken);
			var result = new ParameterHintingResult(node.SpanStart);
			var within = semanticModel.GetEnclosingNamedTypeOrAssembly(node.SpanStart, cancellationToken);

			var targetTypeInfo = semanticModel.GetTypeInfo (node);
			if (targetTypeInfo.Type != null) {
				foreach (IMethodSymbol c in targetTypeInfo.Type.GetMembers().OfType<IMethodSymbol>().Where(m => m.MethodKind == MethodKind.Constructor)) {
					if (c.IsAccessibleWithin (within)) {
						result.AddData(factory.CreateConstructorProvider(c));
					}
				}
			}
			return result;
		}
		ParameterHintingResult HandleInvocationExpression(SemanticModel semanticModel, InvocationExpressionSyntax node, CancellationToken cancellationToken)
		{
			var info = semanticModel.GetSymbolInfo (node, cancellationToken);
			var result = new ParameterHintingResult(node.SpanStart);

			var targetTypeInfo = semanticModel.GetTypeInfo (node.Expression);
			if (targetTypeInfo.Type != null && targetTypeInfo.Type.TypeKind == TypeKind.Delegate) {
				result.AddData (factory.CreateMethodDataProvider (targetTypeInfo.Type.GetDelegateInvokeMethod ()));
				return result;
			}

			var within = semanticModel.GetEnclosingNamedTypeOrAssembly(node.SpanStart, cancellationToken);
			ITypeSymbol type;
			string name = null;
			bool staticLookup = false;
			var ma = node.Expression as MemberAccessExpressionSyntax;
			var mb = node.Expression as MemberBindingExpressionSyntax;
			if (mb != null) {
				info = semanticModel.GetSymbolInfo (mb, cancellationToken);
				type = (info.Symbol ?? info.CandidateSymbols.FirstOrDefault ())?.ContainingType;
				name = mb.Name.Identifier.ValueText;
			} else if (ma != null) {
				staticLookup = semanticModel.GetSymbolInfo (ma.Expression).Symbol is ITypeSymbol;
				type = semanticModel.GetTypeInfo (ma.Expression).Type;
				name = info.Symbol?.Name ?? ma.Name.Identifier.ValueText;
			} else {
				type = within as ITypeSymbol;
				name = info.Symbol?.Name ?? node.Expression.ToString ();
				var sym = semanticModel.GetEnclosingSymbol (node.SpanStart, cancellationToken); 
				staticLookup = sym.IsStatic;
			}
			var addedMethods = new List<IMethodSymbol> ();
			var filterMethod = new HashSet<IMethodSymbol> ();
			for (;type != null; type = type.BaseType) {
				foreach (var method in type.GetMembers ().OfType<IMethodSymbol> ().Concat (GetExtensionMethods(semanticModel, type, node, cancellationToken)).Where (m => m.Name == name)) {
					if (staticLookup && !method.IsStatic)
						continue;
					if (method.OverriddenMethod != null)
						filterMethod.Add (method.OverriddenMethod);
					if (filterMethod.Contains (method))
						continue;
					if (addedMethods.Any (added => SignatureComparer.HaveSameSignature (method, added, true)))
						continue;
					if (method.IsAccessibleWithin (within)) {
						if (info.Symbol != null) {
							var smethod = (IMethodSymbol)info.Symbol;
							if (smethod != null && smethod.OriginalDefinition == method) {
								continue;
							}
						}
						addedMethods.Add (method); 
						result.AddData (factory.CreateMethodDataProvider (method));
					}
				}
			}
			if (info.Symbol != null && !addedMethods.Contains (info.Symbol)) {
				if (!staticLookup || info.Symbol.IsStatic)
					result.AddData (factory.CreateMethodDataProvider ((IMethodSymbol)info.Symbol));
			}
			return result;
		}