public SD_ConstructedMethodGroup(SD_MethodGroup definition, SymbolReference[] arguments)
 {
     name         = definition.name;
     kind         = definition.kind;
     parentSymbol = definition.parentSymbol;
     genericMethodGroupDefinition = definition;
     modifiers     = definition.modifiers;
     typeArguments = arguments;
 }
    public override SymbolDefinition ResolveAsExtensionMethod(SyntaxTreeNode_Leaf invokedLeaf, SymbolDefinition invokedSymbol, TypeDefinitionBase memberOf, SyntaxTreeNode_Rule argumentListNode, SymbolReference[] typeArgs, Scope_Base context)
    {
        if (invokedLeaf == null && (invokedSymbol == null || invokedSymbol.kind == SymbolKind.Error))
        {
            return(null);
        }

        var id = invokedSymbol != null && invokedSymbol.kind != SymbolKind.Error ? invokedSymbol.name : invokedLeaf != null?SymbolDefinition.DecodeId(invokedLeaf.token.text) : "";

        int numArguments = 1;

        Modifiers[] modifiers = null;
        List <TypeDefinitionBase> argumentTypes = null;

        MethodDefinition firstAccessibleMethod = null;

        var thisAssembly = GetAssembly();

        var extensionsMethods = new HashSet <MethodDefinition>();

        thisAssembly.CollectExtensionMethods(definition, id, typeArgs, memberOf, extensionsMethods, context);
        if (extensionsMethods.Count > 0)
        {
            firstAccessibleMethod = extensionsMethods.First();

            if (argumentTypes == null)
            {
                numArguments = SD_MethodGroup.ProcessArgumentListNode(argumentListNode, out modifiers, out argumentTypes, memberOf);
            }

            var candidates = new List <MethodDefinition>(extensionsMethods.Count);
            foreach (var method in extensionsMethods)
            {
                if (argumentTypes == null || method.CanCallWith(modifiers, true))
                {
                    candidates.Add(method);
                }
            }

            if (typeArgs == null)
            {
                for (var i = candidates.Count; i-- > 0;)
                {
                    var candidate = candidates[i];
                    if (candidate.NumTypeParameters == 0 || argumentTypes == null)
                    {
                        continue;
                    }

                    candidate = SD_MethodGroup.InferMethodTypeArguments(candidate, argumentTypes, invokedLeaf);
                    if (candidate == null)
                    {
                        candidates.RemoveAt(i);
                    }
                    else
                    {
                        candidates[i] = candidate;
                    }
                }
            }

            var resolved = SD_MethodGroup.ResolveMethodOverloads(numArguments, argumentTypes, modifiers, candidates);
            if (resolved != null && resolved.kind != SymbolKind.Error)
            {
                return(resolved);
            }
        }

        extensionsMethods.Clear();

        var importedNamespaces = declaration.importedNamespaces;

        for (var i = importedNamespaces.Count; i-- > 0;)
        {
            var nsDef = importedNamespaces[i].Definition as SD_NameSpace;
            if (nsDef != null)
            {
                thisAssembly.CollectExtensionMethods(nsDef, id, typeArgs, memberOf, extensionsMethods, context);
            }
        }
        if (extensionsMethods.Count > 0)
        {
            if (firstAccessibleMethod == null)
            {
                firstAccessibleMethod = extensionsMethods.First();
            }

            if (argumentTypes == null)
            {
                numArguments = SD_MethodGroup.ProcessArgumentListNode(argumentListNode, out modifiers, out argumentTypes, memberOf);
            }

            var candidates = new List <MethodDefinition>(extensionsMethods.Count);
            foreach (var method in extensionsMethods)
            {
                if (argumentTypes == null || method.CanCallWith(modifiers, true))
                {
                    candidates.Add(method);
                }
            }

            if (typeArgs == null)
            {
                for (var i = candidates.Count; i-- > 0;)
                {
                    var candidate = candidates[i];
                    if (candidate.NumTypeParameters == 0 || argumentTypes == null)
                    {
                        continue;
                    }

                    candidate = SD_MethodGroup.InferMethodTypeArguments(candidate, argumentTypes, invokedLeaf);
                    if (candidate == null)
                    {
                        candidates.RemoveAt(i);
                    }
                    else
                    {
                        candidates[i] = candidate;
                    }
                }
            }

            var resolved = SD_MethodGroup.ResolveMethodOverloads(numArguments, argumentTypes, modifiers, candidates);
            if (resolved != null && resolved.kind != SymbolKind.Error)
            {
                return(resolved);
            }
        }

        if (parentScope != null)
        {
            var resolved = parentScope.ResolveAsExtensionMethod(invokedLeaf, invokedSymbol, memberOf, argumentListNode, typeArgs, context);
            if (resolved != null)
            {
                return(resolved);
            }
        }

        if (firstAccessibleMethod != null)
        {
            invokedLeaf.ResolvedSymbol   = firstAccessibleMethod;
            invokedLeaf.m_sSemanticError = SD_MethodGroup.unresolvedMethodOverload.name;
        }
        return(null);
    }