/// <summary>
        /// Creates a list of <see cref="SearchField"/> objects corresponding to
        /// the properties of the type supplied.
        /// </summary>
        /// <param name="modelType">
        /// The type for which fields will be created, based on its properties.
        /// </param>
        /// <returns>A collection of fields.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="modelType"/>.</exception>
        public IList <SearchField> Build(Type modelType)
        {
            Argument.AssertNotNull(modelType, nameof(modelType));

            ArgumentException FailOnNonObjectDataType()
            {
                string errorMessage =
                    $"Type '{modelType}' does not have properties which map to fields of an Azure Search index. Please use a " +
                    "class or struct with public properties.";

                throw new ArgumentException(errorMessage, nameof(modelType));
            }

            Serializer ??= new JsonObjectSerializer();
            IMemberNameConverter nameProvider = Serializer as IMemberNameConverter ?? DefaultSerializedNameProvider.Shared;

            if (ObjectInfo.TryGet(modelType, nameProvider, out ObjectInfo info))
            {
                if (info.Properties.Length == 0)
                {
                    throw FailOnNonObjectDataType();
                }

                // Use Stack to avoid a dependency on ImmutableStack for now.
                return(Build(modelType, info, nameProvider, new Stack <Type>(new[] { modelType })));
            }

            throw FailOnNonObjectDataType();
        }
        public void ConvertMemberName()
        {
            IEnumerable <MemberInfo> members = typeof(ExtendedModel)
                                               .GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                                               .Where(member => (member.MemberType & (MemberTypes.Property | MemberTypes.Field)) != 0);

            IMemberNameConverter converter = _jsonObjectSerializer;

            foreach (MemberInfo member in members)
            {
                string propertyName = converter.ConvertMemberName(member);

                // The following should be null for any property that does not serialized (compare to assertions above).
                switch (member.Name)
                {
                case nameof(ExtendedModel.A):
                    Assert.AreEqual(SerializedName("A"), propertyName);
                    break;

                case nameof(ExtendedModel.B):
                    Assert.AreEqual(SerializedName("B"), propertyName);
                    break;

                case nameof(ExtendedModel.ReadOnlyD):
                    Assert.AreEqual("d", propertyName);
                    break;

                default:
                    Assert.IsNull(propertyName, $"Unexpected serialized name '{propertyName}' for member {member.DeclaringType}.{member.Name}");
                    break;
                }
            }
        }
 private static IList <SearchField> Build(
     Type modelType,
     ObjectInfo info,
     IMemberNameConverter nameProvider,
     Stack <Type> processedTypes)
 {
     SearchField BuildField(ObjectPropertyInfo prop)
     {