//static public MethodReference HHH(this MethodDefinition @this, Dictionary<TypeReference, TypeReference> genericity, MethodReference met)
        //{
        //    if (met is GenericInstanceMethod)
        //    {
        //        if (met.DeclaringType is GenericInstanceType)
        //        {
        //            //var mmm = new MethodReference(met.Name, @this.HHH(genericity, met.ReturnType), @this.HHH(genericity, met.DeclaringType))
        //            //{
        //            //    HasThis = met.HasThis,
        //            //    ExplicitThis = met.ExplicitThis,
        //            //    CallingConvention = met.CallingConvention
        //            //};
        //            //foreach (var parameter in met.Parameters)
        //            //{
        //            //    mmm.Parameters.Add(new ParameterDefinition(@this.HHH(genericity, parameter.ParameterType)));
        //            //}

        //            //foreach (var generic_parameter in met.GenericParameters)
        //            //{
        //            //    mmm.GenericParameters.Add(new GenericParameter(generic_parameter.Name, mmm));
        //            //}
        //            ////var hhhh = new GenericInstanceMethod(mmm);
        //            ////hhhh.
        //            //return mmm.MakeGenericMethod((met as GenericInstanceMethod).GenericArguments.Select(_Type => @this.HHH(genericity, _Type)).ToArray());
        //            //return mmm.MakeGenericMethod((met as GenericInstanceMethod).GenericArguments.Select(_Type => @this.HHH(genericity, _Type)).ToArray());


        //            return @this.Module.Import(@this.Module.Import(met.Resolve())

        //            .MakeGenericMethod((met as GenericInstanceMethod).GenericArguments.Select(_Type => @this.HHH(genericity, _Type)).ToArray())
        //            .MakeHostInstanceGeneric((@this.HHH(genericity, met.DeclaringType) as GenericInstanceType).GenericArguments.ToArray()));

        //            ////var ggg = new GenericInstanceMethod(@this.Module.Import(met.Resolve()));
        //            //ggg.DeclaringType = @this.HHH(genericity, met.DeclaringType);
        //            //ggg.Parameters.Clear();
        //            //foreach (var _parameter in met.Parameters) { ggg.Parameters.Add(new ParameterDefinition(_parameter.Name, _parameter.Attributes, /*@this.HHH(genericity, */_parameter.ParameterType/*)*/)); }
        //            //foreach (var _type in (met as GenericInstanceMethod).GenericArguments) { ggg.GenericArguments.Add(@this.HHH(genericity, _type)); }

        //            //var m = @this.Module.Import(@this.Module.Import(met.Resolve()).MakeHostInstanceGeneric((@this.HHH(genericity, met.DeclaringType) as GenericInstanceType).GenericArguments.Select(_Type => @this.HHH(genericity, _Type)).ToArray()).MakeGenericMethod((met as GenericInstanceMethod).GenericArguments.Select(ppp => @this.HHH(genericity, ppp)).Select(_Type => @this.HHH(genericity, _Type)).ToArray()));
        //            //return met;
        //            //return ggg;
        //        }
        //        else
        //        {
        //            var m =  @this.Module.Import(@this.Module.Import(met.Resolve()).MakeGenericMethod((met as GenericInstanceMethod).GenericArguments.Select(ppp => @this.HHH(genericity, ppp)).ToArray()));
        //            return m;
        //        }
        //    }
        //    else
        //    {
        //        if (met.DeclaringType is GenericInstanceType)
        //        {
        //            var m = @this.Module.Import(met.Resolve()).MakeHostInstanceGeneric((@this.HHH(genericity, met.DeclaringType) as GenericInstanceType).GenericArguments.Select(_Type =>
        //            {
        //                var hhhhhhh = met;
        //                return @this.HHH(genericity, _Type);
        //            }).ToArray());
        //            return m;
        //        }
        //        else
        //        {
        //            return met;
        //        }
        //    }
        //}

        //static public TypeReference HHH(this MethodDefinition @this, Dictionary<TypeReference, TypeReference> genericity, TypeReference type)
        //{
        //    if (type.IsByReference/* || type.Name.EndsWith("&")*/) { return new ByReferenceType(@this.HHH(genericity, (type as ByReferenceType).ElementType)); }
        //    if (genericity.TryGetValue(type, out var _type)) { return _type; }
        //    //var _genericity = @this.DeclaringType.GenericParameters.Concat(@this.GenericParameters).ToArray();
        //    //if (type.Name.StartsWith("!!")) { return _genericity[int.Parse(type.Name.Substring(2)) + @this.DeclaringType.DeclaringType.GenericParameters.Count]; }
        //    //if (type.Name.StartsWith("!")) { return _genericity[int.Parse(type.Name.Substring(1))]; }
        //    if (type is GenericInstanceType) { return @this.Module.Import(type.Resolve()).MakeGenericType((type as GenericInstanceType).GenericArguments.Select(_Type => @this.HHH(genericity, _Type))); }
        //    return type;
        //}

        static public MethodReference Repair(this MethodReference that, MethodReference method)
        {
            var _types = that.GenericParameterTypes().Select(_Type => _Type.Name.StartsWith("!!") ? that.GenericParameters[int.Parse(_Type.Name.Substring(2))] : (_Type.Name.StartsWith("!") ? that.DeclaringType.GenericParameters[int.Parse(_Type.Name.Substring(1))] : _Type)).ToArray();

            if (_types.Length > 0)
            {
                if (method.GenericParameters.Count > 0) //TODO test it!
                {
                    var dec = that.GetRealType(method.DeclaringType);
                    if (dec is GenericInstanceType)
                    {
                        var _method = that.Module.Import(method.Resolve()).MakeHostInstanceGeneric((dec as GenericInstanceType).GenericArguments.ToArray());
                        //var _method = new MethodReference(method.Name, that.GetRealType(method.ReturnType), that.GetRealType(method.DeclaringType));
                        //foreach (var _parameter in method.Parameters) { _method.Parameters.Add(new ParameterDefinition(_parameter.Name, _parameter.Attributes, that.GetRealType(_parameter.ParameterType))); }
                        return(_method.MakeGenericMethod(method.GenericParameters.Select(k => k.Name.StartsWith("!!") ? that.GenericParameters[int.Parse(k.Name.Substring(2))] : (k.Name.StartsWith("!") ? that.DeclaringType.GenericParameters[int.Parse(k.Name.Substring(1))] : k)).ToArray()));
                    }
                    else
                    {
                        return(method.MakeGenericMethod(method.GenericParameters.Select(k => k.Name.StartsWith("!!") ? that.GenericParameters[int.Parse(k.Name.Substring(2))] : (k.Name.StartsWith("!") ? that.DeclaringType.GenericParameters[int.Parse(k.Name.Substring(1))] : k)).ToArray()));
                    }
                }
                else if (method is GenericInstanceMethod)
                {
                    var dec = that.GetRealType(method.DeclaringType);
                    if (dec is GenericInstanceType)
                    {
                        var _method = that.Module.Import(method.Resolve()).MakeHostInstanceGeneric((dec as GenericInstanceType).GenericArguments.ToArray());
                        //var _method = new MethodReference(method.Name, that.GetRealType(method.ReturnType), that.GetRealType(method.DeclaringType));
                        //foreach (var _parameter in method.Parameters) { _method.Parameters.Add(new ParameterDefinition(_parameter.Name, _parameter.Attributes, that.GetRealType(_parameter.ParameterType))); }
                        return(_method.MakeGenericMethod((method as GenericInstanceMethod).GenericArguments.Select(k => k.Name.StartsWith("!!") ? that.GenericParameters[int.Parse(k.Name.Substring(2))] : (k.Name.StartsWith("!") ? that.DeclaringType.GenericParameters[int.Parse(k.Name.Substring(1))] : k)).ToArray()));
                    }
                    else
                    {
                        return(method.MakeGenericMethod((method as GenericInstanceMethod).GenericArguments.Select(k => k.Name.StartsWith("!!") ? that.GenericParameters[int.Parse(k.Name.Substring(2))] : (k.Name.StartsWith("!") ? that.DeclaringType.GenericParameters[int.Parse(k.Name.Substring(1))] : k)).ToArray()));
                    }
                }
                else
                {
                    var dec = that.GetRealType(method.DeclaringType);
                    if (dec is GenericInstanceType)
                    {
                        var _method = that.Module.Import(method.Resolve()).MakeHostInstanceGeneric((dec as GenericInstanceType).GenericArguments.ToArray());
                        //var _method = new MethodReference(method.Name, that.GetRealType(method.ReturnType), that.GetRealType(method.DeclaringType));
                        //foreach (var _parameter in method.Parameters) { _method.Parameters.Add(new ParameterDefinition(_parameter.Name, _parameter.Attributes, that.GetRealType(_parameter.ParameterType))); }
                        return(_method);
                    }
                    else
                    {
                        return(method);
                    }
                }
            }
            //var met = method.Resolve();
            //if (met.GenericParameters.Count > 0)
            //{
            //    var kk = method.Module.Import(met).MakeGenericMethod(_types.Reverse().Take(met.GenericParameters.Count).Reverse().ToArray());
            //    if (met.DeclaringType.GenericParameters.Count > 0) { kk.DeclaringType = met.DeclaringType.MakeGenericType(_types.Take(met.DeclaringType.GenericParameters.Count)); }
            //    return kk;
            //}
            //if (met.DeclaringType.GenericParameters.Count > 0)
            //{
            //    var kk = method.Module.Import(met);
            //    kk.DeclaringType = met.DeclaringType.MakeGenericType(_types.Take(met.DeclaringType.GenericParameters.Count));
            //    return kk;
            //}
            return(method);
        }