internal static InstanceProvider?ForMethod(
            Compilation compilation,
            AttributedMembers attrMembers,
            DeserializerTypes types,
            Location?loc,
            INamedTypeSymbol rowType,
            INamedTypeSymbol hostType,
            string mtdName,
            ref ImmutableArray <Diagnostic> diags
            )
        {
            var instanceProviderMtd = Utils.GetMethod(hostType, mtdName, loc, ref diags);

            if (instanceProviderMtd == null)
            {
                return(null);
            }

            var instanceProviderLoc = instanceProviderMtd.Locations.FirstOrDefault();

            var methodReturnType = instanceProviderMtd.ReturnType;

            if (methodReturnType.SpecialType != SpecialType.System_Boolean)
            {
                var diag = Diagnostics.MethodMustReturnBool(instanceProviderLoc, instanceProviderMtd);
                diags = diags.Add(diag);

                return(null);
            }

            if (!instanceProviderMtd.IsStatic)
            {
                var diag = Diagnostics.MethodNotStatic(instanceProviderLoc, instanceProviderMtd);
                diags = diags.Add(diag);

                return(null);
            }

            var accessible = instanceProviderMtd.IsAccessible(attrMembers);

            if (!accessible)
            {
                var diag = Diagnostics.MethodNotPublicOrInternal(instanceProviderLoc, instanceProviderMtd);
                diags = diags.Add(diag);

                return(null);
            }

            var ps = instanceProviderMtd.Parameters;

            if (ps.Length != 2)
            {
                var diag = Diagnostics.BadInstanceProviderParameters(instanceProviderLoc, instanceProviderMtd);
                diags = diags.Add(diag);

                return(null);
            }

            var p0 = ps[0];

            if (!p0.IsInReadContext(types.OurTypes))
            {
                var diag = Diagnostics.BadInstanceProviderParameters(instanceProviderLoc, instanceProviderMtd);
                diags = diags.Add(diag);

                return(null);
            }

            var p1 = ps[1];

            if (p1.RefKind != RefKind.Out)
            {
                var diag = Diagnostics.BadInstanceProviderParameters(instanceProviderLoc, instanceProviderMtd);
                diags = diags.Add(diag);

                return(null);
            }

            var conversion = compilation.ClassifyConversion(p1.Type, rowType);
            var canConvert = conversion.IsImplicit || conversion.IsIdentity;

            if (!canConvert)
            {
                var diag = Diagnostics.BadInstanceProviderParameters(instanceProviderLoc, instanceProviderMtd);
                diags = diags.Add(diag);

                return(null);
            }

            return(new InstanceProvider(false, instanceProviderMtd, p1.Type));
        }