/// <summary>
        /// Builds a full URL search request including the object type, the query, and the fields to return.
        /// </summary>
        /// <param name="resourceType">An actual infoblox class type.</param>
        /// <param name="searchType">The type of search to be performed.</param>
        /// <param name="searchField">The field to search on.</param>
        /// <param name="recordValue">The value to search for.</param>
        /// <returns></returns>
        internal static string BuildGetSearchRequest(Type resourceType, SearchType searchType, string searchField, string recordValue, IEnumerable <string> fieldsToReturn)
        {
            if (resourceType == null)
            {
                throw new ArgumentNullException("resourceType", "The resource type to get cannot be null.");
            }

            if (String.IsNullOrEmpty(searchField))
            {
                throw new ArgumentNullException("searchField", "The field to search on cannot be null or empty.");
            }

            if (InfobloxSDKExtensionMethods.IsInfobloxType(resourceType))
            {
                if (fieldsToReturn != null && fieldsToReturn.Any())
                {
                    if (fieldsToReturn.Contains("ALL", StringComparer.OrdinalIgnoreCase))
                    {
                        fieldsToReturn = resourceType.GetTypeInfo().GetProperties().Where(x => !x.IsAttributeDefined <NotReadableAttribute>()).Select(x => x.Name);
                    }
                    else if (fieldsToReturn.Contains("BASIC", StringComparer.OrdinalIgnoreCase))
                    {
                        fieldsToReturn = resourceType.GetTypeInfo().GetProperties().Where(x => !x.IsAttributeDefined <NotReadableAttribute>()).Where(x => x.IsAttributeDefined <BasicAttribute>()).Select(x => x.Name);
                    }
                }
                else
                {
                    fieldsToReturn = resourceType.GetTypeInfo().GetProperties().Where(x => !x.IsAttributeDefined <NotReadableAttribute>()).Where(x => x.IsAttributeDefined <BasicAttribute>()).Select(x => x.Name);
                }

                string Fields = String.Join(",", RefObject.RemoveRefProperty(fieldsToReturn));

                MemberInfo[] Info = typeof(SearchType).GetTypeInfo().GetMember(searchType.ToString());

                if (Info != null && Info.Length > 0)
                {
                    string searchOperator = Info[0].GetCustomAttribute <DescriptionAttribute>().Description;

                    if (searchType.IsSearchTypeAllowed(resourceType, searchField))
                    {
                        return($"{resourceType.GetNameAttribute()}?{searchField.ToLower()}{searchOperator}{recordValue}&_return_fields%2B={Fields}");
                    }
                    else
                    {
                        throw new Exception($"The search type {searchType.ToString()} is not allowed on field {searchField}");
                    }
                }
                else
                {
                    throw new ArgumentException("Reflection evaluation on the search type object failed and no member info could be read.");
                }
            }
            else
            {
                throw new ArgumentException("The resource type must be an infoblox class.");
            }
        }
        /// <summary>
        /// This is called indirectly by a number of PowerShell cmdlets in order to cast an InputObject
        /// to the underlying .NET class. This is because when the returned value from a cmdlet is sent
        /// down the pipeline, it is converted to a PSObject, so we need to cast it back to the baseobject
        /// type.
        /// </summary>
        /// <typeparam name="T">The type of the Infoblox class underlying the PSObject</typeparam>
        /// <param name="value">The object passed in the pipeline</param>
        /// <returns>A converted object to the correct Infoblox class</returns>
        public static T ConvertPSObject <T>(this PSObject value)
        {
            if (value != null)
            {
                Type type = value.BaseObject.GetType();

                if (type == typeof(T) && InfobloxSDKExtensionMethods.IsInfobloxType(type))
                {
                    return((T)value.BaseObject);
                }
                else
                {
                    throw new PSArgumentException($"The PS Object must be a valid infoblox object type, {type.FullName} was provided.");
                }
            }
            else
            {
                throw new ArgumentNullException("value", "The PSObject cannot be null.");
            }
        }