private MethodInfo GetOriginalMethod(Type T, string MethodName, bool SearchOnlyInGeneric, bool Strict, bool UsePotential, out Dictionary <string, string> GenericMap, params string[] TypeName)
    {
        Func <string, string, bool> CheckCaseSensitive; Func <string, string, bool> Check; Func <MethodInfo, bool> CheckParams;

        string[] typeName; string methodName; MethodInfo[] methods; MethodInfo Result;
        if (SearchOnlyInGeneric)
        {
            methods = T.GetMethods().Where(S => S.ContainsGenericParameters).ToArray();
        }
        else
        {
            methods = T.GetMethods();
        }
        if (Strict)
        {
            methodName         = MethodName; typeName = TypeName;
            CheckCaseSensitive = (ParamName, CheckName) => ParamName == CheckName;
            Check = (ParamName, CheckName) => ParamName != CheckName;
        }
        else
        {
            methodName         = MethodName.ToUpper(); typeName = TypeName.Select(x => x.ToUpper()).ToArray();
            CheckCaseSensitive = (ParamName, CheckName) =>
                                 ParamName.ToUpper() == CheckName;
            Check = (ParamName, CheckName) =>
                    !ParamName.ToUpper().Contains(CheckName);
        }
        Dictionary <string, string> GM = null;

        if (UsePotential)
        {
            CheckParams = M =>
                          Similar(M, Strict, ref GM, typeName);
        }
        else
        {
            CheckParams = M =>
                          M.GetParameters().Where((P, i) => Check(P.ParameterType.FullName, typeName[i])).FirstOrDefault() == null;
        }
        Result = methods.Select(M => new { Method = M, Prs = M.GetParameters() }).Where(M => (
                                                                                            (CheckCaseSensitive(M.Method.Name, methodName)) &&
                                                                                            (M.Prs.Length == typeName.Length) &&
                                                                                            CheckParams(M.Method)
                                                                                            )).Select(M => M.Method).FirstOrDefault();
        GenericMap = GM;
        return(Result);
    }
    private bool Similar(MethodInfo method, bool Strict, ref Dictionary <string, string> GenericMap, params string[] TypeName)
    {
        Func <string, string> NoStrict = ParamName =>
        {
            string S = ParamName.ToUpper();
            foreach (var C in CH)
            {
                S = S.Replace(C.Key, C.Value);
            }
            // Replace("SYSTEM.COLLECTIONS.GENERIC.", "").Replace("SYSTEM.", "").Replace("`1[", "[").Replace("`2[", "[")
            return(S);
        };
        Func <string, string> CheckStrict = ParamName => Strict ? ParamName : NoStrict(ParamName);

        string[] Name = method.GetParameters().Select(x => CheckStrict(x.ParameterType.ToString())).ToArray();
        int      L = Name.Length; bool Result = false;

        if (L == TypeName.Length)
        {
            Dictionary <string, string> GenericName =
                (Dictionary <string, string>)method.GetGenericArguments().Select(x => x.ToString()).ToDictionary(x => Strict ? x : x.ToUpper(), x => string.Empty);
            string[] typeName;
            if (Strict)
            {
                typeName = TypeName;
            }
            else
            {
                typeName = TypeName.Select(x => NoStrict(x)).ToArray();
            }

            Func <string, string, bool> SameText = ((NameType, NameGeneric) =>
            {
                if (Strict)
                {
                    return(NameType == NameGeneric);
                }
                return(NameGeneric.Contains(NameType));
            });
            Func <string, string, bool> PossibleTranslateInGeneric = ((NameType, NameGeneric) =>
            {
                if (!GenericName.ContainsKey(NameGeneric))
                {
                    return(false);
                }
                string TT = GenericName[NameGeneric];
                if (TT == NameType)
                {
                    return(true);
                }
                else if (TT == string.Empty)
                {
                    GenericName[NameGeneric] = NameType; return(true);
                }
                else
                {
                    return(false);
                }
            });
            Func <string, string> DT3 = (NameGenericMod =>
            {
                GenericName.Select(x => x.Key).ToList().ForEach(y =>
                {
                    NameGenericMod = NameGenericMod.Replace(y + ",", GenericName[y] + ",");
                });
                return(NameGenericMod);
            });
            Result = typeName.Select((t, i) => new
            {
                ParamsType = SimpleTypes(t),
                ParamsGen  = SimpleTypes(Name[i])
            }).Where(t => (
                         (t.ParamsType.Length != t.ParamsGen.Length) ||
                         !(t.ParamsType.Where((x, i) => (!(SameText(x, t.ParamsGen[i]) ||
                                                           PossibleTranslateInGeneric(x, t.ParamsGen[i])))).FirstOrDefault() == null)
                         //|| (t.s1 != DT3(t.s2))
                         )).FirstOrDefault() == null;
            if (Result)
            {
                if (Strict)
                {
                    GenericMap = GenericName;
                }
                else
                {
                    GenericMap = method.GetGenericArguments().ToDictionary(x => x.ToString(), x => string.Empty);
                    for (int i = 0; i < GenericMap.Count; i++)
                    {
                        GenericMap[GenericMap.ElementAt(i).Key] = this.GetFullNameClass(GenericName[GenericName.ElementAt(i).Key]);
                    }
                }
            }
        }
        return(Result);
    }