/*
 * 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);

    }
}
