
com.cedarsoftware.util.convert.Converter Maven / Gradle / Ivy
package com.cedarsoftware.util.convert;
import java.io.Externalizable;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.sql.Timestamp;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.MonthDay;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Period;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Comparator;
import java.util.Collections;
import java.util.Currency;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;
import com.cedarsoftware.util.ClassUtilities;
import com.cedarsoftware.util.ClassValueMap;
/**
* Instance conversion utility for converting objects between various types.
*
* Supports conversion from primitive types to their corresponding wrapper classes, Number classes,
* Date and Time classes (e.g., {@link Date}, {@link Timestamp}, {@link LocalDate}, {@link LocalDateTime},
* {@link ZonedDateTime}, {@link Calendar}), {@link BigInteger}, {@link BigDecimal}, Atomic classes
* (e.g., {@link AtomicBoolean}, {@link AtomicInteger}, {@link AtomicLong}), {@link Class}, {@link UUID},
* {@link String}, Collection classes (e.g., {@link List}, {@link Set}, {@link Map}), ByteBuffer, CharBuffer,
* and other related classes.
*
*
* The Converter includes thousands of built-in conversions. Use the {@link #getSupportedConversions()}
* API to view all source-to-target conversion mappings.
*
*
* The primary API is {@link #convert(Object, Class)}. For example:
*
{@code
* Long x = convert("35", Long.class);
* Date d = convert("2015/01/01", Date.class);
* int y = convert(45.0, int.class);
* String dateStr = convert(date, String.class);
* String dateStr = convert(calendar, String.class);
* Short t = convert(true, short.class); // returns (short) 1 or 0
* Long time = convert(calendar, long.class); // retrieves calendar's time as long
* Map map = Map.of("_v", "75.0");
* Double value = convert(map, double.class); // Extracts "_v" key and converts it
* }
*
*
* Null Handling: If a null value is passed as the source, the Converter returns:
*
* - null for object types
* - 0 for numeric primitive types
* - false for boolean primitives
* - '\u0000' for char primitives
*
*
*
* Map Conversions: A {@code Map} can be converted to almost all supported JDK data classes.
* For example, {@link UUID} can be converted to/from a {@code Map} with keys like "mostSigBits" and "leastSigBits".
* Date/Time classes expect specific keys such as "time" or "nanos". For other classes, the Converter typically
* looks for a "value" key to source the conversion.
*
*
* Extensibility: Additional conversions can be added by specifying the source class, target class,
* and a conversion function (e.g., a lambda). Use the {@link #addConversion(Class, Class, Convert)} method to register
* custom converters. This allows for the inclusion of new Collection types and other custom types as needed.
*
*
*
* Supported Collection Conversions:
* The Converter supports conversions involving various Collection types, including but not limited to:
*
* - {@link List}
* - {@link Set}
* - {@link Map}
* - {@link Collection}
* - Arrays (e.g., {@code byte[]}, {@code char[]}, {@code ByteBuffer}, {@code CharBuffer})
*
* These conversions facilitate seamless transformation between different Collection types and other supported classes.
*
*
*
* Usage Example:
*
{@code
* ConverterOptions options = new ConverterOptions();
* Converter converter = new Converter(options);
*
* // Convert String to Integer
* Integer number = converter.convert("123", Integer.class);
*
* // Convert Enum to String
* Day day = Day.MONDAY;
* String dayStr = converter.convert(day, String.class);
*
* // Convert Object[], String[], Collection, and primitive Arrays to EnumSet
* Object[] array = {Day.MONDAY, Day.WEDNESDAY, "FRIDAY", 4};
* EnumSet daySet = (EnumSet)(Object)converter.convert(array, Day.class);
*
* Enum, String, and Number value in the source collection/array is properly converted
* to the correct Enum type and added to the returned EnumSet. Null values inside the
* source (Object[], Collection) are skipped.
*
* When converting arrays or collections to EnumSet, you must use a double cast due to Java's
* type system and generic type erasure. The cast is safe as the converter guarantees return of
* an EnumSet when converting arrays/collections to enum types.
*
* // Add a custom conversion from String to CustomType
* converter.addConversion(String.class, CustomType.class, (from, conv) -> new CustomType(from));
*
* // Convert using the custom converter
* CustomType custom = converter.convert("customValue", CustomType.class);
* }
*
*
* @author John DeRegnaucourt ([email protected])
* Copyright (c) Cedar Software LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* License
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public final class Converter {
private static final Convert> UNSUPPORTED = Converter::unsupported;
static final String VALUE = "_v";
private static final Map, SortedSet> cacheParentTypes = new ClassValueMap<>();
private static Map> CONVERSION_DB = new HashMap<>(860, 0.8f);
private static final Map> USER_DB = new ConcurrentHashMap<>();
private static final ClassValueMap>> FULL_CONVERSION_CACHE = new ClassValueMap<>();
private static final Map, String> CUSTOM_ARRAY_NAMES = new ClassValueMap<>();
private static final ClassValueMap SIMPLE_TYPE_CACHE = new ClassValueMap<>();
private static final ClassValueMap SELF_CONVERSION_CACHE = new ClassValueMap<>();
private final ConverterOptions options;
// Efficient key that combines two Class instances for fast creation and lookup
public static final class ConversionPair {
private final Class> source;
private final Class> target;
private final int hash;
private ConversionPair(Class> source, Class> target) {
this.source = source;
this.target = target;
this.hash = 31 * source.hashCode() + target.hashCode();
}
public Class> getSource() { // Added getter
return source;
}
public Class> getTarget() { // Added getter
return target;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ConversionPair)) return false;
ConversionPair other = (ConversionPair) obj;
return source == other.source && target == other.target;
}
@Override
public int hashCode() {
return hash;
}
}
// Helper method to get or create a cached key
public static ConversionPair pair(Class> source, Class> target) {
return new ConversionPair(source, target);
}
static {
CUSTOM_ARRAY_NAMES.put(java.sql.Date[].class, "java.sql.Date[]");
buildFactoryConversions();
CONVERSION_DB = Collections.unmodifiableMap(CONVERSION_DB);
}
/**
* Retrieves the converter options associated with this Converter instance.
*
* @return The {@link ConverterOptions} used by this Converter.
*/
public ConverterOptions getOptions() {
return options;
}
/**
* Initializes the built-in conversion mappings within the Converter.
*
* This method populates the {@link #CONVERSION_DB} with a comprehensive set of predefined conversion functions
* that handle a wide range of type transformations, including primitives, wrappers, numbers, dates, times,
* collections, and more.
*
*
* These conversions serve as the foundational capabilities of the Converter, enabling it to perform most
* common type transformations out-of-the-box. Users can extend or override these conversions using the
* {@link #addConversion(Class, Class, Convert)} method as needed.
*
*/
private static void buildFactoryConversions() {
// toNumber
CONVERSION_DB.put(pair(Byte.class, Number.class), Converter::identity);
CONVERSION_DB.put(pair(Short.class, Number.class), Converter::identity);
CONVERSION_DB.put(pair(Integer.class, Number.class), Converter::identity);
CONVERSION_DB.put(pair(Long.class, Number.class), Converter::identity);
CONVERSION_DB.put(pair(Float.class, Number.class), Converter::identity);
CONVERSION_DB.put(pair(Double.class, Number.class), Converter::identity);
CONVERSION_DB.put(pair(AtomicInteger.class, Number.class), Converter::identity);
CONVERSION_DB.put(pair(AtomicLong.class, Number.class), Converter::identity);
CONVERSION_DB.put(pair(BigInteger.class, Number.class), Converter::identity);
CONVERSION_DB.put(pair(BigDecimal.class, Number.class), Converter::identity);
// toByte
CONVERSION_DB.put(pair(Void.class, byte.class), NumberConversions::toByteZero);
CONVERSION_DB.put(pair(Void.class, Byte.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, Byte.class), Converter::identity);
CONVERSION_DB.put(pair(Short.class, Byte.class), NumberConversions::toByte);
CONVERSION_DB.put(pair(Integer.class, Byte.class), NumberConversions::toByte);
CONVERSION_DB.put(pair(Long.class, Byte.class), NumberConversions::toByte);
CONVERSION_DB.put(pair(Float.class, Byte.class), NumberConversions::toByte);
CONVERSION_DB.put(pair(Double.class, Byte.class), NumberConversions::toByte);
CONVERSION_DB.put(pair(Boolean.class, Byte.class), BooleanConversions::toByte);
CONVERSION_DB.put(pair(Character.class, Byte.class), CharacterConversions::toByte);
CONVERSION_DB.put(pair(AtomicBoolean.class, Byte.class), AtomicBooleanConversions::toByte);
CONVERSION_DB.put(pair(AtomicInteger.class, Byte.class), NumberConversions::toByte);
CONVERSION_DB.put(pair(AtomicLong.class, Byte.class), NumberConversions::toByte);
CONVERSION_DB.put(pair(BigInteger.class, Byte.class), NumberConversions::toByte);
CONVERSION_DB.put(pair(BigDecimal.class, Byte.class), NumberConversions::toByte);
CONVERSION_DB.put(pair(Map.class, Byte.class), MapConversions::toByte);
CONVERSION_DB.put(pair(String.class, Byte.class), StringConversions::toByte);
// toShort
CONVERSION_DB.put(pair(Void.class, short.class), NumberConversions::toShortZero);
CONVERSION_DB.put(pair(Void.class, Short.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, Short.class), NumberConversions::toShort);
CONVERSION_DB.put(pair(Short.class, Short.class), Converter::identity);
CONVERSION_DB.put(pair(Integer.class, Short.class), NumberConversions::toShort);
CONVERSION_DB.put(pair(Long.class, Short.class), NumberConversions::toShort);
CONVERSION_DB.put(pair(Float.class, Short.class), NumberConversions::toShort);
CONVERSION_DB.put(pair(Double.class, Short.class), NumberConversions::toShort);
CONVERSION_DB.put(pair(Boolean.class, Short.class), BooleanConversions::toShort);
CONVERSION_DB.put(pair(Character.class, Short.class), CharacterConversions::toShort);
CONVERSION_DB.put(pair(AtomicBoolean.class, Short.class), AtomicBooleanConversions::toShort);
CONVERSION_DB.put(pair(AtomicInteger.class, Short.class), NumberConversions::toShort);
CONVERSION_DB.put(pair(AtomicLong.class, Short.class), NumberConversions::toShort);
CONVERSION_DB.put(pair(BigInteger.class, Short.class), NumberConversions::toShort);
CONVERSION_DB.put(pair(BigDecimal.class, Short.class), NumberConversions::toShort);
CONVERSION_DB.put(pair(Map.class, Short.class), MapConversions::toShort);
CONVERSION_DB.put(pair(String.class, Short.class), StringConversions::toShort);
CONVERSION_DB.put(pair(Year.class, Short.class), YearConversions::toShort);
// toInteger
CONVERSION_DB.put(pair(Void.class, int.class), NumberConversions::toIntZero);
CONVERSION_DB.put(pair(Void.class, Integer.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, Integer.class), NumberConversions::toInt);
CONVERSION_DB.put(pair(Short.class, Integer.class), NumberConversions::toInt);
CONVERSION_DB.put(pair(Integer.class, Integer.class), Converter::identity);
CONVERSION_DB.put(pair(Long.class, Integer.class), NumberConversions::toInt);
CONVERSION_DB.put(pair(Float.class, Integer.class), NumberConversions::toInt);
CONVERSION_DB.put(pair(Double.class, Integer.class), NumberConversions::toInt);
CONVERSION_DB.put(pair(Boolean.class, Integer.class), BooleanConversions::toInt);
CONVERSION_DB.put(pair(Character.class, Integer.class), CharacterConversions::toInt);
CONVERSION_DB.put(pair(AtomicBoolean.class, Integer.class), AtomicBooleanConversions::toInt);
CONVERSION_DB.put(pair(AtomicInteger.class, Integer.class), NumberConversions::toInt);
CONVERSION_DB.put(pair(AtomicLong.class, Integer.class), NumberConversions::toInt);
CONVERSION_DB.put(pair(BigInteger.class, Integer.class), NumberConversions::toInt);
CONVERSION_DB.put(pair(BigDecimal.class, Integer.class), NumberConversions::toInt);
CONVERSION_DB.put(pair(Map.class, Integer.class), MapConversions::toInt);
CONVERSION_DB.put(pair(String.class, Integer.class), StringConversions::toInt);
CONVERSION_DB.put(pair(LocalTime.class, Integer.class), LocalTimeConversions::toInteger);
CONVERSION_DB.put(pair(OffsetTime.class, Integer.class), OffsetTimeConversions::toInteger);
CONVERSION_DB.put(pair(Year.class, Integer.class), YearConversions::toInt);
// toLong
CONVERSION_DB.put(pair(Void.class, long.class), NumberConversions::toLongZero);
CONVERSION_DB.put(pair(Void.class, Long.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, Long.class), NumberConversions::toLong);
CONVERSION_DB.put(pair(Short.class, Long.class), NumberConversions::toLong);
CONVERSION_DB.put(pair(Integer.class, Long.class), NumberConversions::toLong);
CONVERSION_DB.put(pair(Long.class, Long.class), Converter::identity);
CONVERSION_DB.put(pair(Float.class, Long.class), NumberConversions::toLong);
CONVERSION_DB.put(pair(Double.class, Long.class), NumberConversions::toLong);
CONVERSION_DB.put(pair(Boolean.class, Long.class), BooleanConversions::toLong);
CONVERSION_DB.put(pair(Character.class, Long.class), CharacterConversions::toLong);
CONVERSION_DB.put(pair(AtomicBoolean.class, Long.class), AtomicBooleanConversions::toLong);
CONVERSION_DB.put(pair(AtomicInteger.class, Long.class), NumberConversions::toLong);
CONVERSION_DB.put(pair(AtomicLong.class, Long.class), NumberConversions::toLong);
CONVERSION_DB.put(pair(BigInteger.class, Long.class), NumberConversions::toLong);
CONVERSION_DB.put(pair(BigDecimal.class, Long.class), NumberConversions::toLong);
CONVERSION_DB.put(pair(Date.class, Long.class), DateConversions::toLong);
CONVERSION_DB.put(pair(java.sql.Date.class, Long.class), SqlDateConversions::toLong);
CONVERSION_DB.put(pair(Timestamp.class, Long.class), TimestampConversions::toLong);
CONVERSION_DB.put(pair(Instant.class, Long.class), InstantConversions::toLong);
CONVERSION_DB.put(pair(Duration.class, Long.class), DurationConversions::toLong);
CONVERSION_DB.put(pair(LocalDate.class, Long.class), LocalDateConversions::toLong);
CONVERSION_DB.put(pair(LocalTime.class, Long.class), LocalTimeConversions::toLong);
CONVERSION_DB.put(pair(LocalDateTime.class, Long.class), LocalDateTimeConversions::toLong);
CONVERSION_DB.put(pair(OffsetTime.class, Long.class), OffsetTimeConversions::toLong);
CONVERSION_DB.put(pair(OffsetDateTime.class, Long.class), OffsetDateTimeConversions::toLong);
CONVERSION_DB.put(pair(ZonedDateTime.class, Long.class), ZonedDateTimeConversions::toLong);
CONVERSION_DB.put(pair(Calendar.class, Long.class), CalendarConversions::toLong);
CONVERSION_DB.put(pair(Map.class, Long.class), MapConversions::toLong);
CONVERSION_DB.put(pair(String.class, Long.class), StringConversions::toLong);
CONVERSION_DB.put(pair(Year.class, Long.class), YearConversions::toLong);
// toFloat
CONVERSION_DB.put(pair(Void.class, float.class), NumberConversions::toFloatZero);
CONVERSION_DB.put(pair(Void.class, Float.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, Float.class), NumberConversions::toFloat);
CONVERSION_DB.put(pair(Short.class, Float.class), NumberConversions::toFloat);
CONVERSION_DB.put(pair(Integer.class, Float.class), NumberConversions::toFloat);
CONVERSION_DB.put(pair(Long.class, Float.class), NumberConversions::toFloat);
CONVERSION_DB.put(pair(Float.class, Float.class), Converter::identity);
CONVERSION_DB.put(pair(Double.class, Float.class), NumberConversions::toFloat);
CONVERSION_DB.put(pair(Boolean.class, Float.class), BooleanConversions::toFloat);
CONVERSION_DB.put(pair(Character.class, Float.class), CharacterConversions::toFloat);
CONVERSION_DB.put(pair(AtomicBoolean.class, Float.class), AtomicBooleanConversions::toFloat);
CONVERSION_DB.put(pair(AtomicInteger.class, Float.class), NumberConversions::toFloat);
CONVERSION_DB.put(pair(AtomicLong.class, Float.class), NumberConversions::toFloat);
CONVERSION_DB.put(pair(BigInteger.class, Float.class), NumberConversions::toFloat);
CONVERSION_DB.put(pair(BigDecimal.class, Float.class), NumberConversions::toFloat);
CONVERSION_DB.put(pair(Map.class, Float.class), MapConversions::toFloat);
CONVERSION_DB.put(pair(String.class, Float.class), StringConversions::toFloat);
CONVERSION_DB.put(pair(Year.class, Float.class), YearConversions::toFloat);
// toDouble
CONVERSION_DB.put(pair(Void.class, double.class), NumberConversions::toDoubleZero);
CONVERSION_DB.put(pair(Void.class, Double.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, Double.class), NumberConversions::toDouble);
CONVERSION_DB.put(pair(Short.class, Double.class), NumberConversions::toDouble);
CONVERSION_DB.put(pair(Integer.class, Double.class), NumberConversions::toDouble);
CONVERSION_DB.put(pair(Long.class, Double.class), NumberConversions::toDouble);
CONVERSION_DB.put(pair(Float.class, Double.class), NumberConversions::toDouble);
CONVERSION_DB.put(pair(Double.class, Double.class), Converter::identity);
CONVERSION_DB.put(pair(Boolean.class, Double.class), BooleanConversions::toDouble);
CONVERSION_DB.put(pair(Character.class, Double.class), CharacterConversions::toDouble);
CONVERSION_DB.put(pair(Duration.class, Double.class), DurationConversions::toDouble);
CONVERSION_DB.put(pair(Instant.class, Double.class), InstantConversions::toDouble);
CONVERSION_DB.put(pair(LocalTime.class, Double.class), LocalTimeConversions::toDouble);
CONVERSION_DB.put(pair(LocalDate.class, Double.class), LocalDateConversions::toDouble);
CONVERSION_DB.put(pair(LocalDateTime.class, Double.class), LocalDateTimeConversions::toDouble);
CONVERSION_DB.put(pair(ZonedDateTime.class, Double.class), ZonedDateTimeConversions::toDouble);
CONVERSION_DB.put(pair(OffsetTime.class, Double.class), OffsetTimeConversions::toDouble);
CONVERSION_DB.put(pair(OffsetDateTime.class, Double.class), OffsetDateTimeConversions::toDouble);
CONVERSION_DB.put(pair(Date.class, Double.class), DateConversions::toDouble);
CONVERSION_DB.put(pair(java.sql.Date.class, Double.class), SqlDateConversions::toDouble);
CONVERSION_DB.put(pair(Timestamp.class, Double.class), TimestampConversions::toDouble);
CONVERSION_DB.put(pair(AtomicBoolean.class, Double.class), AtomicBooleanConversions::toDouble);
CONVERSION_DB.put(pair(AtomicInteger.class, Double.class), NumberConversions::toDouble);
CONVERSION_DB.put(pair(AtomicLong.class, Double.class), NumberConversions::toDouble);
CONVERSION_DB.put(pair(BigInteger.class, Double.class), NumberConversions::toDouble);
CONVERSION_DB.put(pair(BigDecimal.class, Double.class), NumberConversions::toDouble);
CONVERSION_DB.put(pair(Calendar.class, Double.class), CalendarConversions::toDouble);
CONVERSION_DB.put(pair(Map.class, Double.class), MapConversions::toDouble);
CONVERSION_DB.put(pair(String.class, Double.class), StringConversions::toDouble);
CONVERSION_DB.put(pair(Year.class, Double.class), YearConversions::toDouble);
// Boolean/boolean conversions supported
CONVERSION_DB.put(pair(Void.class, boolean.class), VoidConversions::toBoolean);
CONVERSION_DB.put(pair(Void.class, Boolean.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, Boolean.class), NumberConversions::isIntTypeNotZero);
CONVERSION_DB.put(pair(Short.class, Boolean.class), NumberConversions::isIntTypeNotZero);
CONVERSION_DB.put(pair(Integer.class, Boolean.class), NumberConversions::isIntTypeNotZero);
CONVERSION_DB.put(pair(Long.class, Boolean.class), NumberConversions::isIntTypeNotZero);
CONVERSION_DB.put(pair(Float.class, Boolean.class), NumberConversions::isFloatTypeNotZero);
CONVERSION_DB.put(pair(Double.class, Boolean.class), NumberConversions::isFloatTypeNotZero);
CONVERSION_DB.put(pair(Boolean.class, Boolean.class), Converter::identity);
CONVERSION_DB.put(pair(Character.class, Boolean.class), CharacterConversions::toBoolean);
CONVERSION_DB.put(pair(AtomicBoolean.class, Boolean.class), AtomicBooleanConversions::toBoolean);
CONVERSION_DB.put(pair(AtomicInteger.class, Boolean.class), NumberConversions::isIntTypeNotZero);
CONVERSION_DB.put(pair(AtomicLong.class, Boolean.class), NumberConversions::isIntTypeNotZero);
CONVERSION_DB.put(pair(BigInteger.class, Boolean.class), NumberConversions::isBigIntegerNotZero);
CONVERSION_DB.put(pair(BigDecimal.class, Boolean.class), NumberConversions::isBigDecimalNotZero);
CONVERSION_DB.put(pair(Map.class, Boolean.class), MapConversions::toBoolean);
CONVERSION_DB.put(pair(String.class, Boolean.class), StringConversions::toBoolean);
// Character/char conversions supported
CONVERSION_DB.put(pair(Void.class, char.class), VoidConversions::toCharacter);
CONVERSION_DB.put(pair(Void.class, Character.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, Character.class), ByteConversions::toCharacter);
CONVERSION_DB.put(pair(Short.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(Integer.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(Long.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(Float.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(Double.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(Boolean.class, Character.class), BooleanConversions::toCharacter);
CONVERSION_DB.put(pair(Character.class, Character.class), Converter::identity);
CONVERSION_DB.put(pair(AtomicBoolean.class, Character.class), AtomicBooleanConversions::toCharacter);
CONVERSION_DB.put(pair(AtomicInteger.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(AtomicLong.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(BigInteger.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(BigDecimal.class, Character.class), NumberConversions::toCharacter);
CONVERSION_DB.put(pair(Map.class, Character.class), MapConversions::toCharacter);
CONVERSION_DB.put(pair(String.class, Character.class), StringConversions::toCharacter);
// BigInteger versions supported
CONVERSION_DB.put(pair(Void.class, BigInteger.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, BigInteger.class), NumberConversions::integerTypeToBigInteger);
CONVERSION_DB.put(pair(Short.class, BigInteger.class), NumberConversions::integerTypeToBigInteger);
CONVERSION_DB.put(pair(Integer.class, BigInteger.class), NumberConversions::integerTypeToBigInteger);
CONVERSION_DB.put(pair(Long.class, BigInteger.class), NumberConversions::integerTypeToBigInteger);
CONVERSION_DB.put(pair(Float.class, BigInteger.class), NumberConversions::floatingPointToBigInteger);
CONVERSION_DB.put(pair(Double.class, BigInteger.class), NumberConversions::floatingPointToBigInteger);
CONVERSION_DB.put(pair(Boolean.class, BigInteger.class), BooleanConversions::toBigInteger);
CONVERSION_DB.put(pair(Character.class, BigInteger.class), CharacterConversions::toBigInteger);
CONVERSION_DB.put(pair(BigInteger.class, BigInteger.class), Converter::identity);
CONVERSION_DB.put(pair(BigDecimal.class, BigInteger.class), BigDecimalConversions::toBigInteger);
CONVERSION_DB.put(pair(AtomicBoolean.class, BigInteger.class), AtomicBooleanConversions::toBigInteger);
CONVERSION_DB.put(pair(AtomicInteger.class, BigInteger.class), NumberConversions::integerTypeToBigInteger);
CONVERSION_DB.put(pair(AtomicLong.class, BigInteger.class), NumberConversions::integerTypeToBigInteger);
CONVERSION_DB.put(pair(Date.class, BigInteger.class), DateConversions::toBigInteger);
CONVERSION_DB.put(pair(java.sql.Date.class, BigInteger.class), SqlDateConversions::toBigInteger);
CONVERSION_DB.put(pair(Timestamp.class, BigInteger.class), TimestampConversions::toBigInteger);
CONVERSION_DB.put(pair(Duration.class, BigInteger.class), DurationConversions::toBigInteger);
CONVERSION_DB.put(pair(Instant.class, BigInteger.class), InstantConversions::toBigInteger);
CONVERSION_DB.put(pair(LocalTime.class, BigInteger.class), LocalTimeConversions::toBigInteger);
CONVERSION_DB.put(pair(LocalDate.class, BigInteger.class), LocalDateConversions::toBigInteger);
CONVERSION_DB.put(pair(LocalDateTime.class, BigInteger.class), LocalDateTimeConversions::toBigInteger);
CONVERSION_DB.put(pair(ZonedDateTime.class, BigInteger.class), ZonedDateTimeConversions::toBigInteger);
CONVERSION_DB.put(pair(OffsetTime.class, BigInteger.class), OffsetTimeConversions::toBigInteger);
CONVERSION_DB.put(pair(OffsetDateTime.class, BigInteger.class), OffsetDateTimeConversions::toBigInteger);
CONVERSION_DB.put(pair(UUID.class, BigInteger.class), UUIDConversions::toBigInteger);
CONVERSION_DB.put(pair(Calendar.class, BigInteger.class), CalendarConversions::toBigInteger);
CONVERSION_DB.put(pair(Map.class, BigInteger.class), MapConversions::toBigInteger);
CONVERSION_DB.put(pair(String.class, BigInteger.class), StringConversions::toBigInteger);
CONVERSION_DB.put(pair(Year.class, BigInteger.class), YearConversions::toBigInteger);
// BigDecimal conversions supported
CONVERSION_DB.put(pair(Void.class, BigDecimal.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, BigDecimal.class), NumberConversions::integerTypeToBigDecimal);
CONVERSION_DB.put(pair(Short.class, BigDecimal.class), NumberConversions::integerTypeToBigDecimal);
CONVERSION_DB.put(pair(Integer.class, BigDecimal.class), NumberConversions::integerTypeToBigDecimal);
CONVERSION_DB.put(pair(Long.class, BigDecimal.class), NumberConversions::integerTypeToBigDecimal);
CONVERSION_DB.put(pair(Float.class, BigDecimal.class), NumberConversions::floatingPointToBigDecimal);
CONVERSION_DB.put(pair(Double.class, BigDecimal.class), NumberConversions::floatingPointToBigDecimal);
CONVERSION_DB.put(pair(Boolean.class, BigDecimal.class), BooleanConversions::toBigDecimal);
CONVERSION_DB.put(pair(Character.class, BigDecimal.class), CharacterConversions::toBigDecimal);
CONVERSION_DB.put(pair(BigDecimal.class, BigDecimal.class), Converter::identity);
CONVERSION_DB.put(pair(BigInteger.class, BigDecimal.class), BigIntegerConversions::toBigDecimal);
CONVERSION_DB.put(pair(AtomicBoolean.class, BigDecimal.class), AtomicBooleanConversions::toBigDecimal);
CONVERSION_DB.put(pair(AtomicInteger.class, BigDecimal.class), NumberConversions::integerTypeToBigDecimal);
CONVERSION_DB.put(pair(AtomicLong.class, BigDecimal.class), NumberConversions::integerTypeToBigDecimal);
CONVERSION_DB.put(pair(Date.class, BigDecimal.class), DateConversions::toBigDecimal);
CONVERSION_DB.put(pair(java.sql.Date.class, BigDecimal.class), SqlDateConversions::toBigDecimal);
CONVERSION_DB.put(pair(Timestamp.class, BigDecimal.class), TimestampConversions::toBigDecimal);
CONVERSION_DB.put(pair(Instant.class, BigDecimal.class), InstantConversions::toBigDecimal);
CONVERSION_DB.put(pair(Duration.class, BigDecimal.class), DurationConversions::toBigDecimal);
CONVERSION_DB.put(pair(LocalTime.class, BigDecimal.class), LocalTimeConversions::toBigDecimal);
CONVERSION_DB.put(pair(LocalDate.class, BigDecimal.class), LocalDateConversions::toBigDecimal);
CONVERSION_DB.put(pair(LocalDateTime.class, BigDecimal.class), LocalDateTimeConversions::toBigDecimal);
CONVERSION_DB.put(pair(ZonedDateTime.class, BigDecimal.class), ZonedDateTimeConversions::toBigDecimal);
CONVERSION_DB.put(pair(OffsetTime.class, BigDecimal.class), OffsetTimeConversions::toBigDecimal);
CONVERSION_DB.put(pair(OffsetDateTime.class, BigDecimal.class), OffsetDateTimeConversions::toBigDecimal);
CONVERSION_DB.put(pair(UUID.class, BigDecimal.class), UUIDConversions::toBigDecimal);
CONVERSION_DB.put(pair(Calendar.class, BigDecimal.class), CalendarConversions::toBigDecimal);
CONVERSION_DB.put(pair(Map.class, BigDecimal.class), MapConversions::toBigDecimal);
CONVERSION_DB.put(pair(String.class, BigDecimal.class), StringConversions::toBigDecimal);
CONVERSION_DB.put(pair(Year.class, BigDecimal.class), YearConversions::toBigDecimal);
// AtomicBoolean conversions supported
CONVERSION_DB.put(pair(Void.class, AtomicBoolean.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(Short.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(Integer.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(Long.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(Float.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(Double.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(Boolean.class, AtomicBoolean.class), BooleanConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(Character.class, AtomicBoolean.class), CharacterConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(BigInteger.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(BigDecimal.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(AtomicBoolean.class, AtomicBoolean.class), AtomicBooleanConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(AtomicInteger.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(AtomicLong.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(Map.class, AtomicBoolean.class), MapConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(String.class, AtomicBoolean.class), StringConversions::toAtomicBoolean);
CONVERSION_DB.put(pair(Year.class, AtomicBoolean.class), YearConversions::toAtomicBoolean);
// AtomicInteger conversions supported
CONVERSION_DB.put(pair(Void.class, AtomicInteger.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(Short.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(Integer.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(Long.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(Float.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(Double.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(Boolean.class, AtomicInteger.class), BooleanConversions::toAtomicInteger);
CONVERSION_DB.put(pair(Character.class, AtomicInteger.class), CharacterConversions::toAtomicInteger);
CONVERSION_DB.put(pair(BigInteger.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(BigDecimal.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(AtomicInteger.class, AtomicInteger.class), AtomicIntegerConversions::toAtomicInteger);
CONVERSION_DB.put(pair(AtomicBoolean.class, AtomicInteger.class), AtomicBooleanConversions::toAtomicInteger);
CONVERSION_DB.put(pair(AtomicLong.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(LocalTime.class, AtomicInteger.class), LocalTimeConversions::toAtomicInteger);
CONVERSION_DB.put(pair(OffsetTime.class, AtomicInteger.class), OffsetTimeConversions::toAtomicInteger);
CONVERSION_DB.put(pair(Map.class, AtomicInteger.class), MapConversions::toAtomicInteger);
CONVERSION_DB.put(pair(String.class, AtomicInteger.class), StringConversions::toAtomicInteger);
CONVERSION_DB.put(pair(Year.class, AtomicInteger.class), YearConversions::toAtomicInteger);
// AtomicLong conversions supported
CONVERSION_DB.put(pair(Void.class, AtomicLong.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(Short.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(Integer.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(Long.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(Float.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(Double.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(Boolean.class, AtomicLong.class), BooleanConversions::toAtomicLong);
CONVERSION_DB.put(pair(Character.class, AtomicLong.class), CharacterConversions::toAtomicLong);
CONVERSION_DB.put(pair(BigInteger.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(BigDecimal.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(AtomicBoolean.class, AtomicLong.class), AtomicBooleanConversions::toAtomicLong);
CONVERSION_DB.put(pair(AtomicInteger.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(AtomicLong.class, AtomicLong.class), AtomicLongConversions::toAtomicLong);
CONVERSION_DB.put(pair(Date.class, AtomicLong.class), DateConversions::toAtomicLong);
CONVERSION_DB.put(pair(java.sql.Date.class, AtomicLong.class), SqlDateConversions::toAtomicLong);
CONVERSION_DB.put(pair(Timestamp.class, AtomicLong.class), DateConversions::toAtomicLong);
CONVERSION_DB.put(pair(Instant.class, AtomicLong.class), InstantConversions::toAtomicLong);
CONVERSION_DB.put(pair(Duration.class, AtomicLong.class), DurationConversions::toAtomicLong);
CONVERSION_DB.put(pair(LocalDate.class, AtomicLong.class), LocalDateConversions::toAtomicLong);
CONVERSION_DB.put(pair(LocalTime.class, AtomicLong.class), LocalTimeConversions::toAtomicLong);
CONVERSION_DB.put(pair(LocalDateTime.class, AtomicLong.class), LocalDateTimeConversions::toAtomicLong);
CONVERSION_DB.put(pair(ZonedDateTime.class, AtomicLong.class), ZonedDateTimeConversions::toAtomicLong);
CONVERSION_DB.put(pair(OffsetTime.class, AtomicLong.class), OffsetTimeConversions::toAtomicLong);
CONVERSION_DB.put(pair(OffsetDateTime.class, AtomicLong.class), OffsetDateTimeConversions::toAtomicLong);
CONVERSION_DB.put(pair(Calendar.class, AtomicLong.class), CalendarConversions::toAtomicLong);
CONVERSION_DB.put(pair(Map.class, AtomicLong.class), MapConversions::toAtomicLong);
CONVERSION_DB.put(pair(String.class, AtomicLong.class), StringConversions::toAtomicLong);
CONVERSION_DB.put(pair(Year.class, AtomicLong.class), YearConversions::toAtomicLong);
// Date conversions supported
CONVERSION_DB.put(pair(Void.class, Date.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Long.class, Date.class), NumberConversions::toDate);
CONVERSION_DB.put(pair(Double.class, Date.class), DoubleConversions::toDate);
CONVERSION_DB.put(pair(BigInteger.class, Date.class), BigIntegerConversions::toDate);
CONVERSION_DB.put(pair(BigDecimal.class, Date.class), BigDecimalConversions::toDate);
CONVERSION_DB.put(pair(AtomicLong.class, Date.class), NumberConversions::toDate);
CONVERSION_DB.put(pair(Date.class, Date.class), DateConversions::toDate);
CONVERSION_DB.put(pair(java.sql.Date.class, Date.class), SqlDateConversions::toDate);
CONVERSION_DB.put(pair(Timestamp.class, Date.class), TimestampConversions::toDate);
CONVERSION_DB.put(pair(Instant.class, Date.class), InstantConversions::toDate);
CONVERSION_DB.put(pair(LocalDate.class, Date.class), LocalDateConversions::toDate);
CONVERSION_DB.put(pair(LocalDateTime.class, Date.class), LocalDateTimeConversions::toDate);
CONVERSION_DB.put(pair(ZonedDateTime.class, Date.class), ZonedDateTimeConversions::toDate);
CONVERSION_DB.put(pair(OffsetDateTime.class, Date.class), OffsetDateTimeConversions::toDate);
CONVERSION_DB.put(pair(Calendar.class, Date.class), CalendarConversions::toDate);
CONVERSION_DB.put(pair(Map.class, Date.class), MapConversions::toDate);
CONVERSION_DB.put(pair(String.class, Date.class), StringConversions::toDate);
// java.sql.Date conversion supported
CONVERSION_DB.put(pair(Void.class, java.sql.Date.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Long.class, java.sql.Date.class), NumberConversions::toSqlDate);
CONVERSION_DB.put(pair(Double.class, java.sql.Date.class), DoubleConversions::toSqlDate);
CONVERSION_DB.put(pair(BigInteger.class, java.sql.Date.class), BigIntegerConversions::toSqlDate);
CONVERSION_DB.put(pair(BigDecimal.class, java.sql.Date.class), BigDecimalConversions::toSqlDate);
CONVERSION_DB.put(pair(AtomicLong.class, java.sql.Date.class), NumberConversions::toSqlDate);
CONVERSION_DB.put(pair(java.sql.Date.class, java.sql.Date.class), SqlDateConversions::toSqlDate);
CONVERSION_DB.put(pair(Date.class, java.sql.Date.class), DateConversions::toSqlDate);
CONVERSION_DB.put(pair(Timestamp.class, java.sql.Date.class), TimestampConversions::toSqlDate);
CONVERSION_DB.put(pair(Instant.class, java.sql.Date.class), InstantConversions::toSqlDate);
CONVERSION_DB.put(pair(LocalDate.class, java.sql.Date.class), LocalDateConversions::toSqlDate);
CONVERSION_DB.put(pair(LocalDateTime.class, java.sql.Date.class), LocalDateTimeConversions::toSqlDate);
CONVERSION_DB.put(pair(ZonedDateTime.class, java.sql.Date.class), ZonedDateTimeConversions::toSqlDate);
CONVERSION_DB.put(pair(OffsetDateTime.class, java.sql.Date.class), OffsetDateTimeConversions::toSqlDate);
CONVERSION_DB.put(pair(Calendar.class, java.sql.Date.class), CalendarConversions::toSqlDate);
CONVERSION_DB.put(pair(Map.class, java.sql.Date.class), MapConversions::toSqlDate);
CONVERSION_DB.put(pair(String.class, java.sql.Date.class), StringConversions::toSqlDate);
// Timestamp conversions supported
CONVERSION_DB.put(pair(Void.class, Timestamp.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Long.class, Timestamp.class), NumberConversions::toTimestamp);
CONVERSION_DB.put(pair(Double.class, Timestamp.class), DoubleConversions::toTimestamp);
CONVERSION_DB.put(pair(BigInteger.class, Timestamp.class), BigIntegerConversions::toTimestamp);
CONVERSION_DB.put(pair(BigDecimal.class, Timestamp.class), BigDecimalConversions::toTimestamp);
CONVERSION_DB.put(pair(AtomicLong.class, Timestamp.class), NumberConversions::toTimestamp);
CONVERSION_DB.put(pair(Timestamp.class, Timestamp.class), DateConversions::toTimestamp);
CONVERSION_DB.put(pair(java.sql.Date.class, Timestamp.class), SqlDateConversions::toTimestamp);
CONVERSION_DB.put(pair(Date.class, Timestamp.class), DateConversions::toTimestamp);
CONVERSION_DB.put(pair(Duration.class, Timestamp.class), DurationConversions::toTimestamp);
CONVERSION_DB.put(pair(Instant.class,Timestamp.class), InstantConversions::toTimestamp);
CONVERSION_DB.put(pair(LocalDate.class, Timestamp.class), LocalDateConversions::toTimestamp);
CONVERSION_DB.put(pair(LocalDateTime.class, Timestamp.class), LocalDateTimeConversions::toTimestamp);
CONVERSION_DB.put(pair(ZonedDateTime.class, Timestamp.class), ZonedDateTimeConversions::toTimestamp);
CONVERSION_DB.put(pair(OffsetDateTime.class, Timestamp.class), OffsetDateTimeConversions::toTimestamp);
CONVERSION_DB.put(pair(Calendar.class, Timestamp.class), CalendarConversions::toTimestamp);
CONVERSION_DB.put(pair(Map.class, Timestamp.class), MapConversions::toTimestamp);
CONVERSION_DB.put(pair(String.class, Timestamp.class), StringConversions::toTimestamp);
// Calendar conversions supported
CONVERSION_DB.put(pair(Void.class, Calendar.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Long.class, Calendar.class), NumberConversions::toCalendar);
CONVERSION_DB.put(pair(Double.class, Calendar.class), DoubleConversions::toCalendar);
CONVERSION_DB.put(pair(BigInteger.class, Calendar.class), BigIntegerConversions::toCalendar);
CONVERSION_DB.put(pair(BigDecimal.class, Calendar.class), BigDecimalConversions::toCalendar);
CONVERSION_DB.put(pair(AtomicLong.class, Calendar.class), NumberConversions::toCalendar);
CONVERSION_DB.put(pair(Date.class, Calendar.class), DateConversions::toCalendar);
CONVERSION_DB.put(pair(java.sql.Date.class, Calendar.class), SqlDateConversions::toCalendar);
CONVERSION_DB.put(pair(Timestamp.class, Calendar.class), TimestampConversions::toCalendar);
CONVERSION_DB.put(pair(Instant.class, Calendar.class), InstantConversions::toCalendar);
CONVERSION_DB.put(pair(LocalTime.class, Calendar.class), LocalTimeConversions::toCalendar);
CONVERSION_DB.put(pair(LocalDate.class, Calendar.class), LocalDateConversions::toCalendar);
CONVERSION_DB.put(pair(LocalDateTime.class, Calendar.class), LocalDateTimeConversions::toCalendar);
CONVERSION_DB.put(pair(ZonedDateTime.class, Calendar.class), ZonedDateTimeConversions::toCalendar);
CONVERSION_DB.put(pair(OffsetDateTime.class, Calendar.class), OffsetDateTimeConversions::toCalendar);
CONVERSION_DB.put(pair(Calendar.class, Calendar.class), CalendarConversions::clone);
CONVERSION_DB.put(pair(Map.class, Calendar.class), MapConversions::toCalendar);
CONVERSION_DB.put(pair(String.class, Calendar.class), StringConversions::toCalendar);
// LocalDate conversions supported
CONVERSION_DB.put(pair(Void.class, LocalDate.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Long.class, LocalDate.class), NumberConversions::toLocalDate);
CONVERSION_DB.put(pair(Double.class, LocalDate.class), DoubleConversions::toLocalDate);
CONVERSION_DB.put(pair(BigInteger.class, LocalDate.class), BigIntegerConversions::toLocalDate);
CONVERSION_DB.put(pair(BigDecimal.class, LocalDate.class), BigDecimalConversions::toLocalDate);
CONVERSION_DB.put(pair(AtomicLong.class, LocalDate.class), NumberConversions::toLocalDate);
CONVERSION_DB.put(pair(java.sql.Date.class, LocalDate.class), SqlDateConversions::toLocalDate);
CONVERSION_DB.put(pair(Timestamp.class, LocalDate.class), DateConversions::toLocalDate);
CONVERSION_DB.put(pair(Date.class, LocalDate.class), DateConversions::toLocalDate);
CONVERSION_DB.put(pair(Instant.class, LocalDate.class), InstantConversions::toLocalDate);
CONVERSION_DB.put(pair(LocalDate.class, LocalDate.class), Converter::identity);
CONVERSION_DB.put(pair(LocalDateTime.class, LocalDate.class), LocalDateTimeConversions::toLocalDate);
CONVERSION_DB.put(pair(ZonedDateTime.class, LocalDate.class), ZonedDateTimeConversions::toLocalDate);
CONVERSION_DB.put(pair(OffsetDateTime.class, LocalDate.class), OffsetDateTimeConversions::toLocalDate);
CONVERSION_DB.put(pair(Calendar.class, LocalDate.class), CalendarConversions::toLocalDate);
CONVERSION_DB.put(pair(Map.class, LocalDate.class), MapConversions::toLocalDate);
CONVERSION_DB.put(pair(String.class, LocalDate.class), StringConversions::toLocalDate);
// LocalDateTime conversions supported
CONVERSION_DB.put(pair(Void.class, LocalDateTime.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Long.class, LocalDateTime.class), NumberConversions::toLocalDateTime);
CONVERSION_DB.put(pair(Double.class, LocalDateTime.class), DoubleConversions::toLocalDateTime);
CONVERSION_DB.put(pair(BigInteger.class, LocalDateTime.class), BigIntegerConversions::toLocalDateTime);
CONVERSION_DB.put(pair(BigDecimal.class, LocalDateTime.class), BigDecimalConversions::toLocalDateTime);
CONVERSION_DB.put(pair(AtomicLong.class, LocalDateTime.class), NumberConversions::toLocalDateTime);
CONVERSION_DB.put(pair(java.sql.Date.class, LocalDateTime.class), SqlDateConversions::toLocalDateTime);
CONVERSION_DB.put(pair(Timestamp.class, LocalDateTime.class), TimestampConversions::toLocalDateTime);
CONVERSION_DB.put(pair(Date.class, LocalDateTime.class), DateConversions::toLocalDateTime);
CONVERSION_DB.put(pair(Instant.class, LocalDateTime.class), InstantConversions::toLocalDateTime);
CONVERSION_DB.put(pair(LocalDateTime.class, LocalDateTime.class), LocalDateTimeConversions::toLocalDateTime);
CONVERSION_DB.put(pair(LocalDate.class, LocalDateTime.class), LocalDateConversions::toLocalDateTime);
CONVERSION_DB.put(pair(ZonedDateTime.class, LocalDateTime.class), ZonedDateTimeConversions::toLocalDateTime);
CONVERSION_DB.put(pair(OffsetDateTime.class, LocalDateTime.class), OffsetDateTimeConversions::toLocalDateTime);
CONVERSION_DB.put(pair(Calendar.class, LocalDateTime.class), CalendarConversions::toLocalDateTime);
CONVERSION_DB.put(pair(Map.class, LocalDateTime.class), MapConversions::toLocalDateTime);
CONVERSION_DB.put(pair(String.class, LocalDateTime.class), StringConversions::toLocalDateTime);
// LocalTime conversions supported
CONVERSION_DB.put(pair(Void.class, LocalTime.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Integer.class, LocalTime.class), NumberConversions::toLocalTime);
CONVERSION_DB.put(pair(Long.class, LocalTime.class), NumberConversions::toLocalTime);
CONVERSION_DB.put(pair(Double.class, LocalTime.class), DoubleConversions::toLocalTime);
CONVERSION_DB.put(pair(BigInteger.class, LocalTime.class), BigIntegerConversions::toLocalTime);
CONVERSION_DB.put(pair(BigDecimal.class, LocalTime.class), BigDecimalConversions::toLocalTime);
CONVERSION_DB.put(pair(AtomicInteger.class, LocalTime.class), NumberConversions::toLocalTime);
CONVERSION_DB.put(pair(AtomicLong.class, LocalTime.class), NumberConversions::toLocalTime);
CONVERSION_DB.put(pair(Timestamp.class, LocalTime.class), DateConversions::toLocalTime);
CONVERSION_DB.put(pair(Date.class, LocalTime.class), DateConversions::toLocalTime);
CONVERSION_DB.put(pair(Instant.class, LocalTime.class), InstantConversions::toLocalTime);
CONVERSION_DB.put(pair(LocalDateTime.class, LocalTime.class), LocalDateTimeConversions::toLocalTime);
CONVERSION_DB.put(pair(LocalTime.class, LocalTime.class), Converter::identity);
CONVERSION_DB.put(pair(ZonedDateTime.class, LocalTime.class), ZonedDateTimeConversions::toLocalTime);
CONVERSION_DB.put(pair(OffsetDateTime.class, LocalTime.class), OffsetDateTimeConversions::toLocalTime);
CONVERSION_DB.put(pair(Calendar.class, LocalTime.class), CalendarConversions::toLocalTime);
CONVERSION_DB.put(pair(Map.class, LocalTime.class), MapConversions::toLocalTime);
CONVERSION_DB.put(pair(String.class, LocalTime.class), StringConversions::toLocalTime);
// ZonedDateTime conversions supported
CONVERSION_DB.put(pair(Void.class, ZonedDateTime.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Long.class, ZonedDateTime.class), NumberConversions::toZonedDateTime);
CONVERSION_DB.put(pair(Double.class, ZonedDateTime.class), DoubleConversions::toZonedDateTime);
CONVERSION_DB.put(pair(BigInteger.class, ZonedDateTime.class), BigIntegerConversions::toZonedDateTime);
CONVERSION_DB.put(pair(BigDecimal.class, ZonedDateTime.class), BigDecimalConversions::toZonedDateTime);
CONVERSION_DB.put(pair(AtomicLong.class, ZonedDateTime.class), NumberConversions::toZonedDateTime);
CONVERSION_DB.put(pair(java.sql.Date.class, ZonedDateTime.class), SqlDateConversions::toZonedDateTime);
CONVERSION_DB.put(pair(Timestamp.class, ZonedDateTime.class), DateConversions::toZonedDateTime);
CONVERSION_DB.put(pair(Date.class, ZonedDateTime.class), DateConversions::toZonedDateTime);
CONVERSION_DB.put(pair(Instant.class, ZonedDateTime.class), InstantConversions::toZonedDateTime);
CONVERSION_DB.put(pair(LocalDate.class, ZonedDateTime.class), LocalDateConversions::toZonedDateTime);
CONVERSION_DB.put(pair(LocalDateTime.class, ZonedDateTime.class), LocalDateTimeConversions::toZonedDateTime);
CONVERSION_DB.put(pair(ZonedDateTime.class, ZonedDateTime.class), Converter::identity);
CONVERSION_DB.put(pair(OffsetDateTime.class, ZonedDateTime.class), OffsetDateTimeConversions::toZonedDateTime);
CONVERSION_DB.put(pair(Calendar.class, ZonedDateTime.class), CalendarConversions::toZonedDateTime);
CONVERSION_DB.put(pair(Map.class, ZonedDateTime.class), MapConversions::toZonedDateTime);
CONVERSION_DB.put(pair(String.class, ZonedDateTime.class), StringConversions::toZonedDateTime);
// toOffsetDateTime
CONVERSION_DB.put(pair(Void.class, OffsetDateTime.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(OffsetDateTime.class, OffsetDateTime.class), Converter::identity);
CONVERSION_DB.put(pair(Map.class, OffsetDateTime.class), MapConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(String.class, OffsetDateTime.class), StringConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(Long.class, OffsetDateTime.class), NumberConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(AtomicLong.class, OffsetDateTime.class), NumberConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(Double.class, OffsetDateTime.class), DoubleConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(BigInteger.class, OffsetDateTime.class), BigIntegerConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(BigDecimal.class, OffsetDateTime.class), BigDecimalConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(java.sql.Date.class, OffsetDateTime.class), SqlDateConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(Date.class, OffsetDateTime.class), DateConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(Calendar.class, OffsetDateTime.class), CalendarConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(Timestamp.class, OffsetDateTime.class), TimestampConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(LocalDate.class, OffsetDateTime.class), LocalDateConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(Instant.class, OffsetDateTime.class), InstantConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(ZonedDateTime.class, OffsetDateTime.class), ZonedDateTimeConversions::toOffsetDateTime);
CONVERSION_DB.put(pair(LocalDateTime.class, OffsetDateTime.class), LocalDateTimeConversions::toOffsetDateTime);
// toOffsetTime
CONVERSION_DB.put(pair(Void.class, OffsetTime.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Integer.class, OffsetTime.class), NumberConversions::toOffsetTime);
CONVERSION_DB.put(pair(Long.class, OffsetTime.class), NumberConversions::toOffsetTime);
CONVERSION_DB.put(pair(Double.class, OffsetTime.class), DoubleConversions::toOffsetTime);
CONVERSION_DB.put(pair(BigInteger.class, OffsetTime.class), BigIntegerConversions::toOffsetTime);
CONVERSION_DB.put(pair(BigDecimal.class, OffsetTime.class), BigDecimalConversions::toOffsetTime);
CONVERSION_DB.put(pair(AtomicInteger.class, OffsetTime.class), NumberConversions::toOffsetTime);
CONVERSION_DB.put(pair(AtomicLong.class, OffsetTime.class), NumberConversions::toOffsetTime);
CONVERSION_DB.put(pair(OffsetTime.class, OffsetTime.class), Converter::identity);
CONVERSION_DB.put(pair(OffsetDateTime.class, OffsetTime.class), OffsetDateTimeConversions::toOffsetTime);
CONVERSION_DB.put(pair(Map.class, OffsetTime.class), MapConversions::toOffsetTime);
CONVERSION_DB.put(pair(String.class, OffsetTime.class), StringConversions::toOffsetTime);
// UUID conversions supported
CONVERSION_DB.put(pair(Void.class, UUID.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(UUID.class, UUID.class), Converter::identity);
CONVERSION_DB.put(pair(String.class, UUID.class), StringConversions::toUUID);
CONVERSION_DB.put(pair(BigInteger.class, UUID.class), BigIntegerConversions::toUUID);
CONVERSION_DB.put(pair(BigDecimal.class, UUID.class), BigDecimalConversions::toUUID);
CONVERSION_DB.put(pair(Map.class, UUID.class), MapConversions::toUUID);
// Class conversions supported
CONVERSION_DB.put(pair(Void.class, Class.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Class.class, Class.class), Converter::identity);
CONVERSION_DB.put(pair(Map.class, Class.class), MapConversions::toClass);
CONVERSION_DB.put(pair(String.class, Class.class), StringConversions::toClass);
// Locale conversions supported
CONVERSION_DB.put(pair(Void.class, Locale.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Locale.class, Locale.class), Converter::identity);
CONVERSION_DB.put(pair(String.class, Locale.class), StringConversions::toLocale);
CONVERSION_DB.put(pair(Map.class, Locale.class), MapConversions::toLocale);
// String conversions supported
CONVERSION_DB.put(pair(Void.class, String.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(Short.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(Integer.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(Long.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(Float.class, String.class), NumberConversions::floatToString);
CONVERSION_DB.put(pair(Double.class, String.class), NumberConversions::doubleToString);
CONVERSION_DB.put(pair(Boolean.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(Character.class, String.class), CharacterConversions::toString);
CONVERSION_DB.put(pair(BigInteger.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(BigDecimal.class, String.class), BigDecimalConversions::toString);
CONVERSION_DB.put(pair(AtomicBoolean.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(AtomicInteger.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(AtomicLong.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(byte[].class, String.class), ByteArrayConversions::toString);
CONVERSION_DB.put(pair(char[].class, String.class), CharArrayConversions::toString);
CONVERSION_DB.put(pair(Character[].class, String.class), CharacterArrayConversions::toString);
CONVERSION_DB.put(pair(ByteBuffer.class, String.class), ByteBufferConversions::toString);
CONVERSION_DB.put(pair(CharBuffer.class, String.class), CharBufferConversions::toString);
CONVERSION_DB.put(pair(Class.class, String.class), ClassConversions::toString);
CONVERSION_DB.put(pair(Date.class, String.class), DateConversions::toString);
CONVERSION_DB.put(pair(java.sql.Date.class, String.class), SqlDateConversions::toString);
CONVERSION_DB.put(pair(Timestamp.class, String.class), TimestampConversions::toString);
CONVERSION_DB.put(pair(LocalDate.class, String.class), LocalDateConversions::toString);
CONVERSION_DB.put(pair(LocalTime.class, String.class), LocalTimeConversions::toString);
CONVERSION_DB.put(pair(LocalDateTime.class, String.class), LocalDateTimeConversions::toString);
CONVERSION_DB.put(pair(ZonedDateTime.class, String.class), ZonedDateTimeConversions::toString);
CONVERSION_DB.put(pair(UUID.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(Calendar.class, String.class), CalendarConversions::toString);
CONVERSION_DB.put(pair(Map.class, String.class), MapConversions::toString);
CONVERSION_DB.put(pair(Enum.class, String.class), StringConversions::enumToString);
CONVERSION_DB.put(pair(String.class, String.class), Converter::identity);
CONVERSION_DB.put(pair(Duration.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(Instant.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(MonthDay.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(YearMonth.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(Period.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(ZoneId.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(ZoneOffset.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(OffsetTime.class, String.class), OffsetTimeConversions::toString);
CONVERSION_DB.put(pair(OffsetDateTime.class, String.class), OffsetDateTimeConversions::toString);
CONVERSION_DB.put(pair(Year.class, String.class), YearConversions::toString);
CONVERSION_DB.put(pair(Locale.class, String.class), LocaleConversions::toString);
CONVERSION_DB.put(pair(URL.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(URI.class, String.class), StringConversions::toString);
CONVERSION_DB.put(pair(TimeZone.class, String.class), TimeZoneConversions::toString);
CONVERSION_DB.put(pair(StringBuilder.class, String.class), StringBuilderConversions::toString);
CONVERSION_DB.put(pair(StringBuffer.class, String.class), StringBufferConversions::toString);
CONVERSION_DB.put(pair(Pattern.class, String.class), PatternConversions::toString);
CONVERSION_DB.put(pair(Currency.class, String.class), CurrencyConversions::toString);
// Currency conversions
CONVERSION_DB.put(pair(Void.class, Currency.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Currency.class, Currency.class), Converter::identity);
CONVERSION_DB.put(pair(String.class, Currency.class), StringConversions::toCurrency);
CONVERSION_DB.put(pair(Map.class, Currency.class), MapConversions::toCurrency);
// Pattern conversions
CONVERSION_DB.put(pair(Void.class, Pattern.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Pattern.class, Pattern.class), Converter::identity);
CONVERSION_DB.put(pair(String.class, Pattern.class), StringConversions::toPattern);
CONVERSION_DB.put(pair(Map.class, Pattern.class), MapConversions::toPattern);
// URL conversions
CONVERSION_DB.put(pair(Void.class, URL.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(URL.class, URL.class), Converter::identity);
CONVERSION_DB.put(pair(URI.class, URL.class), UriConversions::toURL);
CONVERSION_DB.put(pair(String.class, URL.class), StringConversions::toURL);
CONVERSION_DB.put(pair(Map.class, URL.class), MapConversions::toURL);
// URI Conversions
CONVERSION_DB.put(pair(Void.class, URI.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(URI.class, URI.class), Converter::identity);
CONVERSION_DB.put(pair(URL.class, URI.class), UrlConversions::toURI);
CONVERSION_DB.put(pair(String.class, URI.class), StringConversions::toURI);
CONVERSION_DB.put(pair(Map.class, URI.class), MapConversions::toURI);
// TimeZone Conversions
CONVERSION_DB.put(pair(Void.class, TimeZone.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(TimeZone.class, TimeZone.class), Converter::identity);
CONVERSION_DB.put(pair(String.class, TimeZone.class), StringConversions::toTimeZone);
CONVERSION_DB.put(pair(Map.class, TimeZone.class), MapConversions::toTimeZone);
CONVERSION_DB.put(pair(ZoneId.class, TimeZone.class), ZoneIdConversions::toTimeZone);
CONVERSION_DB.put(pair(ZoneOffset.class, TimeZone.class), ZoneOffsetConversions::toTimeZone);
// Duration conversions supported
CONVERSION_DB.put(pair(Void.class, Duration.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Duration.class, Duration.class), Converter::identity);
CONVERSION_DB.put(pair(Long.class, Duration.class), NumberConversions::toDuration);
CONVERSION_DB.put(pair(Double.class, Duration.class), DoubleConversions::toDuration);
CONVERSION_DB.put(pair(AtomicLong.class, Duration.class), NumberConversions::toDuration);
CONVERSION_DB.put(pair(BigInteger.class, Duration.class), BigIntegerConversions::toDuration);
CONVERSION_DB.put(pair(BigDecimal.class, Duration.class), BigDecimalConversions::toDuration);
CONVERSION_DB.put(pair(Timestamp.class, Duration.class), TimestampConversions::toDuration);
CONVERSION_DB.put(pair(String.class, Duration.class), StringConversions::toDuration);
CONVERSION_DB.put(pair(Map.class, Duration.class), MapConversions::toDuration);
// Instant conversions supported
CONVERSION_DB.put(pair(Void.class, Instant.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Instant.class, Instant.class), Converter::identity);
CONVERSION_DB.put(pair(Long.class, Instant.class), NumberConversions::toInstant);
CONVERSION_DB.put(pair(Double.class, Instant.class), DoubleConversions::toInstant);
CONVERSION_DB.put(pair(BigInteger.class, Instant.class), BigIntegerConversions::toInstant);
CONVERSION_DB.put(pair(BigDecimal.class, Instant.class), BigDecimalConversions::toInstant);
CONVERSION_DB.put(pair(AtomicLong.class, Instant.class), NumberConversions::toInstant);
CONVERSION_DB.put(pair(java.sql.Date.class, Instant.class), SqlDateConversions::toInstant);
CONVERSION_DB.put(pair(Timestamp.class, Instant.class), DateConversions::toInstant);
CONVERSION_DB.put(pair(Date.class, Instant.class), DateConversions::toInstant);
CONVERSION_DB.put(pair(LocalDate.class, Instant.class), LocalDateConversions::toInstant);
CONVERSION_DB.put(pair(LocalDateTime.class, Instant.class), LocalDateTimeConversions::toInstant);
CONVERSION_DB.put(pair(ZonedDateTime.class, Instant.class), ZonedDateTimeConversions::toInstant);
CONVERSION_DB.put(pair(OffsetDateTime.class, Instant.class), OffsetDateTimeConversions::toInstant);
CONVERSION_DB.put(pair(Calendar.class, Instant.class), CalendarConversions::toInstant);
CONVERSION_DB.put(pair(String.class, Instant.class), StringConversions::toInstant);
CONVERSION_DB.put(pair(Map.class, Instant.class), MapConversions::toInstant);
// ZoneId conversions supported
CONVERSION_DB.put(pair(Void.class, ZoneId.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(ZoneId.class, ZoneId.class), Converter::identity);
CONVERSION_DB.put(pair(String.class, ZoneId.class), StringConversions::toZoneId);
CONVERSION_DB.put(pair(Map.class, ZoneId.class), MapConversions::toZoneId);
CONVERSION_DB.put(pair(TimeZone.class, ZoneId.class), TimeZoneConversions::toZoneId);
CONVERSION_DB.put(pair(ZoneOffset.class, ZoneId.class), ZoneOffsetConversions::toZoneId);
// ZoneOffset conversions supported
CONVERSION_DB.put(pair(Void.class, ZoneOffset.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(ZoneOffset.class, ZoneOffset.class), Converter::identity);
CONVERSION_DB.put(pair(String.class, ZoneOffset.class), StringConversions::toZoneOffset);
CONVERSION_DB.put(pair(Map.class, ZoneOffset.class), MapConversions::toZoneOffset);
CONVERSION_DB.put(pair(ZoneId.class, ZoneOffset.class), ZoneIdConversions::toZoneOffset);
CONVERSION_DB.put(pair(TimeZone.class, ZoneOffset.class), TimeZoneConversions::toZoneOffset);
// MonthDay conversions supported
CONVERSION_DB.put(pair(Void.class, MonthDay.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(MonthDay.class, MonthDay.class), Converter::identity);
CONVERSION_DB.put(pair(java.sql.Date.class, MonthDay.class), SqlDateConversions::toMonthDay);
CONVERSION_DB.put(pair(Date.class, MonthDay.class), DateConversions::toMonthDay);
CONVERSION_DB.put(pair(Timestamp.class, MonthDay.class), TimestampConversions::toMonthDay);
CONVERSION_DB.put(pair(LocalDate.class, MonthDay.class), LocalDateConversions::toMonthDay);
CONVERSION_DB.put(pair(LocalDateTime.class, MonthDay.class), LocalDateTimeConversions::toMonthDay);
CONVERSION_DB.put(pair(ZonedDateTime.class, MonthDay.class), ZonedDateTimeConversions::toMonthDay);
CONVERSION_DB.put(pair(OffsetDateTime.class, MonthDay.class), OffsetDateTimeConversions::toMonthDay);
CONVERSION_DB.put(pair(Calendar.class, MonthDay.class), CalendarConversions::toMonthDay);
CONVERSION_DB.put(pair(String.class, MonthDay.class), StringConversions::toMonthDay);
CONVERSION_DB.put(pair(Map.class, MonthDay.class), MapConversions::toMonthDay);
// YearMonth conversions supported
CONVERSION_DB.put(pair(Void.class, YearMonth.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(YearMonth.class, YearMonth.class), Converter::identity);
CONVERSION_DB.put(pair(java.sql.Date.class, YearMonth.class), SqlDateConversions::toYearMonth);
CONVERSION_DB.put(pair(Date.class, YearMonth.class), DateConversions::toYearMonth);
CONVERSION_DB.put(pair(Timestamp.class, YearMonth.class), TimestampConversions::toYearMonth);
CONVERSION_DB.put(pair(LocalDate.class, YearMonth.class), LocalDateConversions::toYearMonth);
CONVERSION_DB.put(pair(LocalDateTime.class, YearMonth.class), LocalDateTimeConversions::toYearMonth);
CONVERSION_DB.put(pair(ZonedDateTime.class, YearMonth.class), ZonedDateTimeConversions::toYearMonth);
CONVERSION_DB.put(pair(OffsetDateTime.class, YearMonth.class), OffsetDateTimeConversions::toYearMonth);
CONVERSION_DB.put(pair(Calendar.class, YearMonth.class), CalendarConversions::toYearMonth);
CONVERSION_DB.put(pair(String.class, YearMonth.class), StringConversions::toYearMonth);
CONVERSION_DB.put(pair(Map.class, YearMonth.class), MapConversions::toYearMonth);
// Period conversions supported
CONVERSION_DB.put(pair(Void.class, Period.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Period.class, Period.class), Converter::identity);
CONVERSION_DB.put(pair(String.class, Period.class), StringConversions::toPeriod);
CONVERSION_DB.put(pair(Map.class, Period.class), MapConversions::toPeriod);
// toStringBuffer
CONVERSION_DB.put(pair(Void.class, StringBuffer.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(String.class, StringBuffer.class), StringConversions::toStringBuffer);
CONVERSION_DB.put(pair(StringBuilder.class, StringBuffer.class), StringConversions::toStringBuffer);
CONVERSION_DB.put(pair(StringBuffer.class, StringBuffer.class), StringConversions::toStringBuffer);
CONVERSION_DB.put(pair(ByteBuffer.class, StringBuffer.class), ByteBufferConversions::toStringBuffer);
CONVERSION_DB.put(pair(CharBuffer.class, StringBuffer.class), CharBufferConversions::toStringBuffer);
CONVERSION_DB.put(pair(Character[].class, StringBuffer.class), CharacterArrayConversions::toStringBuffer);
CONVERSION_DB.put(pair(char[].class, StringBuffer.class), CharArrayConversions::toStringBuffer);
CONVERSION_DB.put(pair(byte[].class, StringBuffer.class), ByteArrayConversions::toStringBuffer);
CONVERSION_DB.put(pair(Map.class, StringBuffer.class), MapConversions::toStringBuffer);
// toStringBuilder
CONVERSION_DB.put(pair(Void.class, StringBuilder.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(String.class, StringBuilder.class), StringConversions::toStringBuilder);
CONVERSION_DB.put(pair(StringBuilder.class, StringBuilder.class), StringConversions::toStringBuilder);
CONVERSION_DB.put(pair(StringBuffer.class, StringBuilder.class), StringConversions::toStringBuilder);
CONVERSION_DB.put(pair(ByteBuffer.class, StringBuilder.class), ByteBufferConversions::toStringBuilder);
CONVERSION_DB.put(pair(CharBuffer.class, StringBuilder.class), CharBufferConversions::toStringBuilder);
CONVERSION_DB.put(pair(Character[].class, StringBuilder.class), CharacterArrayConversions::toStringBuilder);
CONVERSION_DB.put(pair(char[].class, StringBuilder.class), CharArrayConversions::toStringBuilder);
CONVERSION_DB.put(pair(byte[].class, StringBuilder.class), ByteArrayConversions::toStringBuilder);
CONVERSION_DB.put(pair(Map.class, StringBuilder.class), MapConversions::toStringBuilder);
// toByteArray
CONVERSION_DB.put(pair(Void.class, byte[].class), VoidConversions::toNull);
CONVERSION_DB.put(pair(String.class, byte[].class), StringConversions::toByteArray);
CONVERSION_DB.put(pair(StringBuilder.class, byte[].class), StringConversions::toByteArray);
CONVERSION_DB.put(pair(StringBuffer.class, byte[].class), StringConversions::toByteArray);
CONVERSION_DB.put(pair(ByteBuffer.class, byte[].class), ByteBufferConversions::toByteArray);
CONVERSION_DB.put(pair(CharBuffer.class, byte[].class), CharBufferConversions::toByteArray);
CONVERSION_DB.put(pair(char[].class, byte[].class), VoidConversions::toNull); // advertising convertion, implemented generically in ArrayConversions.
CONVERSION_DB.put(pair(byte[].class, byte[].class), Converter::identity);
// toCharArray
CONVERSION_DB.put(pair(Void.class, char[].class), VoidConversions::toNull);
CONVERSION_DB.put(pair(String.class, char[].class), StringConversions::toCharArray);
CONVERSION_DB.put(pair(StringBuilder.class, char[].class), StringConversions::toCharArray);
CONVERSION_DB.put(pair(StringBuffer.class, char[].class), StringConversions::toCharArray);
CONVERSION_DB.put(pair(ByteBuffer.class, char[].class), ByteBufferConversions::toCharArray);
CONVERSION_DB.put(pair(CharBuffer.class, char[].class), CharBufferConversions::toCharArray);
CONVERSION_DB.put(pair(char[].class, char[].class), CharArrayConversions::toCharArray);
CONVERSION_DB.put(pair(byte[].class, char[].class), VoidConversions::toNull); // Used for advertising capability, implemented generically in ArrayConversions.
// toCharacterArray
CONVERSION_DB.put(pair(Void.class, Character[].class), VoidConversions::toNull);
CONVERSION_DB.put(pair(String.class, Character[].class), StringConversions::toCharacterArray);
CONVERSION_DB.put(pair(StringBuffer.class, Character[].class), StringConversions::toCharacterArray);
CONVERSION_DB.put(pair(StringBuilder.class, Character[].class), StringConversions::toCharacterArray);
// toCharBuffer
CONVERSION_DB.put(pair(Void.class, CharBuffer.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(String.class, CharBuffer.class), StringConversions::toCharBuffer);
CONVERSION_DB.put(pair(StringBuilder.class, CharBuffer.class), StringConversions::toCharBuffer);
CONVERSION_DB.put(pair(StringBuffer.class, CharBuffer.class), StringConversions::toCharBuffer);
CONVERSION_DB.put(pair(ByteBuffer.class, CharBuffer.class), ByteBufferConversions::toCharBuffer);
CONVERSION_DB.put(pair(CharBuffer.class, CharBuffer.class), CharBufferConversions::toCharBuffer);
CONVERSION_DB.put(pair(char[].class, CharBuffer.class), CharArrayConversions::toCharBuffer);
CONVERSION_DB.put(pair(byte[].class, CharBuffer.class), ByteArrayConversions::toCharBuffer);
CONVERSION_DB.put(pair(Map.class, CharBuffer.class), MapConversions::toCharBuffer);
// toByteBuffer
CONVERSION_DB.put(pair(Void.class, ByteBuffer.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(String.class, ByteBuffer.class), StringConversions::toByteBuffer);
CONVERSION_DB.put(pair(StringBuilder.class, ByteBuffer.class), StringConversions::toByteBuffer);
CONVERSION_DB.put(pair(StringBuffer.class, ByteBuffer.class), StringConversions::toByteBuffer);
CONVERSION_DB.put(pair(ByteBuffer.class, ByteBuffer.class), ByteBufferConversions::toByteBuffer);
CONVERSION_DB.put(pair(CharBuffer.class, ByteBuffer.class), CharBufferConversions::toByteBuffer);
CONVERSION_DB.put(pair(char[].class, ByteBuffer.class), CharArrayConversions::toByteBuffer);
CONVERSION_DB.put(pair(byte[].class, ByteBuffer.class), ByteArrayConversions::toByteBuffer);
CONVERSION_DB.put(pair(Map.class, ByteBuffer.class), MapConversions::toByteBuffer);
// toYear
CONVERSION_DB.put(pair(Void.class, Year.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Year.class, Year.class), Converter::identity);
CONVERSION_DB.put(pair(Short.class, Year.class), NumberConversions::toYear);
CONVERSION_DB.put(pair(Integer.class, Year.class), NumberConversions::toYear);
CONVERSION_DB.put(pair(Long.class, Year.class), NumberConversions::toYear);
CONVERSION_DB.put(pair(Float.class, Year.class), NumberConversions::toYear);
CONVERSION_DB.put(pair(Double.class, Year.class), NumberConversions::toYear);
CONVERSION_DB.put(pair(AtomicInteger.class, Year.class), NumberConversions::toYear);
CONVERSION_DB.put(pair(AtomicLong.class, Year.class), NumberConversions::toYear);
CONVERSION_DB.put(pair(BigInteger.class, Year.class), NumberConversions::toYear);
CONVERSION_DB.put(pair(BigDecimal.class, Year.class), NumberConversions::toYear);
CONVERSION_DB.put(pair(java.sql.Date.class, Year.class), SqlDateConversions::toYear);
CONVERSION_DB.put(pair(Date.class, Year.class), DateConversions::toYear);
CONVERSION_DB.put(pair(Timestamp.class, Year.class), TimestampConversions::toYear);
CONVERSION_DB.put(pair(LocalDate.class, Year.class), LocalDateConversions::toYear);
CONVERSION_DB.put(pair(LocalDateTime.class, Year.class), LocalDateTimeConversions::toYear);
CONVERSION_DB.put(pair(ZonedDateTime.class, Year.class), ZonedDateTimeConversions::toYear);
CONVERSION_DB.put(pair(OffsetDateTime.class, Year.class), OffsetDateTimeConversions::toYear);
CONVERSION_DB.put(pair(Calendar.class, Year.class), CalendarConversions::toYear);
CONVERSION_DB.put(pair(String.class, Year.class), StringConversions::toYear);
CONVERSION_DB.put(pair(Map.class, Year.class), MapConversions::toYear);
// Throwable conversions supported
CONVERSION_DB.put(pair(Void.class, Throwable.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Map.class, Throwable.class), (ConvertWithTarget) MapConversions::toThrowable);
// Map conversions supported
CONVERSION_DB.put(pair(Void.class, Map.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(Short.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(Integer.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(Long.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(Float.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(Double.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(Boolean.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(Character.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(BigInteger.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(BigDecimal.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(AtomicBoolean.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(AtomicInteger.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(AtomicLong.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(Date.class, Map.class), DateConversions::toMap);
CONVERSION_DB.put(pair(java.sql.Date.class, Map.class), SqlDateConversions::toMap);
CONVERSION_DB.put(pair(Timestamp.class, Map.class), TimestampConversions::toMap);
CONVERSION_DB.put(pair(Calendar.class, Map.class), CalendarConversions::toMap);
CONVERSION_DB.put(pair(LocalDate.class, Map.class), LocalDateConversions::toMap);
CONVERSION_DB.put(pair(LocalDateTime.class, Map.class), LocalDateTimeConversions::toMap);
CONVERSION_DB.put(pair(ZonedDateTime.class, Map.class), ZonedDateTimeConversions::toMap);
CONVERSION_DB.put(pair(Duration.class, Map.class), DurationConversions::toMap);
CONVERSION_DB.put(pair(Instant.class, Map.class), InstantConversions::toMap);
CONVERSION_DB.put(pair(LocalTime.class, Map.class), LocalTimeConversions::toMap);
CONVERSION_DB.put(pair(MonthDay.class, Map.class), MonthDayConversions::toMap);
CONVERSION_DB.put(pair(YearMonth.class, Map.class), YearMonthConversions::toMap);
CONVERSION_DB.put(pair(Period.class, Map.class), PeriodConversions::toMap);
CONVERSION_DB.put(pair(TimeZone.class, Map.class), TimeZoneConversions::toMap);
CONVERSION_DB.put(pair(ZoneId.class, Map.class), ZoneIdConversions::toMap);
CONVERSION_DB.put(pair(ZoneOffset.class, Map.class), ZoneOffsetConversions::toMap);
CONVERSION_DB.put(pair(Class.class, Map.class), MapConversions::initMap);
CONVERSION_DB.put(pair(UUID.class, Map.class), UUIDConversions::toMap);
CONVERSION_DB.put(pair(Map.class, Map.class), UNSUPPORTED);
CONVERSION_DB.put(pair(Enum.class, Map.class), EnumConversions::toMap);
CONVERSION_DB.put(pair(OffsetDateTime.class, Map.class), OffsetDateTimeConversions::toMap);
CONVERSION_DB.put(pair(OffsetTime.class, Map.class), OffsetTimeConversions::toMap);
CONVERSION_DB.put(pair(Year.class, Map.class), YearConversions::toMap);
CONVERSION_DB.put(pair(Locale.class, Map.class), LocaleConversions::toMap);
CONVERSION_DB.put(pair(URI.class, Map.class), UriConversions::toMap);
CONVERSION_DB.put(pair(URL.class, Map.class), UrlConversions::toMap);
CONVERSION_DB.put(pair(Throwable.class, Map.class), ThrowableConversions::toMap);
CONVERSION_DB.put(pair(Pattern.class, Map.class), PatternConversions::toMap);
CONVERSION_DB.put(pair(Currency.class, Map.class), CurrencyConversions::toMap);
CONVERSION_DB.put(pair(ByteBuffer.class, Map.class), ByteBufferConversions::toMap);
CONVERSION_DB.put(pair(CharBuffer.class, Map.class), CharBufferConversions::toMap);
}
/**
* Constructs a new Converter instance with the specified options.
*
* The Converter initializes its internal conversion databases by merging the predefined
* {@link #CONVERSION_DB} with any user-specified overrides provided in {@code options}.
*
*
* @param options The {@link ConverterOptions} that configure this Converter's behavior and conversions.
* @throws NullPointerException if {@code options} is {@code null}.
*/
public Converter(ConverterOptions options) {
this.options = options;
USER_DB.putAll(this.options.getConverterOverrides());
}
/**
* Converts the given source object to the specified target type.
*
* The {@code convert} method serves as the primary API for transforming objects between various types.
* It supports a wide range of conversions, including primitive types, wrapper classes, numeric types,
* date and time classes, collections, and custom objects. Additionally, it allows for extensibility
* by enabling the registration of custom converters.
*
*
* Key Features:
*
* - Wide Range of Supported Types: Supports conversion between Java primitives, their corresponding
* wrapper classes, {@link Number} subclasses, date and time classes (e.g., {@link Date}, {@link LocalDateTime}),
* collections (e.g., {@link List}, {@link Set}, {@link Map}), {@link UUID}, and more.
* - Null Handling: Gracefully handles {@code null} inputs by returning {@code null} for object types,
* default primitive values (e.g., 0 for numeric types, {@code false} for boolean), and default characters.
* - Inheritance-Based Conversions: Automatically considers superclass and interface hierarchies
* to find the most suitable converter when a direct conversion is not available.
* - Custom Converters: Allows users to register custom conversion logic for specific source-target type pairs
* using the {@link #addConversion(Class, Class, Convert)} method.
* - Thread-Safe: Designed to be thread-safe, allowing concurrent conversions without compromising data integrity.
*
*
*
* Usage Examples:
* {@code
* ConverterOptions options = new ConverterOptions();
* Converter converter = new Converter(options);
*
* // Example 1: Convert String to Integer
* String numberStr = "123";
* Integer number = converter.convert(numberStr, Integer.class);
* System.out.println("Converted Integer: " + number); // Output: Converted Integer: 123
*
* // Example 2: Convert String to Date
* String dateStr = "2024-04-27";
* LocalDate date = converter.convert(dateStr, LocalDate.class);
* System.out.println("Converted Date: " + date); // Output: Converted Date: 2024-04-27
*
* // Example 3: Convert Enum to String
* Day day = Day.MONDAY;
* String dayStr = converter.convert(day, String.class);
* System.out.println("Converted Day: " + dayStr); // Output: Converted Day: MONDAY
*
* // Example 4: Convert Array to List
* String[] stringArray = {"apple", "banana", "cherry"};
* List stringList = converter.convert(stringArray, List.class);
* System.out.println("Converted List: " + stringList); // Output: Converted List: [apple, banana, cherry]
*
* // Example 5: Convert Map to UUID
* Map uuidMap = Map.of("mostSigBits", 123456789L, "leastSigBits", 987654321L);
* UUID uuid = converter.convert(uuidMap, UUID.class);
* System.out.println("Converted UUID: " + uuid); // Output: Converted UUID: 00000000-075b-cd15-0000-0000003ade68
*
* // Example 6: Convert Object[], String[], Collection, and primitive Arrays to EnumSet
* Object[] array = {Day.MONDAY, Day.WEDNESDAY, "FRIDAY", 4};
* EnumSet daySet = (EnumSet)(Object)converter.convert(array, Day.class);
*
* Enum, String, and Number value in the source collection/array is properly converted
* to the correct Enum type and added to the returned EnumSet. Null values inside the
* source (Object[], Collection) are skipped.
*
* When converting arrays or collections to EnumSet, you must use a double cast due to Java's
* type system and generic type erasure. The cast is safe as the converter guarantees return of
* an EnumSet when converting arrays/collections to enum types.
*
* // Example 7: Register and Use a Custom Converter
* // Custom converter to convert String to CustomType
* converter.addConversion(String.class, CustomType.class, (from, conv) -> new CustomType(from));
*
* String customStr = "customValue";
* CustomType custom = converter.convert(customStr, CustomType.class);
* System.out.println("Converted CustomType: " + custom); // Output: Converted CustomType: CustomType{value='customValue'}
* }
*
*
* Parameter Descriptions:
*
* - from: The source object to be converted. This can be any object, including {@code null}.
* The actual type of {@code from} does not need to match the target type; the Converter will attempt to
* perform the necessary transformation.
* - toType: The target class to which the source object should be converted. This parameter
* specifies the desired output type. It can be a primitive type (e.g., {@code int.class}), a wrapper class
* (e.g., {@link Integer}.class), or any other supported class.
*
*
* Return Value:
*
* Returns an instance of the specified target type {@code toType}, representing the converted value of the source object {@code from}.
* If {@code from} is {@code null}, the method returns:
*
* - {@code null} for non-primitive target types.
* - Default primitive values for primitive target types (e.g., 0 for numeric types, {@code false} for {@code boolean}, '\u0000' for {@code char}).
*
*
*
* Exceptions:
*
* - IllegalArgumentException: Thrown if the conversion from the source type to the target type is not supported,
* or if the target type {@code toType} is {@code null}.
* - RuntimeException: Any underlying exception thrown during the conversion process is propagated as a {@code RuntimeException}.
*
*
* Supported Conversions:
*
* The Converter supports a vast array of conversions, including but not limited to:
*
* - Primitives and Wrappers: Convert between Java primitive types (e.g., {@code int}, {@code boolean}) and their corresponding wrapper classes (e.g., {@link Integer}, {@link Boolean}).
* - Numbers: Convert between different numeric types (e.g., {@link Integer} to {@link Double}, {@link BigInteger} to {@link BigDecimal}).
* - Date and Time: Convert between various date and time classes (e.g., {@link String} to {@link LocalDate}, {@link Date} to {@link Instant}, {@link Calendar} to {@link ZonedDateTime}).
* - Collections: Convert between different collection types (e.g., arrays to {@link List}, {@link Set} to {@link Map}, {@link StringBuilder} to {@link String}).
* - Custom Objects: Convert between complex objects (e.g., {@link UUID} to {@link Map}, {@link Class} to {@link String}, custom types via user-defined converters).
* - Buffer Types: Convert between buffer types (e.g., {@link ByteBuffer} to {@link String}, {@link CharBuffer} to {@link Byte}[]).
*
*
*
* Extensibility:
*
* Users can extend the Converter's capabilities by registering custom converters for specific type pairs.
* This is accomplished using the {@link #addConversion(Class, Class, Convert)} method, which accepts the source type,
* target type, and a {@link Convert} functional interface implementation that defines the conversion logic.
*
*
* Performance Considerations:
*
* The Converter utilizes caching mechanisms to store and retrieve converters, ensuring efficient performance
* even with a large number of conversion operations. However, registering an excessive number of custom converters
* may impact memory usage. It is recommended to register only necessary converters to maintain optimal performance.
*
*
* @param from The source object to be converted. Can be any object, including {@code null}.
* @param toType The target class to which the source object should be converted. Must not be {@code null}.
* @param The type of the target object.
* @return An instance of {@code toType} representing the converted value of {@code from}.
* @throws IllegalArgumentException if {@code toType} is {@code null} or if the conversion is not supported.
* @see #getSupportedConversions()
* @see #addConversion(Class, Class, Convert)
*/
@SuppressWarnings("unchecked")
public T convert(Object from, Class toType) {
if (toType == null) {
throw new IllegalArgumentException("toType cannot be null");
}
Class> sourceType;
if (from == null) {
// For null inputs, use Void.class so that e.g. convert(null, int.class) returns 0.
sourceType = Void.class;
// Also check the cache for (Void.class, toType) to avoid redundant lookups.
Convert> cached = getCachedConverter(sourceType, toType);
if (cached != null) {
return (T) cached.convert(from, this, toType);
}
} else {
sourceType = from.getClass();
// For non-null inputs, if toType is primitive, normalize it to its wrapper.
if (toType.isPrimitive()) {
toType = (Class) ClassUtilities.toPrimitiveWrapperClass(toType);
}
Convert> cached = getCachedConverter(sourceType, toType);
if (cached != null) {
return (T) cached.convert(from, this, toType);
}
// Try collection conversion first.
T result = attemptCollectionConversion(from, sourceType, toType);
if (result != null) {
return result;
}
}
// Prepare a conversion key.
ConversionPair key = pair(sourceType, toType);
// Check user-added conversions first.
Convert> conversionMethod = USER_DB.get(key);
if (isValidConversion(conversionMethod)) {
cacheConverter(sourceType, toType, conversionMethod);
return (T) conversionMethod.convert(from, this, toType);
}
// Then check the factory conversion database.
conversionMethod = CONVERSION_DB.get(key);
if (isValidConversion(conversionMethod)) {
cacheConverter(sourceType, toType, conversionMethod);
return (T) conversionMethod.convert(from, this, toType);
}
// Attempt inheritance-based conversion.
conversionMethod = getInheritedConverter(sourceType, toType);
if (isValidConversion(conversionMethod)) {
cacheConverter(sourceType, toType, conversionMethod);
return (T) conversionMethod.convert(from, this, toType);
}
// If no specific converter found, check assignment compatibility as fallback [someone is doing convert(linkedMap, Map.class) for example]
if (from != null && toType.isAssignableFrom(from.getClass())) {
return (T) from; // Assignment compatible - use as-is
}
throw new IllegalArgumentException("Unsupported conversion, source type [" + name(from) +
"] target type '" + getShortName(toType) + "'");
}
private static Convert> getCachedConverter(Class> source, Class> target) {
ClassValueMap> targetMap = FULL_CONVERSION_CACHE.get(source);
if (targetMap != null) {
return targetMap.get(target);
}
return null;
}
private static void cacheConverter(Class> source, Class> target, Convert> converter) {
FULL_CONVERSION_CACHE.computeIfAbsent(source, s -> new ClassValueMap<>()).put(target, converter);
}
@SuppressWarnings("unchecked")
private T attemptCollectionConversion(Object from, Class> sourceType, Class toType) {
// First validate source type is actually a collection/array type
if (!(from.getClass().isArray() || from instanceof Collection)) {
return null;
}
// Check for EnumSet target first
if (EnumSet.class.isAssignableFrom(toType)) {
throw new IllegalArgumentException("To convert to EnumSet, specify the Enum class to convert to as the 'toType.' Example: EnumSet daySet = (EnumSet)(Object)converter.convert(array, Day.class);");
}
// Special handling for Collection/Array/EnumSet conversions
if (toType.isEnum()) {
// When target is something like Day.class, we're actually creating an EnumSet
if (sourceType.isArray() || Collection.class.isAssignableFrom(sourceType)) {
return (T) EnumConversions.toEnumSet(from, toType);
}
} else if (EnumSet.class.isAssignableFrom(sourceType)) {
if (Collection.class.isAssignableFrom(toType)) {
Collection