/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */

package org.apache.commons.beanutils2;

import java.io.File;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.nio.file.Path;
import java.sql.Timestamp;
import java.time.Duration;
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.Calendar;
import java.util.Collection;
import java.util.UUID;

import org.apache.commons.beanutils2.converters.ArrayConverter;
import org.apache.commons.beanutils2.converters.BigDecimalConverter;
import org.apache.commons.beanutils2.converters.BigIntegerConverter;
import org.apache.commons.beanutils2.converters.BooleanConverter;
import org.apache.commons.beanutils2.converters.ByteConverter;
import org.apache.commons.beanutils2.converters.CalendarConverter;
import org.apache.commons.beanutils2.converters.CharacterConverter;
import org.apache.commons.beanutils2.converters.ClassConverter;
import org.apache.commons.beanutils2.converters.ConverterFacade;
import org.apache.commons.beanutils2.converters.DateConverter;
import org.apache.commons.beanutils2.converters.DoubleConverter;
import org.apache.commons.beanutils2.converters.EnumConverter;
import org.apache.commons.beanutils2.converters.DurationConverter;
import org.apache.commons.beanutils2.converters.FileConverter;
import org.apache.commons.beanutils2.converters.FloatConverter;
import org.apache.commons.beanutils2.converters.IntegerConverter;
import org.apache.commons.beanutils2.converters.LocalDateConverter;
import org.apache.commons.beanutils2.converters.LocalDateTimeConverter;
import org.apache.commons.beanutils2.converters.LocalTimeConverter;
import org.apache.commons.beanutils2.converters.LongConverter;
import org.apache.commons.beanutils2.converters.MonthDayConverter;
import org.apache.commons.beanutils2.converters.OffsetDateTimeConverter;
import org.apache.commons.beanutils2.converters.OffsetTimeConverter;
import org.apache.commons.beanutils2.converters.PathConverter;
import org.apache.commons.beanutils2.converters.PeriodConverter;
import org.apache.commons.beanutils2.converters.ShortConverter;
import org.apache.commons.beanutils2.converters.SqlDateConverter;
import org.apache.commons.beanutils2.converters.SqlTimeConverter;
import org.apache.commons.beanutils2.converters.SqlTimestampConverter;
import org.apache.commons.beanutils2.converters.StringConverter;
import org.apache.commons.beanutils2.converters.URIConverter;
import org.apache.commons.beanutils2.converters.URLConverter;
import org.apache.commons.beanutils2.converters.UUIDConverter;
import org.apache.commons.beanutils2.converters.YearConverter;
import org.apache.commons.beanutils2.converters.YearMonthConverter;
import org.apache.commons.beanutils2.converters.ZoneIdConverter;
import org.apache.commons.beanutils2.converters.ZoneOffsetConverter;
import org.apache.commons.beanutils2.converters.ZonedDateTimeConverter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * <p>Utility methods for converting String scalar values to objects of the
 * specified Class, String arrays to arrays of the specified Class.  The
 * actual {@link Converter} instance to be used can be registered for each
 * possible destination Class.  Unless you override them, standard
 * {@link Converter} instances are provided for all of the following
 * destination Classes:</p>
 * <ul>
 * <li>java.lang.BigDecimal (no default value)</li>
 * <li>java.lang.BigInteger (no default value)</li>
 * <li>boolean and java.lang.Boolean (default to false)</li>
 * <li>byte and java.lang.Byte (default to zero)</li>
 * <li>char and java.lang.Character (default to a space)</li>
 * <li>java.lang.Class (no default value)</li>
 * <li>double and java.lang.Double (default to zero)</li>
 * <li>float and java.lang.Float (default to zero)</li>
 * <li>int and java.lang.Integer (default to zero)</li>
 * <li>long and java.lang.Long (default to zero)</li>
 * <li>short and java.lang.Short (default to zero)</li>
 * <li>java.lang.String (default to null)</li>
 * <li>java.lang.Enum (default to null)</li>
 * <li>java.io.File (no default value)</li>
 * <li>java.nio.file.Path (no default value)</li>
 * <li>java.net.URL (no default value)</li>
 * <li>java.net.URI (no default value)</li>
 * <li>java.util.UUID (no default value)</li>
 * <li>java.sql.Date (no default value)</li>
 * <li>java.sql.Time (no default value)</li>
 * <li>java.sql.Timestamp (no default value)</li>
 * <li>java.time.LocalDate (no default value)</li>
 * <li>java.time.LocalDateTime (no default value)</li>
 * <li>java.time.LocalTime (no default value)</li>
 * <li>java.time.OffsetDateTime (no default value)</li>
 * <li>java.time.OffsetTime (no default value)</li>
 * <li>java.time.ZonedDateTime (no default value)</li>
 * <li>java.time.Duration (no default value)</li>
 * <li>java.time.MonthDay (no default value)</li>
 * <li>java.time.Period (no default value)</li>
 * <li>java.time.Year (no default value)</li>
 * <li>java.time.YearMonth (no default value)</li>
 * <li>java.time.ZoneId (no default value)</li>
 * <li>java.time.ZoneOffset (no default value)</li>
 * </ul>
 *
 * <p>For backwards compatibility, the standard Converters for primitive
 * types (and the corresponding wrapper classes) return a defined
 * default value when a conversion error occurs.  If you prefer to have a
 * {@link ConversionException} thrown instead, replace the standard Converter
 * instances with instances created with the zero-arguments constructor.  For
 * example, to cause the Converters for integers to throw an exception on
 * conversion errors, you could do this:</p>
 * <pre>
 *   // No-args constructor gets the version that throws exceptions
 *   Converter myConverter =
 *    new org.apache.commons.beanutils2.converter.IntegerConverter();
 *   ConvertUtils.register(myConverter, Integer.TYPE);    // Native type
 *   ConvertUtils.register(myConverter, Integer.class);   // Wrapper class
 * </pre>
 *
 * <p>
 * Converters generally treat null input as if it were invalid
 * input, ie they return their default value if one was specified when the
 * converter was constructed, and throw an exception otherwise. If you prefer
 * nulls to be preserved for converters that are converting to objects (not
 * primitives) then register a converter as above, passing a default value of
 * null to the converter constructor (and of course registering that converter
 * only for the .class target).
 * </p>
 *
 * <p>
 * When a converter is listed above as having no default value, then that
 * converter will throw an exception when passed null or an invalid value
 * as its input. In particular, by default the BigInteger and BigDecimal
 * converters have no default (and are therefore somewhat inconsistent
 * with the other numerical converters which all have zero as their default).
 * </p>
 *
 * <p>
 * Converters that generate <i>arrays</i> of each of the primitive types are
 * also automatically configured (including String[]). When passed null
 * or invalid input, these return an empty array (not null). See class
 * AbstractArrayConverter for the supported input formats for these converters.
 * </p>
 *
 * @since 1.7
 */

public class ConvertUtilsBean {

    private static final Integer ZERO = Integer.valueOf(0);
    private static final Character SPACE = Character.valueOf(' ');

    
    /**
     * Get singleton instance
     * @return The singleton instance
     */
    protected static ConvertUtilsBean getInstance() {
        return BeanUtilsBean.getInstance().getConvertUtils();
    }

    

    /**
     * The set of {@link Converter}s that can be used to convert Strings
     * into objects of a specified Class, keyed by the destination Class.
     */
    private final WeakFastHashMap<Class<?>, Converter> converters =
            new WeakFastHashMap<>();

    /**
     * The {@code Log} instance for this class.
     */
    private final Log log = LogFactory.getLog(ConvertUtilsBean.class);

    

    /** Construct a bean with standard converters registered */
    public ConvertUtilsBean() {
        converters.setFast(false);
        deregister();
        converters.setFast(true);
    }

    

    /**
     * Convert the specified value into a String.  If the specified value
     * is an array, the first element (converted to a String) will be
     * returned.  The registered {@link Converter} for the
     * {@code java.lang.String} class will be used, which allows
     * applications to customize Object-&gt;String conversions (the default
     * implementation simply uses toString()).
     *
     * @param value Value to be converted (may be null)
     * @return The converted String value or null if value is null
     */
    public String convert(Object value) {

        if (value == null) {
            return null;
        } else if (value.getClass().isArray()) {
            if (Array.getLength(value) < 1) {
                return null;
            }
            value = Array.get(value, 0);
            if (value == null) {
                return null;
            }
            final Converter converter = lookup(String.class);
            return converter.convert(String.class, value);
        } else {
            final Converter converter = lookup(String.class);
            return converter.convert(String.class, value);
        }

    }

    /**
     * Convert the specified value to an object of the specified class (if
     * possible).  Otherwise, return a String representation of the value.
     *
     * @param value Value to be converted (may be null)
     * @param clazz Java class to be converted to (must not be null)
     * @return The converted value
     *
     * @throws ConversionException if thrown by an underlying Converter
     */
    public Object convert(final String value, final Class<?> clazz) {

        if (log.isDebugEnabled()) {
            log.debug("Convert string '" + value + "' to class '" +
                      clazz.getName() + "'");
        }
        Converter converter = lookup(clazz);
        if (converter == null) {
            converter = lookup(String.class);
        }
        if (log.isTraceEnabled()) {
            log.trace("  Using converter " + converter);
        }
        return converter.convert(clazz, value);

    }

    /**
     * Convert an array of specified values to an array of objects of the
     * specified class (if possible).  If the specified Java class is itself
     * an array class, this class will be the type of the returned value.
     * Otherwise, an array will be constructed whose component type is the
     * specified class.
     *
     * @param values Array of values to be converted
     * @param clazz Java array or element class to be converted to (must not be null)
     * @return The converted value
     *
     * @throws ConversionException if thrown by an underlying Converter
     */
    public Object convert(final String[] values, final Class<?> clazz) {

        Class<?> type = clazz;
        if (clazz.isArray()) {
            type = clazz.getComponentType();
        }
        if (log.isDebugEnabled()) {
            log.debug("Convert String[" + values.length + "] to class '" +
                      type.getName() + "[]'");
        }
        Converter converter = lookup(type);
        if (converter == null) {
            converter = lookup(String.class);
        }
        if (log.isTraceEnabled()) {
            log.trace("  Using converter " + converter);
        }
        final Object array = Array.newInstance(type, values.length);
        for (int i = 0; i < values.length; i++) {
            Array.set(array, i, converter.convert(type, values[i]));
        }
        return array;

    }

    /**
     * Convert the value to an object of the specified class (if
     * possible). If no converter for the desired target type is registered,
     * the passed in object is returned unchanged.
     *
     * @param value Value to be converted (may be null)
     * @param targetType Class of the value to be converted to (must not be null)
     * @return The converted value
     *
     * @throws ConversionException if thrown by an underlying Converter
     */
    public Object convert(final Object value, final Class<?> targetType) {

        final Class<?> sourceType = value == null ? null : value.getClass();

        if (log.isDebugEnabled()) {
            if (value == null) {
                log.debug("Convert null value to type '" +
                        targetType.getName() + "'");
            } else {
                log.debug("Convert type '" + sourceType.getName() + "' value '" + value +
                      "' to type '" + targetType.getName() + "'");
            }
        }

        Object converted = value;
        Converter converter = lookup(sourceType, targetType);
        if (converter != null) {
            if (log.isTraceEnabled()) {
                log.trace("  Using converter " + converter);
            }
            converted = converter.convert(targetType, value);
        }
        if (String.class.equals(targetType) && converted != null &&
                !(converted instanceof String)) {

            // NOTE: For backwards compatibility, if the Converter
            //       doesn't handle  conversion-->String then
            //       use the registered String Converter
            converter = lookup(String.class);
            if (converter != null) {
                if (log.isTraceEnabled()) {
                    log.trace("  Using converter " + converter);
                }
                converted = converter.convert(String.class, converted);
            }

            // If the object still isn't a String, use toString() method
            if (converted != null && !(converted instanceof String)) {
                converted = converted.toString();
            }

        }
        return converted;

    }

    /**
     * Remove all registered {@link Converter}s, and re-establish the
     * standard Converters.
     */
    public void deregister() {

        converters.clear();

        registerPrimitives(false);
        registerStandard(false, false);
        registerOther(true);
        registerArrays(false, 0);
        register(BigDecimal.class, new BigDecimalConverter());
        register(BigInteger.class, new BigIntegerConverter());
    }

    /**
     * Register the provided converters with the specified defaults.
     *
     * @param throwException {@code true} if the converters should
     * throw an exception when a conversion error occurs, otherwise
     * {@code false} if a default value should be used.
     * @param defaultNull {@code true}if the <i>standard</i> converters
     * (see {@link ConvertUtilsBean#registerStandard(boolean, boolean)})
     * should use a default value of {@code null</code>, otherwise <code>false}.
     * N.B. This values is ignored if {@code throwException</code> is <code>true}
     * @param defaultArraySize The size of the default array value for array converters
     * (N.B. This values is ignored if {@code throwException</code> is <code>true}).
     * Specifying a value less than zero causes a {@code null} value to be used for
     * the default.
     */
    public void register(final boolean throwException, final boolean defaultNull, final int defaultArraySize) {
        registerPrimitives(throwException);
        registerStandard(throwException, defaultNull);
        registerOther(throwException);
        registerArrays(throwException, defaultArraySize);
    }

    /**
     * Register the converters for primitive types.
     * </p>
     * This method registers the following converters:
     * <ul>
     *     <li>{@code Boolean.TYPE} - {@link BooleanConverter}</li>
     *     <li>{@code Byte.TYPE} - {@link ByteConverter}</li>
     *     <li>{@code Character.TYPE} - {@link CharacterConverter}</li>
     *     <li>{@code Double.TYPE} - {@link DoubleConverter}</li>
     *     <li>{@code Float.TYPE} - {@link FloatConverter}</li>
     *     <li>{@code Integer.TYPE} - {@link IntegerConverter}</li>
     *     <li>{@code Long.TYPE} - {@link LongConverter}</li>
     *     <li>{@code Short.TYPE} - {@link ShortConverter}</li>
     * </ul>
     * @param throwException {@code true} if the converters should
     * throw an exception when a conversion error occurs, otherwise <code>
     * {@code false} if a default value should be used.
     */
    private void registerPrimitives(final boolean throwException) {
        register(Boolean.TYPE,   throwException ? new BooleanConverter()    : new BooleanConverter(Boolean.FALSE));
        register(Byte.TYPE,      throwException ? new ByteConverter()       : new ByteConverter(ZERO));
        register(Character.TYPE, throwException ? new CharacterConverter()  : new CharacterConverter(SPACE));
        register(Double.TYPE,    throwException ? new DoubleConverter()     : new DoubleConverter(ZERO));
        register(Float.TYPE,     throwException ? new FloatConverter()      : new FloatConverter(ZERO));
        register(Integer.TYPE,   throwException ? new IntegerConverter()    : new IntegerConverter(ZERO));
        register(Long.TYPE,      throwException ? new LongConverter()       : new LongConverter(ZERO));
        register(Short.TYPE,     throwException ? new ShortConverter()      : new ShortConverter(ZERO));
    }

    /**
     * Register the converters for standard types.
     * </p>
     * This method registers the following converters:
     * <ul>
     *     <li>{@code BigDecimal.class} - {@link BigDecimalConverter}</li>
     *     <li>{@code BigInteger.class} - {@link BigIntegerConverter}</li>
     *     <li>{@code Boolean.class} - {@link BooleanConverter}</li>
     *     <li>{@code Byte.class} - {@link ByteConverter}</li>
     *     <li>{@code Character.class} - {@link CharacterConverter}</li>
     *     <li>{@code Double.class} - {@link DoubleConverter}</li>
     *     <li>{@code Float.class} - {@link FloatConverter}</li>
     *     <li>{@code Integer.class} - {@link IntegerConverter}</li>
     *     <li>{@code Long.class} - {@link LongConverter}</li>
     *     <li>{@code Short.class} - {@link ShortConverter}</li>
     *     <li>{@code String.class} - {@link StringConverter}</li>
     * </ul>
     * @param throwException {@code true} if the converters should
     * throw an exception when a conversion error occurs, otherwise <code>
     * {@code false} if a default value should be used.
     * @param defaultNull {@code true}if the <i>standard</i> converters
     * (see {@link ConvertUtilsBean#registerStandard(boolean, boolean)})
     * should use a default value of {@code null</code>, otherwise <code>false}.
     * N.B. This values is ignored if {@code throwException</code> is <code>true}
     */
    private void registerStandard(final boolean throwException, final boolean defaultNull) {

        final Number     defaultNumber     = defaultNull ? null : ZERO;
        final BigDecimal bigDecDeflt       = defaultNull ? null : new BigDecimal("0.0");
        final BigInteger bigIntDeflt       = defaultNull ? null : new BigInteger("0");
        final Boolean    booleanDefault    = defaultNull ? null : Boolean.FALSE;
        final Character  charDefault       = defaultNull ? null : SPACE;
        final String     stringDefault     = defaultNull ? null : "";

        register(BigDecimal.class, throwException ? new BigDecimalConverter() : new BigDecimalConverter(bigDecDeflt));
        register(BigInteger.class, throwException ? new BigIntegerConverter() : new BigIntegerConverter(bigIntDeflt));
        register(Boolean.class,    throwException ? new BooleanConverter()    : new BooleanConverter(booleanDefault));
        register(Byte.class,       throwException ? new ByteConverter()       : new ByteConverter(defaultNumber));
        register(Character.class,  throwException ? new CharacterConverter()  : new CharacterConverter(charDefault));
        register(Double.class,     throwException ? new DoubleConverter()     : new DoubleConverter(defaultNumber));
        register(Float.class,      throwException ? new FloatConverter()      : new FloatConverter(defaultNumber));
        register(Integer.class,    throwException ? new IntegerConverter()    : new IntegerConverter(defaultNumber));
        register(Long.class,       throwException ? new LongConverter()       : new LongConverter(defaultNumber));
        register(Short.class,      throwException ? new ShortConverter()      : new ShortConverter(defaultNumber));
        register(String.class,     throwException ? new StringConverter()     : new StringConverter(stringDefault));

    }

    /**
     * Register the converters for other types.
     * </p>
     * This method registers the following converters:
     * <ul>
     *     <li>{@code Class.class} - {@link ClassConverter}</li>
     *     <li>{@code Enum.class} - {@link EnumConverter}</li>
     *     <li>{@code java.util.Date.class} - {@link DateConverter}</li>
     *     <li>{@code java.util.Calendar.class} - {@link CalendarConverter}</li>
     *     <li>{@code File.class} - {@link FileConverter}</li>
     *     <li>{@code Path.class} - {@link PathConverter}</li>
     *     <li>{@code java.sql.Date.class} - {@link SqlDateConverter}</li>
     *     <li>{@code java.sql.Time.class} - {@link SqlTimeConverter}</li>
     *     <li>{@code java.sql.Timestamp.class} - {@link SqlTimestampConverter}</li>
     *     <li>{@code URL.class} - {@link URLConverter}</li>
     *     <li>{@code URI.class} - {@link URIConverter}</li>
     *     <li>{@code UUID.class} - {@link UUIDConverter}</li>
     *     <li>{@code LocalDate.class} - {@link LocalDateConverter}</li>
     *     <li>{@code LocalDateTime.class} - {@link LocalDateTimeConverter}</li>
     *     <li>{@code LocalTime.class} - {@link LocalTimeConverter}</li>
     *     <li>{@code OffsetDateTime.class} - {@link OffsetDateTimeConverter}</li>
     *     <li>{@code OffsetTime.class} - {@link OffsetTimeConverter}</li>
     *     <li>{@code ZonedDateTime.class} - {@link ZonedDateTimeConverter}</li>
     *     <li>{@code Duration.class} - {@link DurationConverter}</li>
     *     <li>{@code MonthDay.class} - {@link MonthDayConverter}</li>
     *     <li>{@code Period.class} - {@link PeriodConverter}</li>
     *     <li>{@code Year.class} - {@link YearConverter}</li>
     *     <li>{@code YearMonth.class} - {@link YearMonthConverter}</li>
     *     <li>{@code ZoneId.class} - {@link ZoneIdConverter}</li>
     *     <li>{@code ZoneOffset.class} - {@link ZoneOffsetConverter}</li>
     * </ul>
     * @param throwException {@code true} if the converters should
     * throw an exception when a conversion error occurs, otherwise <code>
     * {@code false} if a default value should be used.
     */
    private void registerOther(final boolean throwException) {
    	  // @formatter:off
        register(Class.class,          throwException ? new ClassConverter()          : new ClassConverter(null));
        register(Enum.class,           throwException ? new EnumConverter()           : new EnumConverter(null));
        register(java.util.Date.class, throwException ? new DateConverter()           : new DateConverter(null));
        register(Calendar.class,       throwException ? new CalendarConverter()       : new CalendarConverter(null));
        register(File.class,           throwException ? new FileConverter()           : new FileConverter(null));
        register(Path.class,           throwException ? new PathConverter()           : new PathConverter(null));
        register(java.sql.Date.class,  throwException ? new SqlDateConverter()        : new SqlDateConverter(null));
        register(java.sql.Time.class,  throwException ? new SqlTimeConverter()        : new SqlTimeConverter(null));
        register(Timestamp.class,      throwException ? new SqlTimestampConverter()   : new SqlTimestampConverter(null));
        register(URL.class,            throwException ? new URLConverter()            : new URLConverter(null));
        register(URI.class,            throwException ? new URIConverter()            : new URIConverter(null));
        register(UUID.class,           throwException ? new UUIDConverter()           : new UUIDConverter(null));
        register(LocalDate.class,      throwException ? new LocalDateConverter()      : new LocalDateConverter(null));
        register(LocalDateTime.class,  throwException ? new LocalDateTimeConverter()  : new LocalDateTimeConverter(null));
        register(LocalTime.class,      throwException ? new LocalTimeConverter()      : new LocalTimeConverter(null));
        register(OffsetDateTime.class, throwException ? new OffsetDateTimeConverter() : new OffsetDateTimeConverter(null));
        register(OffsetTime.class,     throwException ? new OffsetTimeConverter()     : new OffsetTimeConverter(null));
        register(ZonedDateTime.class,  throwException ? new ZonedDateTimeConverter()  : new ZonedDateTimeConverter(null));
        register(Duration.class,       throwException ? new DurationConverter()       : new DurationConverter(null));
        register(MonthDay.class,       throwException ? new MonthDayConverter()       : new MonthDayConverter(null));
        register(Period.class,         throwException ? new PeriodConverter()         : new PeriodConverter(null));
        register(Year.class,           throwException ? new YearConverter()           : new YearConverter(null));
        register(YearMonth.class,      throwException ? new YearMonthConverter()      : new YearMonthConverter(null));
        register(ZoneId.class,         throwException ? new ZoneIdConverter()         : new ZoneIdConverter(null));
        register(ZoneOffset.class,     throwException ? new ZoneOffsetConverter()     : new ZoneOffsetConverter(null));
        // @formatter:on
    }

    /**
     * Register array converters.
     *
     * @param throwException {@code true} if the converters should
     * throw an exception when a conversion error occurs, otherwise <code>
     * {@code false} if a default value should be used.
     * @param defaultArraySize The size of the default array value for array converters
     * (N.B. This values is ignored if {@code throwException</code> is <code>true}).
     * Specifying a value less than zero causes a <code>null<code> value to be used for
     * the default.
     */
    private void registerArrays(final boolean throwException, final int defaultArraySize) {
    	// @formatter:off

        // Primitives
        registerArrayConverter(Boolean.TYPE,   new BooleanConverter(),   throwException, defaultArraySize);
        registerArrayConverter(Byte.TYPE,      new ByteConverter(),      throwException, defaultArraySize);
        registerArrayConverter(Character.TYPE, new CharacterConverter(), throwException, defaultArraySize);
        registerArrayConverter(Double.TYPE,    new DoubleConverter(),    throwException, defaultArraySize);
        registerArrayConverter(Float.TYPE,     new FloatConverter(),     throwException, defaultArraySize);
        registerArrayConverter(Integer.TYPE,   new IntegerConverter(),   throwException, defaultArraySize);
        registerArrayConverter(Long.TYPE,      new LongConverter(),      throwException, defaultArraySize);
        registerArrayConverter(Short.TYPE,     new ShortConverter(),     throwException, defaultArraySize);

        // Standard
        registerArrayConverter(BigDecimal.class, new BigDecimalConverter(), throwException, defaultArraySize);
        registerArrayConverter(BigInteger.class, new BigIntegerConverter(), throwException, defaultArraySize);
        registerArrayConverter(Boolean.class,    new BooleanConverter(),    throwException, defaultArraySize);
        registerArrayConverter(Byte.class,       new ByteConverter(),       throwException, defaultArraySize);
        registerArrayConverter(Character.class,  new CharacterConverter(),  throwException, defaultArraySize);
        registerArrayConverter(Double.class,     new DoubleConverter(),     throwException, defaultArraySize);
        registerArrayConverter(Float.class,      new FloatConverter(),      throwException, defaultArraySize);
        registerArrayConverter(Integer.class,    new IntegerConverter(),    throwException, defaultArraySize);
        registerArrayConverter(Long.class,       new LongConverter(),       throwException, defaultArraySize);
        registerArrayConverter(Short.class,      new ShortConverter(),      throwException, defaultArraySize);
        registerArrayConverter(String.class,     new StringConverter(),     throwException, defaultArraySize);

        // Other
        registerArrayConverter(Class.class,          new ClassConverter(),         throwException, defaultArraySize);
        registerArrayConverter(Enum.class,           new EnumConverter(),          throwException, defaultArraySize);
        registerArrayConverter(java.util.Date.class, new DateConverter(),          throwException, defaultArraySize);
        registerArrayConverter(Calendar.class,       new DateConverter(),          throwException, defaultArraySize);
        registerArrayConverter(File.class,           new FileConverter(),          throwException, defaultArraySize);
        registerArrayConverter(Path.class,           new PathConverter(),          throwException, defaultArraySize);
        registerArrayConverter(java.sql.Date.class,  new SqlDateConverter(),       throwException, defaultArraySize);
        registerArrayConverter(java.sql.Time.class,  new SqlTimeConverter(),       throwException, defaultArraySize);
        registerArrayConverter(Timestamp.class,      new SqlTimestampConverter(),  throwException, defaultArraySize);
        registerArrayConverter(URL.class,            new URLConverter(),           throwException, defaultArraySize);
        registerArrayConverter(URI.class,            new URIConverter(),           throwException, defaultArraySize);
        registerArrayConverter(UUID.class,           new UUIDConverter(),          throwException, defaultArraySize);
        registerArrayConverter(LocalDate.class,      new LocalDateConverter(),     throwException, defaultArraySize);
        registerArrayConverter(LocalDateTime.class,  new LocalDateTimeConverter(), throwException, defaultArraySize);
        registerArrayConverter(LocalTime.class,      new LocalTimeConverter(),     throwException, defaultArraySize);
        registerArrayConverter(OffsetDateTime.class, new OffsetDateTimeConverter(),throwException, defaultArraySize);
        registerArrayConverter(OffsetTime.class,     new OffsetTimeConverter(),    throwException, defaultArraySize);
        registerArrayConverter(ZonedDateTime.class,  new ZonedDateTimeConverter(), throwException, defaultArraySize);
        registerArrayConverter(Duration.class,       new DurationConverter(),      throwException, defaultArraySize);
        registerArrayConverter(MonthDay.class,       new MonthDayConverter(),      throwException, defaultArraySize);
        registerArrayConverter(Period.class,         new PeriodConverter(),        throwException, defaultArraySize);
        registerArrayConverter(Year.class,           new YearConverter(),          throwException, defaultArraySize);
        registerArrayConverter(YearMonth.class,      new YearMonthConverter(),     throwException, defaultArraySize);
        registerArrayConverter(ZoneId.class,         new ZoneIdConverter(),        throwException, defaultArraySize);
        registerArrayConverter(ZoneOffset.class,     new ZoneOffsetConverter(),    throwException, defaultArraySize);
        // @formatter:on
    }

    /**
     * Register a new ArrayConverter with the specified element delegate converter
     * that returns a default array of the specified size in the event of conversion errors.
     *
     * @param componentType The component type of the array
     * @param componentConverter The converter to delegate to for the array elements
     * @param throwException Whether a conversion exception should be thrown or a default
     * value used in the event of a conversion error
     * @param defaultArraySize The size of the default array
     */
    private void registerArrayConverter(final Class<?> componentType, final Converter componentConverter,
            final boolean throwException, final int defaultArraySize) {
        final Class<?> arrayType = Array.newInstance(componentType, 0).getClass();
        Converter arrayConverter = null;
        if (throwException) {
            arrayConverter = new ArrayConverter(arrayType, componentConverter);
        } else {
            arrayConverter = new ArrayConverter(arrayType, componentConverter, defaultArraySize);
        }
        register(arrayType, arrayConverter);
    }

    /** strictly for convenience since it has same parameter order as Map.put */
    private void register(final Class<?> clazz, final Converter converter) {
        register(new ConverterFacade(converter), clazz);
    }

    /**
     * Remove any registered {@link Converter} for the specified destination
     * {@code Class}.
     *
     * @param clazz Class for which to remove a registered Converter
     */
    public void deregister(final Class<?> clazz) {

        converters.remove(clazz);

    }

    /**
     * Look up and return any registered {@link Converter} for the specified
     * destination class; if there is no registered Converter, return
     * {@code null}.
     *
     * @param clazz Class for which to return a registered Converter
     * @return The registered {@link Converter} or {@code null} if not found
     */
    public Converter lookup(final Class<?> clazz) {

        return converters.get(clazz);

    }

    /**
     * Look up and return any registered {@link Converter} for the specified
     * source and destination class; if there is no registered Converter,
     * return {@code null}.
     *
     * @param sourceType Class of the value being converted
     * @param targetType Class of the value to be converted to
     * @return The registered {@link Converter} or {@code null} if not found
     */
    public Converter lookup(final Class<?> sourceType, final Class<?> targetType) {

        if (targetType == null) {
            throw new IllegalArgumentException("Target type is missing");
        }
        if (sourceType == null) {
            return lookup(targetType);
        }

        Converter converter = null;
        // Convert --> String
        if (targetType == String.class) {
            converter = lookup(sourceType);
            if (converter == null && (sourceType.isArray() ||
                        Collection.class.isAssignableFrom(sourceType))) {
                converter = lookup(String[].class);
            }
            if (converter == null) {
                converter = lookup(String.class);
            }
            return converter;
        }

        // Convert --> String array
        if (targetType == String[].class) {
            if (sourceType.isArray() || Collection.class.isAssignableFrom(sourceType)) {
                converter = lookup(sourceType);
            }
            if (converter == null) {
                converter = lookup(String[].class);
            }
            return converter;
        }

        return lookup(targetType);

    }

    /**
     * Register a custom {@link Converter} for the specified destination
     * {@code Class}, replacing any previously registered Converter.
     *
     * @param converter Converter to be registered
     * @param clazz Destination class for conversions performed by this
     *  Converter
     */
    public void register(final Converter converter, final Class<?> clazz) {

        converters.put(clazz, converter);

    }
}
