/// <summary>
        /// <para>Try gets all members based on the search filters provided, and provides a proper error message if no members was found.</para>
        /// </summary>
        public bool TryGetMembers(out MemberInfo[] memberInfos, out string errorMessage)
        {
            try
            {
                //if (this.name == null && this.HasCondition(ConditionFlags.HasName))
                //{
                //    memberInfos = null;
                //    errorMessage = ""
                //}

                IEnumerable <MemberInfo> tmpMemberInfos = Enumerable.Empty <MemberInfo>();
                BindingFlags             bindingFlags   = this.HasCondition(ConditionFlags.IsDeclaredOnly) ? BindingFlags.DeclaredOnly : BindingFlags.FlattenHierarchy;

                bool hasNoParamaters = this.HasCondition(ConditionFlags.HasNoParamaters);
                bool isInstance      = this.HasCondition(ConditionFlags.IsInstance);
                bool isStatic        = this.HasCondition(ConditionFlags.IsStatic);
                bool isPublic        = this.HasCondition(ConditionFlags.IsPublic);
                bool isNonPublic     = this.HasCondition(ConditionFlags.IsNonPublic);
                bool isMethod        = this.HasCondition(ConditionFlags.IsMethod);
                bool isField         = this.HasCondition(ConditionFlags.IsField);
                bool isProperty      = this.HasCondition(ConditionFlags.IsProperty);

                if (!isPublic && !isNonPublic)
                {
                    isPublic    = true;
                    isNonPublic = true;
                }

                if (!isStatic && !isInstance)
                {
                    isStatic   = true;
                    isInstance = true;
                }

                if (!(isField || isProperty || isMethod))
                {
                    isMethod   = true;
                    isField    = true;
                    isProperty = true;
                }

                if (isInstance)
                {
                    bindingFlags |= BindingFlags.Instance;
                }
                if (isStatic)
                {
                    bindingFlags |= BindingFlags.Static;
                }
                if (isPublic)
                {
                    bindingFlags |= BindingFlags.Public;
                }
                if (isNonPublic)
                {
                    bindingFlags |= BindingFlags.NonPublic;
                }

                if (isMethod && isField && isProperty)
                {
                    if (this.name == null)
                    {
                        tmpMemberInfos = this.type.GetAllMembers(bindingFlags);
                    }
                    else
                    {
                        tmpMemberInfos = this.type.GetAllMembers(bindingFlags).Where(n => n.Name == this.name);
                    }

                    if (hasNoParamaters)
                    {
                        tmpMemberInfos = tmpMemberInfos.Where(x => x is MethodInfo == false || (x as MethodInfo).GetParameters().Length == 0);
                    }
                }
                else
                {
                    if (isMethod)
                    {
                        IEnumerable <MethodInfo> methodInfos = this.name == null?this.type.GetAllMembers <MethodInfo>(bindingFlags) : this.type.GetAllMembers <MethodInfo>(bindingFlags).Where(x => x.Name == name);

                        if (hasNoParamaters)
                        {
                            methodInfos = methodInfos.Where(x => x.GetParameters().Length == 0);
                        }
                        else if (this.paramTypes.Count > 0)
                        {
                            methodInfos = methodInfos.Where(x => x.HasParamaters(this.paramTypes));
                        }

                        tmpMemberInfos = methodInfos.OfType <MemberInfo>();
                    }

                    if (isField)
                    {
                        if (this.name == null)
                        {
                            tmpMemberInfos = tmpMemberInfos.Append(this.type.GetAllMembers <FieldInfo>(bindingFlags).Cast <MemberInfo>());
                        }
                        else
                        {
                            tmpMemberInfos = tmpMemberInfos.Append(this.type.GetAllMembers <FieldInfo>(bindingFlags).Where(n => n.Name == this.name).Cast <MemberInfo>());
                        }
                    }

                    if (isProperty)
                    {
                        if (this.name == null)
                        {
                            tmpMemberInfos = tmpMemberInfos.Append(this.type.GetAllMembers <PropertyInfo>(bindingFlags).Cast <MemberInfo>());
                        }
                        else
                        {
                            tmpMemberInfos = tmpMemberInfos.Append(this.type.GetAllMembers <PropertyInfo>(bindingFlags).Where(n => n.Name == this.name).Cast <MemberInfo>());
                        }
                    }
                }

                if (this.returnType != null)
                {
                    if (this.returnTypeCanInherit)
                    {
                        tmpMemberInfos = tmpMemberInfos.Where(x => x.GetReturnType().InheritsFrom(this.returnType));
                    }
                    else
                    {
                        tmpMemberInfos = tmpMemberInfos.Where(x => x.GetReturnType() == this.returnType);
                    }
                }

                memberInfos = tmpMemberInfos.ToArray();

                if (memberInfos != null && memberInfos.Length != 0)
                {
                    errorMessage = null;
                    return(true);
                }
                else
                {
                    MemberInfo namedMember = this.name == null ? null : this.type.GetMember(this.name, Flags.AllMembers).FirstOrDefault(t =>
                                                                                                                                        t is MethodInfo && isMethod ||
                                                                                                                                        t is FieldInfo && isField ||
                                                                                                                                        t is PropertyInfo && isProperty);

                    if (namedMember != null)
                    {
                        string accessModifies      = namedMember.IsStatic() ? "Static " : "Non-static ";
                        bool   noParamaterExpected = hasNoParamaters && namedMember is MethodInfo && (namedMember as MethodInfo).GetParameters().Length > 0;
                        if (noParamaterExpected)
                        {
                            errorMessage = accessModifies + "method " + this.name + " can not take parameters.";
                            return(false);
                        }

                        bool wrongParameters = isMethod && this.paramTypes.Count > 0 && namedMember is MethodInfo && (namedMember as MethodInfo).HasParamaters(this.paramTypes) == false;
                        if (wrongParameters)
                        {
                            errorMessage = accessModifies + "method " + this.name + " must have the following parameters: " + string.Join(", ", this.paramTypes.Select(x => x.GetNiceName()).ToArray()) + ".";
                            return(false);
                        }

                        bool wrongReturnType = this.returnType != null && this.returnType != namedMember.GetReturnType();
                        if (wrongReturnType)
                        {
                            if (this.returnTypeCanInherit)
                            {
                                errorMessage = accessModifies + namedMember.MemberType.ToString().ToLower(CultureInfo.InvariantCulture) + " " + this.name + " must have a return type that is assignable from " + this.returnType.GetNiceName() + ".";
                            }
                            else
                            {
                                errorMessage = accessModifies + namedMember.MemberType.ToString().ToLower(CultureInfo.InvariantCulture) + " " + this.name + " must have a return type of " + this.returnType.GetNiceName() + ".";
                            }
                            return(false);
                        }
                    }

                    int modCount = (isField ? 1 : 0) + (isProperty ? 1 : 0) + (isMethod ? 1 : 0);

                    string strMemberTypes = (isField ? ("fields" + (modCount-- > 1 ? (modCount == 1 ? " or " : ", ") : " ")) : string.Empty) +
                                            (isProperty ? ("properties" + (modCount-- > 1 ? (modCount == 1 ? " or " : ", ") : " ")) : string.Empty) +
                                            (isMethod ? ("methods" + (modCount-- > 1 ? (modCount == 1 ? " or " : ", ") : " ")) : string.Empty);

                    string strAccessModifiers = (isPublic != isNonPublic ? (isPublic ? "public " : "non-public ") : string.Empty) +
                                                (isStatic != isInstance ? (isStatic ? "static " : "non-static ") : string.Empty);

                    string strReturnType = this.returnType == null ? " " : ("with a return type of " + this.returnType.GetNiceName() + " ");

                    string strParameters = this.paramTypes.Count == 0 ? " " : (strReturnType == " " ? "" : "and ") + "with the parameter signature (" + string.Join(", ", this.paramTypes.Select(n => n.GetNiceName()).ToArray()) + ") ";

                    if (this.name == null)
                    {
                        errorMessage = "No " + strAccessModifiers + strMemberTypes + strReturnType + strParameters + "was found in " + this.type.GetNiceName() + ".";
                        return(false);
                    }
                    else
                    {
                        errorMessage = "No " + strAccessModifiers + strMemberTypes + "named " + this.name + " " + strReturnType + strParameters + "was found in " + this.type.GetNiceName() + ".";
                        return(false);
                    }
                }
            }
            finally
            {
                Cache <MemberFinder> .Release(this.cache);
            }
        }
        /// <summary>
        /// <para>Find members of the given type, while providing good error messages based on the following search filters provided.</para>
        /// </summary>
        public static MemberFinder Start <T>()
        {
            var cache = Cache <MemberFinder> .Claim();

            return(cache.Value.Start(typeof(T), cache));
        }
        /// <summary>
        /// <para>Find members of the given type, while providing good error messages based on the following search filters provided.</para>
        /// </summary>
        public static MemberFinder Start(Type type)
        {
            var cache = Cache <MemberFinder> .Claim();

            return(cache.Value.Start(type, cache));
        }