IEnumerable<IMethodSymbol> GetExtensionMethods (SemanticModel semanticModel, ITypeSymbol typeToExtend, InvocationExpressionSyntax node, CancellationToken cancellationToken)
		{
			var usedNamespaces = new HashSet<string> ();
			foreach (var un in semanticModel.GetUsingNamespacesInScope (node)) {
				usedNamespaces.Add (un.GetFullName ());
			}
			var enclosingNamespaceName = semanticModel.GetEnclosingNamespace (node.SpanStart, cancellationToken).GetFullName ();

			var stack = new Stack<INamespaceOrTypeSymbol> ();
			stack.Push (semanticModel.Compilation.GlobalNamespace);

			while (stack.Count > 0) {
				if (cancellationToken.IsCancellationRequested)
					break;
				var current = stack.Pop ();
				var currentNs = current as INamespaceSymbol;
				if (currentNs != null) {

					foreach (var member in currentNs.GetNamespaceMembers ()) {
						var currentNsName = member.GetFullName ();
						if (usedNamespaces.Contains (currentNsName) ||
							enclosingNamespaceName == currentNsName ||
							(enclosingNamespaceName.StartsWith (currentNsName, StringComparison.Ordinal) &&
							enclosingNamespaceName [currentNsName.Length] == '.')) {
							stack.Push (member);
						}
					}

					foreach (var member in currentNs.GetTypeMembers ())
						stack.Push (member);

				} else {
					var type = (INamedTypeSymbol)current;
					if (type.IsImplicitClass || type.IsScriptClass)
						continue;
					if (type.DeclaredAccessibility != Accessibility.Public) {
						if (type.DeclaredAccessibility != Accessibility.Internal)
							continue;
						if (!type.IsAccessibleWithin (semanticModel.Compilation.Assembly))
							continue;
					}
					if (!type.MightContainExtensionMethods)
						continue;
					foreach (var extMethod in type.GetMembers ().OfType<IMethodSymbol> ().Where (method => method.IsExtensionMethod)) {
						var reducedMethod = extMethod.ReduceExtensionMethod (typeToExtend);
						if (reducedMethod != null) {
							yield return reducedMethod;
						}
					}
				}
			}
		}