public SerializerMetadata GetSerializerMetadataForType(Type type)
        {
            var underlyingType = type.IsNullable(out Type innerType) ? innerType : type;

            if (PrimitiveTypesAndFormats.ContainsKey(underlyingType))
            {
                var primitiveTypeAndFormat = PrimitiveTypesAndFormats[underlyingType];
                return(SerializerMetadata.ForPrimitive(underlyingType, primitiveTypeAndFormat.Item1, primitiveTypeAndFormat.Item2));
            }

            if (underlyingType.IsEnum)
            {
                var enumValues = GetSerializeEnumValuesFor(underlyingType);

                var primitiveTypeAndFormat = (enumValues.Any(value => value.GetType() == typeof(string)))
                    ? PrimitiveTypesAndFormats[typeof(string)]
                    : PrimitiveTypesAndFormats[underlyingType.GetEnumUnderlyingType()];

                return(SerializerMetadata.ForPrimitive(underlyingType, primitiveTypeAndFormat.Item1, primitiveTypeAndFormat.Item2, enumValues));
            }

            if (underlyingType.IsDictionary(out Type keyType, out Type valueType))
            {
                return(SerializerMetadata.ForDictionary(underlyingType, keyType, valueType));
            }

            if (underlyingType.IsEnumerable(out Type itemType))
            {
                return(SerializerMetadata.ForArray(underlyingType, itemType));
            }

            return(SerializerMetadata.ForObject(
                       underlyingType,
                       GetSerializerPropertiesFor(underlyingType, out Type extensionDataValueType),
                       extensionDataValueType));
        }