public IProperties GetProperties(ConcurrentDictionary <Type, int> seenTypes = null, int maxRecursion = 0)
        {
            var properties = new Properties();

            if (seenTypes != null && seenTypes.TryGetValue(_type, out var seen) && seen > maxRecursion)
            {
                return(properties);
            }

            foreach (var propertyInfo in _type.GetAllProperties())
            {
                var attribute = OpenSearchPropertyAttributeBase.From(propertyInfo);
                if (attribute != null && attribute.Ignore)
                {
                    continue;
                }
                if (_visitor.SkipProperty(propertyInfo, attribute))
                {
                    continue;
                }

                var property = GetProperty(propertyInfo, attribute);
                if (property is IPropertyWithClrOrigin withCLrOrigin)
                {
                    withCLrOrigin.ClrOrigin = propertyInfo;
                }
                properties.Add(propertyInfo, property);
            }

            return(properties);
        }
            private JsonProperty GetMapping(MemberInfo member)
            {
                // TODO: Skip calling this method for OSC and OpenSearch.Net types, at the type level
                if (!_settings.PropertyMappings.TryGetValue(member, out var propertyMapping))
                {
                    propertyMapping = OpenSearchPropertyAttributeBase.From(member);
                }

                var serializerMapping = _settings.PropertyMappingProvider?.CreatePropertyMapping(member);
                var nameOverride      = propertyMapping?.Name ?? serializerMapping?.Name;
                var property          = new JsonProperty(nameOverride);

                var overrideIgnore = propertyMapping?.Ignore ?? serializerMapping?.Ignore;

                if (overrideIgnore.HasValue)
                {
                    property.Ignore = overrideIgnore.Value;
                }

                if (propertyMapping != null || serializerMapping != null)
                {
                    property.AllowPrivate = true;
                }

                if (member.GetCustomAttribute <StringEnumAttribute>() != null)
                {
                    CreateEnumFormatterForProperty(member, property);
                }
                else if (member.GetCustomAttribute <StringTimeSpanAttribute>() != null)
                {
                    switch (member)
                    {
                    case PropertyInfo propertyInfo:
                        property.JsonFormatter =
                            BuiltinResolver.BuiltinResolverGetFormatterHelper.GetFormatter(propertyInfo.PropertyType);
                        break;

                    case FieldInfo fieldInfo:
                        property.JsonFormatter =
                            BuiltinResolver.BuiltinResolverGetFormatterHelper.GetFormatter(fieldInfo.FieldType);
                        break;
                    }
                }
                else if (member.GetCustomAttribute <EpochDateTimeAttribute>() != null)
                {
                    property.JsonFormatter = EpochDateTimeFormatter.Instance;
                }

                return(property);
            }