/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2021 IBM Corporation and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
//     09/30/2014-2.6.0 Dalia Abo Sheasha
//       - 445546: NullPointerException thrown when an Array of Bytes contains null values
//     05/11/2020-2.7.0 Jody Grassel
//       - 538296: Wrong month is returned if OffsetDateTime is used in JPA 2.2 code
package org.eclipse.persistence.internal.helper;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;


import org.eclipse.persistence.config.SystemProperties;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.internal.core.helper.CoreConversionManager;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetClassLoaderForClass;
import org.eclipse.persistence.internal.security.PrivilegedGetContextClassLoader;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;

/**
 * <p>
 * <b>Purpose</b>: Contains the conversion routines for some common classes in the system.
 * Primarily used to convert objects from a given database type to a different type in Java.
 * Uses a singleton instance, this is also used from the platform.
 * <p>
 * <b>Responsibilities</b>:
 * <ul>
 * <li> Execute the appropriate conversion routine.
 *    </ul>
 */
public class ConversionManager extends CoreConversionManager implements Serializable, Cloneable {
    protected Map defaultNullValues;
    private static ZoneId defaultZoneOffset = null;

    /**
     * This flag is here if the Conversion Manager should use the class loader on the
     * thread when loading classes.
     */
    protected boolean shouldUseClassLoaderFromCurrentThread = false;
    protected static ConversionManager defaultManager;

    /** Allows the setting of a global default if no instance-level loader is set. */
    private static ClassLoader defaultLoader;
    protected ClassLoader loader;

    /** Store the list of Classes that can be converted to from the key. */
    protected Hashtable dataTypesConvertedFromAClass;

    /** Store the list of Classes that can be converted from to the key. */
    protected Hashtable dataTypesConvertedToAClass;

    private static ZoneId getDefaultZoneOffset() {
        if (defaultZoneOffset == null) {
            ZoneId tzoneid = null;
            String tzone = null;
            try {
                tzone = PrivilegedAccessHelper.getSystemProperty(SystemProperties.CONVERSION_USE_TIMEZONE);
                if (tzone != null) {
                    try {
                        tzoneid = java.time.ZoneId.of(tzone);
                    } catch (Throwable t) {
                        // If an invalid time zone id is supplied, then fall back to checking for checking for using
                        // either UTC or the system's default time zone.
                        if (AbstractSessionLog.getLog().shouldLog(SessionLog.WARNING)) {
                            AbstractSessionLog.getLog().log(SessionLog.WARNING, "invalid_tzone", 
                                    SystemProperties.CONVERSION_USE_TIMEZONE, tzone);
                        }
                    }
                } 
            } catch (Exception e) {
                // Error occurred attempting to access this system property.  Fall back to the next property.
            }
            
            String propVal = null;
            try {
                if (tzoneid == null) {
                    propVal = PrivilegedAccessHelper.getSystemProperty(SystemProperties.CONVERSION_USE_DEFAULT_TIMEZONE, "false");
                    if (Boolean.parseBoolean(propVal)) {
                        tzoneid = java.time.ZoneId.systemDefault();
                    } else {
                        tzoneid = ZoneOffset.UTC;
                    }
                }
            } catch (Exception e) {
                // Error occurred attempting to access this system property.  Fall back to UTC.
                tzoneid = ZoneOffset.UTC;
                if (AbstractSessionLog.getLog().shouldLog(SessionLog.WARNING)) {
                    AbstractSessionLog.getLog().log(SessionLog.WARNING, "invalid_default_tzone", 
                            SystemProperties.CONVERSION_USE_DEFAULT_TIMEZONE, propVal);
                }
            }           
            
            defaultZoneOffset = tzoneid;
            
            if (AbstractSessionLog.getLog().shouldLog(SessionLog.FINER)) {
                AbstractSessionLog.getLog().log(SessionLog.FINER, "using_conversion_tzone", defaultZoneOffset);
            }
        }
        
        return defaultZoneOffset;        
    }
    
    public ConversionManager() {
        this.dataTypesConvertedFromAClass = new Hashtable();
        this.dataTypesConvertedToAClass = new Hashtable();
    }

    /**
     * INTERNAL:
     */
    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException exception) {
            return null;
        }
    }

    /**
     * Convert the object to the appropriate type by invoking the appropriate
     * ConversionManager method
     * @param sourceObject the object that must be converted
     * @param javaClass the class that the object must be converted to
     * @exception ConversionException all exceptions will be thrown as this type.
     * @return the newly converted object
     */
    @Override
    public Object convertObject(Object sourceObject, Class javaClass) throws ConversionException {
        if (sourceObject == null) {
            // Check for default null conversion.
            // i.e. allow for null to be defaulted to "", or 0 etc.
            if (javaClass != null ) {
                return getDefaultNullValue(javaClass);
            } else {
                return null;
            }
        }

        if ((sourceObject.getClass() == javaClass) || (javaClass == null) || (javaClass == ClassConstants.OBJECT) || (javaClass == ClassConstants.BLOB) || (javaClass == ClassConstants.CLOB)) {
            return sourceObject;
        }

        try {
            if (javaClass == ClassConstants.STRING) {
                return convertObjectToString(sourceObject);
            } else if (javaClass == ClassConstants.UTILDATE) {
                return convertObjectToUtilDate(sourceObject);
            } else if (javaClass == ClassConstants.SQLDATE) {
                return convertObjectToDate(sourceObject);
            } else if (javaClass == ClassConstants.TIME) {
                return convertObjectToTime(sourceObject);
            } else if (javaClass == ClassConstants.TIMESTAMP) {
                return convertObjectToTimestamp(sourceObject);
            } else if (javaClass == ClassConstants.TIME_LDATE) {
                return convertObjectToLocalDate(sourceObject);
            } else if (javaClass == ClassConstants.TIME_LDATETIME) {
                return convertObjectToLocalDateTime(sourceObject);
            } else if (javaClass == ClassConstants.TIME_LTIME) {
                return convertObjectToLocalTime(sourceObject);
            } else if (javaClass == ClassConstants.TIME_ODATETIME) {
                return convertObjectToOffsetDateTime(sourceObject);
            } else if (javaClass == ClassConstants.TIME_OTIME) {
                return convertObjectToOffsetTime(sourceObject);
            } else if ((javaClass == ClassConstants.CALENDAR) || (javaClass == ClassConstants.GREGORIAN_CALENDAR)) {
                return convertObjectToCalendar(sourceObject);
            } else if ((javaClass == ClassConstants.CHAR) || (javaClass == ClassConstants.PCHAR && !(sourceObject instanceof Character))) {
                return convertObjectToChar(sourceObject);
            } else if ((javaClass == ClassConstants.INTEGER) || (javaClass == ClassConstants.PINT && !(sourceObject instanceof Integer))) {
                return convertObjectToInteger(sourceObject);
            } else if ((javaClass == ClassConstants.DOUBLE) || (javaClass == ClassConstants.PDOUBLE && !(sourceObject instanceof Double))) {
                return convertObjectToDouble(sourceObject);
            } else if ((javaClass == ClassConstants.FLOAT) || (javaClass == ClassConstants.PFLOAT && !(sourceObject instanceof Float))) {
                return convertObjectToFloat(sourceObject);
            } else if ((javaClass == ClassConstants.LONG) || (javaClass == ClassConstants.PLONG && !(sourceObject instanceof Long))) {
                return convertObjectToLong(sourceObject);
            } else if ((javaClass == ClassConstants.SHORT) || (javaClass == ClassConstants.PSHORT && !(sourceObject instanceof Short))) {
                return convertObjectToShort(sourceObject);
            } else if ((javaClass == ClassConstants.BYTE) || (javaClass == ClassConstants.PBYTE && !(sourceObject instanceof Byte))) {
                return convertObjectToByte(sourceObject);
            } else if (javaClass == ClassConstants.BIGINTEGER) {
                return convertObjectToBigInteger(sourceObject);
            } else if (javaClass == ClassConstants.BIGDECIMAL) {
                return convertObjectToBigDecimal(sourceObject);
            } else if (javaClass == ClassConstants.NUMBER) {
                return convertObjectToNumber(sourceObject);
            } else if ((javaClass == ClassConstants.BOOLEAN) || (javaClass == ClassConstants.PBOOLEAN  && !(sourceObject instanceof Boolean))) {
                return convertObjectToBoolean(sourceObject);
            } else if (javaClass == ClassConstants.APBYTE) {
                return convertObjectToByteArray(sourceObject);
            } else if (javaClass == ClassConstants.ABYTE) {
                return convertObjectToByteObjectArray(sourceObject);
            } else if (javaClass == ClassConstants.APCHAR) {
                return convertObjectToCharArray(sourceObject);
            } else if (javaClass == ClassConstants.ACHAR) {
                return convertObjectToCharacterArray(sourceObject);
            } else if ((sourceObject.getClass() == ClassConstants.STRING) && (javaClass == ClassConstants.CLASS)) {
                return convertObjectToClass(sourceObject);
            } else if(javaClass == ClassConstants.URL_Class) {
                return convertObjectToUrl(sourceObject);
            }
        } catch (ConversionException ce) {
            throw ce;
        } catch (Exception e) {
            throw ConversionException.couldNotBeConverted(sourceObject, javaClass, e);
        }

        // Check if object is instance of the real class for the primitive class.
        if ((((javaClass == ClassConstants.PBOOLEAN) && (sourceObject instanceof Boolean)  ) ||
            ((javaClass == ClassConstants.PLONG) && (sourceObject instanceof Long) ) ||
            ((javaClass == ClassConstants.PINT) && (sourceObject instanceof Integer)  ) ||
            ((javaClass == ClassConstants.PFLOAT) && (sourceObject instanceof Float)) ||
            ((javaClass == ClassConstants.PDOUBLE) &&  (sourceObject instanceof Double) ) ||
            ((javaClass == ClassConstants.PBYTE) &&  (sourceObject instanceof Byte)) ||
            ((javaClass == ClassConstants.PCHAR) &&  (sourceObject instanceof Character)) ||
            ((javaClass == ClassConstants.PSHORT) &&  (sourceObject instanceof Short)))) {
            return sourceObject;
        }

        // Delay this check as poor performance.
        if (javaClass.isInstance(sourceObject)) {
            return sourceObject;
        }
        if (ClassConstants.NOCONVERSION.isAssignableFrom(javaClass)) {
            return sourceObject;
        }

        throw ConversionException.couldNotBeConverted(sourceObject, javaClass);
    }

    /**
     * Build a valid instance of BigDecimal from the given sourceObject
     *    @param sourceObject    Valid instance of String, BigInteger, any Number
     */
    protected BigDecimal convertObjectToBigDecimal(Object sourceObject) throws ConversionException {
        BigDecimal bigDecimal = null;

        try {
            if (sourceObject instanceof String) {
                bigDecimal = new BigDecimal((String)sourceObject);
            } else if (sourceObject instanceof BigInteger) {
                bigDecimal = new BigDecimal((BigInteger)sourceObject);
            } else if (sourceObject instanceof Number) {
                // Doubles do not maintain scale, because of this it is
                // impossible to distinguish between 1 and 1.0.  In order to
                // maintain backwards compatibility both 1 and 1.0 will be
                // treated as BigDecimal(1).
                String numberString = String.valueOf(sourceObject);
                if(numberString.endsWith(".0") || numberString.contains(".0E+")) {
                    bigDecimal = new BigDecimal(((Number)sourceObject).doubleValue());
                } else {
                    bigDecimal = new BigDecimal(numberString);
                }
            } else {
                throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.BIGDECIMAL);
            }
        } catch (NumberFormatException exception) {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.BIGDECIMAL, exception);
        }
        return bigDecimal;
    }

    /**
     * Build a valid instance of BigInteger from the provided sourceObject.
     *    @param sourceObject    Valid instance of String, BigDecimal, or any Number
     */
    protected BigInteger convertObjectToBigInteger(Object sourceObject) throws ConversionException {
        BigInteger bigInteger = null;

        try {
            if (sourceObject instanceof BigInteger) {
                bigInteger = (BigInteger)sourceObject;
            } else if (sourceObject instanceof String) {
                bigInteger = new BigInteger((String)sourceObject);
            } else if (sourceObject instanceof BigDecimal) {
                bigInteger = ((BigDecimal)sourceObject).toBigInteger();
            } else if (sourceObject instanceof Number) {
                bigInteger = new BigInteger(String.valueOf(((Number)sourceObject).longValue()));
            } else if (sourceObject instanceof Byte[]) {
                Byte[] objectBytes = (Byte[])sourceObject;
                byte[] bytes = new byte[objectBytes.length];
                for (int index = 0; index < objectBytes.length; index++) {
                    bytes[index] = objectBytes[index];
                }
                bigInteger = new BigInteger(bytes);
            } else if (sourceObject instanceof byte[]) {
                bigInteger = new BigInteger((byte[]) sourceObject);
            } else {
                throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.BIGINTEGER);
            }
        } catch (NumberFormatException exception) {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.BIGINTEGER, exception);
        }

        return bigInteger;
    }

    /**
     *    Build a valid instance of Boolean from the source object.
     *    't', 'T', "true", "TRUE", 1,'1'             -&gt; Boolean(true)
     *    'f', 'F', "false", "FALSE", 0 ,'0'        -&gt; Boolean(false)
     */
    protected Boolean convertObjectToBoolean(Object sourceObject) {
        if (sourceObject instanceof Character) {
            switch (Character.toLowerCase((Character) sourceObject)) {
            case '1':
            case 't':
                return Boolean.TRUE;
            case '0':
            case 'f':
                return Boolean.FALSE;
            }
        }
        if (sourceObject instanceof String) {
            String stringValue = ((String)sourceObject).toLowerCase();
            if (stringValue.equals("t") || stringValue.equals("true") || stringValue.equals("1")) {
                return Boolean.TRUE;
            } else if (stringValue.equals("f") || stringValue.equals("false") || stringValue.equals("0")) {
                return Boolean.FALSE;
            }
        }
        if (sourceObject instanceof Number) {
            int intValue = ((Number)sourceObject).intValue();
            if (intValue != 0) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }
        throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.BOOLEAN);
    }

    /**
     * Build a valid instance of Byte from the provided sourceObject
     * @param sourceObject    Valid instance of String or any Number
     * @throws ConversionException   The Byte(String) constructor throws a
     *     NumberFormatException if the String does not contain a parsable byte.
     *
     */
    protected Byte convertObjectToByte(Object sourceObject) throws ConversionException {
        try {
            if (sourceObject instanceof String) {
                return Byte.valueOf((String)sourceObject);
            }
            if (sourceObject instanceof Number) {
                return ((Number) sourceObject).byteValue();
            }
        } catch (NumberFormatException exception) {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.BYTE, exception);
        }

        throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.BYTE);
    }

    /**
      * Build a valid instance of a byte array from the given object.
      * This method does hex conversion of the string values.  Some
      * databases have problems with storing blobs unless the blob
      * is stored as a hex string.
      */
    protected byte[] convertObjectToByteArray(Object sourceObject) throws ConversionException {
        //Bug#3128838 Used when converted to Byte[]
        if (sourceObject instanceof byte[]) {
            return (byte[])sourceObject;
            //Related to Bug#3128838.  Add support to convert to Byte[]
        } else if (sourceObject instanceof Byte[]) {
            Byte[] objectBytes = (Byte[])sourceObject;
            byte[] bytes = new byte[objectBytes.length];
            for (int index = 0; index < objectBytes.length; index++) {
                Byte value = objectBytes[index];
                if (value != null) {
                    bytes[index] = value;
                }
            }
            return bytes;
        } else if (sourceObject instanceof String) {
            return Helper.buildBytesFromHexString((String)sourceObject);
        } else if (sourceObject instanceof Blob) {
            Blob blob = (Blob)sourceObject;
            try {
                return blob.getBytes(1L, (int)blob.length());
            } catch (SQLException exception) {
                throw DatabaseException.sqlException(exception);
            }
        } else if (sourceObject instanceof InputStream) {
            InputStream inputStream = (InputStream)sourceObject;
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            try {
                int tempInt = inputStream.read();
                while (tempInt != -1) {
                    outputStream.write(tempInt);
                    tempInt = inputStream.read();
                }
                return outputStream.toByteArray();
            } catch (IOException ioException) {
                throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.APBYTE, ioException);
            }
        } else if (sourceObject instanceof BigInteger) {
            return ((BigInteger)sourceObject).toByteArray();
        }

        throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.APBYTE);
    }

    /**
      * Build a valid instance of a Byte array from the given object.
      * This method does hex conversion of the string values.  Some
      * databases have problems with storing blobs unless the blob
      * is stored as a hex string.
      */
    protected Byte[] convertObjectToByteObjectArray(Object sourceObject) throws ConversionException {
        byte[] bytes = convertObjectToByteArray(sourceObject);
        Byte[] objectBytes = new Byte[bytes.length];
        for (int index = 0; index < bytes.length; index++) {
            objectBytes[index] = bytes[index];
        }
        return objectBytes;
    }

    /**
     * Build a valid instance of java.util.Calendar from the given source object.
     *    @param sourceObject    Valid instance of java.util.Date, String, java.sql.Timestamp, or Long
     */
    protected Calendar convertObjectToCalendar(Object sourceObject) throws ConversionException {
        if (sourceObject instanceof Calendar) {
            return (Calendar)sourceObject;
        } else if (sourceObject instanceof java.util.Date) {
            // PERF: Avoid double conversion for date subclasses.
            return Helper.calendarFromUtilDate((java.util.Date)sourceObject);
        }
        return Helper.calendarFromUtilDate(convertObjectToUtilDate(sourceObject));
    }

    /**
     * Build a valid instance of Character from the provided sourceObject.
     *    @param sourceObject    Valid instance of String or any Number
     */
    protected Character convertObjectToChar(Object sourceObject) throws ConversionException {
        if (sourceObject instanceof String) {
            if (((String)sourceObject).length() < 1) {
                // ELBug336192 - Return default null value of char instead of returning null.
                return (Character)getDefaultNullValue(ClassConstants.PCHAR);
            }
            return ((String) sourceObject).charAt(0);
        }

        if (sourceObject instanceof Number) {
            return (char) ((Number) sourceObject).byteValue();
        }

        throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.CHAR);
    }

    /**
      * Build a valid instance of a Character array from the given object.
      */
    protected Character[] convertObjectToCharacterArray(Object sourceObject) throws ConversionException {
        String stringValue = convertObjectToString(sourceObject);
        Character[] chars = new Character[stringValue.length()];
        for (int index = 0; index < stringValue.length(); index++) {
            chars[index] = stringValue.charAt(index);
        }
        return chars;
    }

    /**
      * Build a valid instance of a char array from the given object.
      */
    protected char[] convertObjectToCharArray(Object sourceObject) throws ConversionException {
        if (sourceObject instanceof Character[]) {
            Character[] objectChars = (Character[])sourceObject;
            char[] chars = new char[objectChars.length];
            for (int index = 0; index < objectChars.length; index++) {
                chars[index] = objectChars[index];
            }
            return chars;
        }
        String stringValue = convertObjectToString(sourceObject);
        char[] chars = new char[stringValue.length()];
        for (int index = 0; index < stringValue.length(); index++) {
            chars[index] = stringValue.charAt(index);
        }
        return chars;
    }

    /**
     * Build a valid Class from the string that is passed in
     *    @param sourceObject    Valid instance of String
     */
    protected Class convertObjectToClass(Object sourceObject) throws ConversionException {
        Class theClass = null;
        if (!(sourceObject instanceof String)) {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.CLASS);
        }
        try {
            // bug # 2799318
            theClass = getPrimitiveClass((String)sourceObject);
            if (theClass == null) {
                theClass = Class.forName((String)sourceObject, true, getLoader());
            }
        } catch (Exception exception) {
            throw ConversionException.couldNotBeConvertedToClass(sourceObject, ClassConstants.CLASS, exception);
        }
        return theClass;
    }

    /**
      * Convert the object to an instance of java.sql.Date.
      *    @param    sourceObject Object of type java.sql.Timestamp, java.util.Date, String or Long
      */
    protected java.sql.Date convertObjectToDate(Object sourceObject) throws ConversionException {
        java.sql.Date date = null;

        if (sourceObject instanceof java.sql.Date) {
            date = (java.sql.Date)sourceObject;//Helper date is not caught on class check.
        } else if (sourceObject instanceof java.sql.Timestamp) {
            date = Helper.dateFromTimestamp((java.sql.Timestamp)sourceObject);
        } else if (sourceObject.getClass() == ClassConstants.UTILDATE) {
            date = Helper.sqlDateFromUtilDate((java.util.Date)sourceObject);
        } else if (sourceObject instanceof Calendar) {
            return Helper.dateFromCalendar((Calendar)sourceObject);
        } else if (sourceObject instanceof String) {
            date = Helper.dateFromString((String)sourceObject);
        } else if (sourceObject instanceof Long) {
            date = Helper.dateFromLong((Long)sourceObject);
        } else {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.SQLDATE);
        }
        return date;
    }

    /**
      * Convert the object to an instance of Double.
      * @param                    sourceObject Object of type String or Number.
      * @throws ConversionException The Double(String) constructor throws a
      *         NumberFormatException if the String does not contain a parsable double.
      */
    protected Double convertObjectToDouble(Object sourceObject) throws ConversionException {
        try {
            if (sourceObject instanceof String) {
                return Double.valueOf((String)sourceObject);
            }
            if (sourceObject instanceof Number) {
                return ((Number) sourceObject).doubleValue();
            }
        } catch (NumberFormatException exception) {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.DOUBLE, exception);
        }
        throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.DOUBLE);
    }

    /**
     * Build a valid Float instance from a String or another Number instance.
     * @throws ConversionException The Float(String) constructor throws a
     *         NumberFormatException if the String does not contain a parsable Float.
     */
    protected Float convertObjectToFloat(Object sourceObject) throws ConversionException {
        try {
            if (sourceObject instanceof String) {
                return Float.valueOf((String)sourceObject);
            }
            if (sourceObject instanceof Number) {
                return ((Number) sourceObject).floatValue();
            }
        } catch (NumberFormatException exception) {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.FLOAT, exception);
        }

        throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.FLOAT);
    }

    /**
     * Build a valid Integer instance from a String or another Number instance.
     * @throws ConversionException The Integer(String) constructor throws a
     *         NumberFormatException if the String does not contain a parsable integer.
     */
    protected Integer convertObjectToInteger(Object sourceObject) throws ConversionException {
        try {
            if (sourceObject instanceof String) {
                return Integer.valueOf((String)sourceObject);
            }

            if (sourceObject instanceof Number) {
                return ((Number) sourceObject).intValue();
            }

            if (sourceObject instanceof Boolean) {
                if ((Boolean) sourceObject) {
                    return 1;
                } else {
                    return 0;
                }
            }
        } catch (NumberFormatException exception) {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.INTEGER, exception);
        }

        throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.INTEGER);
    }

    /**
      * Build a valid Long instance from a String or another Number instance.
      * @throws ConversionException  The Long(String) constructor throws a
      *         NumberFormatException if the String does not contain a parsable long.
      *
      */
    protected Long convertObjectToLong(Object sourceObject) throws ConversionException {
        try {
            if (sourceObject instanceof String) {
                return Long.valueOf((String)sourceObject);
            }
            if (sourceObject instanceof Number) {
                return ((Number) sourceObject).longValue();
            }
            if (sourceObject instanceof java.util.Date) {
                return ((java.util.Date) sourceObject).getTime();
            }
            if (sourceObject instanceof java.util.Calendar) {
                return ((Calendar) sourceObject).getTimeInMillis();
            }

            if (sourceObject instanceof Boolean) {
                if ((Boolean) sourceObject) {
                    return 1L;
                } else {
                    return 0L;
                }
            }
        } catch (NumberFormatException exception) {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.LONG, exception);
        }

        throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.LONG);
    }

    /**
     * INTERNAL:
     * Build a valid BigDecimal instance from a String or another
     * Number instance.  BigDecimal is the most general type so is
     * must be returned when an object is converted to a number.
     * @throws ConversionException The BigDecimal(String) constructor throws a
     *     NumberFormatException if the String does not contain a parsable BigDecimal.
     */
    protected BigDecimal convertObjectToNumber(Object sourceObject) throws ConversionException {
        try {
            if (sourceObject instanceof String) {
                return new BigDecimal((String)sourceObject);
            }

            if (sourceObject instanceof Number) {
                return new BigDecimal(((Number)sourceObject).doubleValue());
            }

            if (sourceObject instanceof Boolean) {
                if ((Boolean) sourceObject) {
                    return BigDecimal.valueOf(1);
                } else {
                    return BigDecimal.valueOf(0);
                }
            }
        } catch (NumberFormatException exception) {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.NUMBER, exception);
        }

        throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.NUMBER);
    }

    /**
     * INTERNAL:
     * Build a valid Short instance from a String or another Number instance.
     * @throws ConversionException The Short(String) constructor throws a
     *     NumberFormatException if the String does not contain a parsable short.
     */
    protected Short convertObjectToShort(Object sourceObject) throws ConversionException {
        try {
            if (sourceObject instanceof String) {
                return Short.valueOf((String)sourceObject);
            }

            if (sourceObject instanceof Number) {
                return ((Number) sourceObject).shortValue();
            }

            if (sourceObject instanceof Boolean) {
                if ((Boolean) sourceObject) {
                    return (short) 1;
                } else {
                    return (short) 0;
                }
            }
        } catch (Exception exception) {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.SHORT, exception);
        }

        throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.SHORT);
    }

    /**
     * INTERNAL:
     * Converts objects to their string representations.  java.util.Date
     * is converted to a timestamp first and then to a string.  An array
     * of bytes is converted to a hex string.
     */
    protected String convertObjectToString(Object sourceObject) throws ConversionException {

        Class sourceObjectClass = sourceObject.getClass();

        if (sourceObject instanceof java.lang.Number) {
            return sourceObject.toString();
        } else if (sourceObjectClass == ClassConstants.BOOLEAN) {
            return sourceObject.toString();
        } else if (sourceObjectClass == ClassConstants.UTILDATE) {
            return Helper.printTimestamp(Helper.timestampFromDate((java.util.Date)sourceObject));
        } else if (sourceObject instanceof java.util.Calendar) {
            return Helper.printCalendar((Calendar)sourceObject);
        } else if (sourceObjectClass == ClassConstants.TIMESTAMP) {
            return Helper.printTimestamp((java.sql.Timestamp)sourceObject);
        } else if (sourceObject instanceof java.sql.Date) {
            return Helper.printDate((java.sql.Date)sourceObject);
        } else if (sourceObject instanceof java.sql.Time) {
            return Helper.printTime((java.sql.Time)sourceObject);
        } else if (sourceObjectClass == ClassConstants.APBYTE) {
            return Helper.buildHexStringFromBytes((byte[])sourceObject);
            //Bug#3854296 Added support to convert Byte[], char[] and Character[] to String correctly
        } else if (sourceObjectClass == ClassConstants.ABYTE) {
            return Helper.buildHexStringFromBytes(convertObjectToByteArray(sourceObject));
        } else if (sourceObjectClass == ClassConstants.APCHAR) {
            return new String((char[])sourceObject);
        } else if (sourceObjectClass == ClassConstants.ACHAR) {
            return new String(convertObjectToCharArray(sourceObject));
        } else if (sourceObject instanceof Class) {
            return ((Class)sourceObject).getName();
        } else if (sourceObjectClass == ClassConstants.CHAR) {
            return sourceObject.toString();
        } else if (sourceObject instanceof Clob) {
            Clob clob = (Clob)sourceObject;
            try {
                return clob.getSubString(1L, (int)clob.length());
            } catch (SQLException exception) {
                throw DatabaseException.sqlException(exception);
            }
        }

        return sourceObject.toString();
    }

    /**
     * INTERNAL:
     * Build a valid instance of java.sql.Time from the given source object.
     * @param    sourceObject    Valid instance of java.sql.Time, String, java.util.Date, java.sql.Timestamp, or Long
     */
    protected java.sql.Time convertObjectToTime(Object sourceObject) throws ConversionException {
        java.sql.Time time = null;

        if (sourceObject instanceof java.sql.Time) {
            return (java.sql.Time)sourceObject;//Helper timestamp is not caught on class check.
        }

        if (sourceObject instanceof String) {
            time = Helper.timeFromString((String)sourceObject);
        } else if (sourceObject.getClass() == ClassConstants.UTILDATE) {
            time = Helper.timeFromDate((java.util.Date)sourceObject);
        } else if (sourceObject instanceof java.sql.Timestamp) {
            time = Helper.timeFromTimestamp((java.sql.Timestamp)sourceObject);
        } else if (sourceObject instanceof Calendar) {
            return Helper.timeFromCalendar((Calendar)sourceObject);
        } else if (sourceObject instanceof Long) {
            time = Helper.timeFromLong((Long)sourceObject);
        } else if (sourceObject.getClass() == ClassConstants.TIME_LTIME) {
            time = java.sql.Time.valueOf((java.time.LocalTime) sourceObject);
        } else if (sourceObject.getClass() == ClassConstants.TIME_OTIME) {
            time = java.sql.Time.valueOf(((java.time.OffsetTime) sourceObject).toLocalTime());
        } else {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.TIME);
        }
        return time;
    }

    /**
     * INTERNAL:
     * Build a valid instance of java.sql.Timestamp from the given source object.
     * @param sourceObject    Valid object of class java.sql.Timestamp, String, java.util.Date, or Long
     */
    protected java.sql.Timestamp convertObjectToTimestamp(Object sourceObject) throws ConversionException {
        java.sql.Timestamp timestamp = null;

        if (sourceObject instanceof java.sql.Timestamp) {
            return (java.sql.Timestamp)sourceObject;// Helper timestamp is not caught on class check.
        }

        if (sourceObject instanceof String) {
            timestamp = Helper.timestampFromString((String)sourceObject);
        } else if (sourceObject instanceof java.util.Date) {// This handles all date and subclasses, sql.Date, sql.Time conversions.
            timestamp = Helper.timestampFromDate((java.util.Date)sourceObject);
        } else if (sourceObject instanceof Calendar) {
            return Helper.timestampFromCalendar((Calendar)sourceObject);
        } else if (sourceObject instanceof Long) {
            timestamp = Helper.timestampFromLong((Long)sourceObject);
        } else if (sourceObject instanceof LocalDateTime) {
            timestamp = Timestamp.valueOf((LocalDateTime) sourceObject);
        } else {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.TIMESTAMP);
        }
        return timestamp;
    }

    /**
     * INTERNAL: Build a valid instance of java.time.LocalDate from the given
     * source object.
     *
     * @param sourceObject
     *            Valid object of class java.sql.Timestamp, String,
     *            java.util.Date, or Long
     */
    protected java.time.LocalDate convertObjectToLocalDate(Object sourceObject) throws ConversionException {
        java.time.LocalDate localDate = null;

        if (sourceObject instanceof java.time.LocalDate) {
            return (java.time.LocalDate) sourceObject;
        }

        if (sourceObject instanceof String) {
            localDate = java.time.LocalDate.parse(((String) sourceObject).replace(' ', 'T'), Helper.getDefaultDateTimeFormatter());
        } else if (sourceObject instanceof java.sql.Date) {
            localDate = ((java.sql.Date) sourceObject).toLocalDate();
        } else if (sourceObject instanceof java.sql.Timestamp) {
            localDate = ((java.sql.Timestamp) sourceObject).toLocalDateTime().toLocalDate();
        } else if (sourceObject instanceof java.util.Date) {
            // handles sql.Time too
            localDate = ((java.util.Date) sourceObject).toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        } else if (sourceObject instanceof Calendar) {
            Calendar cal = (Calendar) sourceObject;
            localDate = java.time.LocalDate.of(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH));
        } else if (sourceObject instanceof Long) {
            localDate = java.time.LocalDate.ofEpochDay((Long) sourceObject);
        } else {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.TIME_LDATE);
        }

        return localDate;
    }

    /**
     * INTERNAL: Build a valid instance of java.time.LocalTime from the given
     * source object.
     *
     * @param sourceObject
     *            Valid object of class java.sql.Timestamp, String,
     *            java.util.Date, or Long
     */
    protected java.time.LocalTime convertObjectToLocalTime(Object sourceObject) throws ConversionException {
        java.time.LocalTime localTime = null;

        if (sourceObject instanceof java.time.LocalTime) {
            return (java.time.LocalTime) sourceObject;
        }

        if (sourceObject instanceof String) {
            localTime = java.time.LocalTime.parse(((String) sourceObject).replace(' ', 'T'), Helper.getDefaultDateTimeFormatter());
        } else if (sourceObject instanceof java.sql.Timestamp) {
            localTime = ((java.sql.Timestamp) sourceObject).toLocalDateTime().toLocalTime();
        } else if (sourceObject instanceof java.sql.Time) {
            localTime = ((java.sql.Time) sourceObject).toLocalTime();
        } else if (sourceObject instanceof java.util.Date) {
            // handles sql.Date
            Calendar cal = Helper.allocateCalendar();
            cal.setTime((java.util.Date) sourceObject);
            localTime = java.time.LocalTime.of(
                    cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND));
            Helper.releaseCalendar(cal);
        } else if (sourceObject instanceof Calendar) {
            Calendar cal = (Calendar) sourceObject;
            localTime = java.time.LocalTime.of(
                    cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND));
        } else if (sourceObject instanceof Long) {
            localTime = java.time.LocalTime.ofSecondOfDay((Long) sourceObject);
        } else {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.TIME_LTIME);
        }

        return localTime;
    }

    /**
     * INTERNAL: Build a valid instance of java.time.LocalDateTime from the given
     * source object.
     *
     * @param sourceObject
     *            Valid object of class java.sql.Timestamp, String,
     *            java.util.Date, or Long
     */
    protected java.time.LocalDateTime convertObjectToLocalDateTime(Object sourceObject) throws ConversionException {
        java.time.LocalDateTime localDateTime = null;

        if (sourceObject instanceof java.time.LocalDateTime) {
            return (java.time.LocalDateTime) sourceObject;
        }

        if (sourceObject instanceof String) {
            localDateTime = java.time.LocalDateTime.parse(((String) sourceObject).replace(' ', 'T'), Helper.getDefaultDateTimeFormatter());
        } else if (sourceObject instanceof java.sql.Timestamp) {
            localDateTime = ((java.sql.Timestamp) sourceObject).toLocalDateTime();
        } else if (sourceObject instanceof java.util.Date) {
            // handles sql.Time, sql.Date
            Calendar cal = Helper.allocateCalendar();
            cal.setTime((java.util.Date) sourceObject);
            localDateTime = java.time.LocalDateTime.of(
                    cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH),
                    cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND));
            Helper.releaseCalendar(cal);
        } else if (sourceObject instanceof Calendar) {
            Calendar cal = (Calendar) sourceObject;
            localDateTime = java.time.LocalDateTime.of(
                    cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH),
                    cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND));
        } else if (sourceObject instanceof Long) {
            localDateTime = java.time.LocalDateTime.ofInstant(
                    java.time.Instant.ofEpochSecond((Long) sourceObject), getDefaultZoneOffset());
        } else {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.TIME_LDATETIME);
        }

        return localDateTime;
    }

    /**
     * INTERNAL: Build a valid instance of java.time.OffsetDateTime from the given
     * source object.
     *
     * @param sourceObject
     *            Valid object of class java.sql.Timestamp, String,
     *            java.util.Date, or Long
     */
    protected java.time.OffsetDateTime convertObjectToOffsetDateTime(Object sourceObject) throws ConversionException {
        java.time.OffsetDateTime offsetDateTime = null;

        if (sourceObject instanceof java.time.OffsetDateTime) {
            return (java.time.OffsetDateTime) sourceObject;
        }

        if (sourceObject instanceof String) {
            java.time.LocalDateTime ldt = java.time.LocalDateTime.parse(((String) sourceObject).replace(' ', 'T'), Helper.getDefaultDateTimeFormatter());
            return ldt.atZone(java.time.ZoneId.systemDefault()).toOffsetDateTime();
        } else if (sourceObject instanceof java.util.Date) {
            // handles sql.Time, sql.Date, sql.Timestamp
            Calendar cal = Helper.allocateCalendar();
            cal.setTime((java.util.Date) sourceObject);
            offsetDateTime = java.time.OffsetDateTime.of(
                    cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH),
                    cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND) * 1000000,
                    java.time.ZoneOffset.ofTotalSeconds((cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / 1000));
            Helper.releaseCalendar(cal);
        } else if (sourceObject instanceof Calendar) {
            Calendar cal = (Calendar) sourceObject;
            offsetDateTime = java.time.OffsetDateTime.of(
                    cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH),
                    cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND)  * 1000000,
                    java.time.ZoneOffset.ofTotalSeconds((cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / 1000));
        } else if (sourceObject instanceof Long) {
            offsetDateTime = java.time.OffsetDateTime.ofInstant(
                    java.time.Instant.ofEpochSecond((Long) sourceObject), getDefaultZoneOffset());
        } else {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.TIME_ODATETIME);
        }

        return offsetDateTime;
    }

    /**
     * INTERNAL: Build a valid instance of java.time.OffsetTime from the given
     * source object.
     *
     * @param sourceObject
     *            Valid object of class java.sql.Timestamp, String,
     *            java.util.Date, or Long
     */
    protected java.time.OffsetTime convertObjectToOffsetTime(Object sourceObject) throws ConversionException {
        java.time.OffsetTime offsetTime = null;

        if (sourceObject instanceof java.time.OffsetTime) {
            return (java.time.OffsetTime) sourceObject;
        }

        if (sourceObject instanceof String) {
            try {
                offsetTime = java.time.OffsetTime.parse(((String) sourceObject).replace(' ', 'T'), Helper.getDefaultDateTimeFormatter());
            } catch (Exception e) {
                java.time.LocalTime localTime = java.time.LocalTime.parse(((String) sourceObject).replace(' ', 'T'), Helper.getDefaultDateTimeFormatter());
                offsetTime = java.time.OffsetTime.of(localTime, java.time.OffsetDateTime.now().getOffset());
            }
        } else if (sourceObject instanceof java.util.Date) {
            // handles sql.Time, sql.Date, sql.Timestamp
            Calendar cal = Helper.allocateCalendar();
            cal.setTime((java.util.Date) sourceObject);
            offsetTime = java.time.OffsetTime.of(
                    cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND),
                    java.time.ZoneOffset.ofTotalSeconds((cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / 1000));
            Helper.releaseCalendar(cal);
        } else if (sourceObject instanceof Calendar) {
            Calendar cal = (Calendar) sourceObject;
            offsetTime = java.time.OffsetTime.of(
                    cal.get(Calendar.HOUR), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND),
                    java.time.ZoneOffset.ofTotalSeconds((cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / 1000));
        } else if (sourceObject instanceof Long) {
            offsetTime = java.time.OffsetTime.ofInstant(
                    java.time.Instant.ofEpochSecond((Long) sourceObject), getDefaultZoneOffset());
        } else {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.TIME_OTIME);
        }

        return offsetTime;
    }

    /**
     * INTERNAL:
     * Build a valid instance of java.net.URL from the given source object.
     * @param sourceObject    Valid instance of java.net.URL, or String
     */
    protected URL convertObjectToUrl(Object sourceObject) throws ConversionException {
        if(sourceObject.getClass() == ClassConstants.URL_Class) {
            return (URL) sourceObject;
        } else if (sourceObject.getClass() == ClassConstants.STRING) {
            try {
                return new URL((String) sourceObject);
            } catch(Exception e) {
                throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.URL_Class, e);
            }
        } else {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.URL_Class);
        }
    }

    /**
     * INTERNAL:
     * Build a valid instance of java.util.Date from the given source object.
     * @param sourceObject    Valid instance of java.util.Date, String, java.sql.Timestamp, or Long
     */
    protected java.util.Date convertObjectToUtilDate(Object sourceObject) throws ConversionException {
        java.util.Date date = null;

        if (sourceObject.getClass() == java.util.Date.class) {
            date = (java.util.Date)sourceObject;//used when converting util.Date to Calendar
        } else if (sourceObject instanceof java.sql.Date) {
            date = Helper.utilDateFromSQLDate((java.sql.Date)sourceObject);
        } else if (sourceObject instanceof java.sql.Time) {
            date = Helper.utilDateFromTime((java.sql.Time)sourceObject);
        } else if (sourceObject instanceof String) {
            date = Helper.utilDateFromTimestamp(Helper.timestampFromString((String)sourceObject));
        } else if (sourceObject instanceof java.sql.Timestamp) {
            date = Helper.utilDateFromTimestamp((java.sql.Timestamp)sourceObject);
        } else if (sourceObject instanceof Calendar) {
            return ((Calendar)sourceObject).getTime();
        } else if (sourceObject instanceof Long) {
            date = Helper.utilDateFromLong((Long)sourceObject);
        } else if (sourceObject instanceof java.util.Date) {
            date = new java.util.Date(((java.util.Date) sourceObject).getTime());
        } else if (sourceObject instanceof LocalDateTime) {
            date = Helper.utilDateFromTimestamp(java.sql.Timestamp.valueOf((LocalDateTime) sourceObject));
        } else {
            throw ConversionException.couldNotBeConverted(sourceObject, ClassConstants.UTILDATE);
        }
        return date;
    }

    /**
     * PUBLIC:
     * Resolve the given String className into a class using this
     * ConversionManager's classloader.
     */
    public Class convertClassNameToClass(String className) throws ConversionException {
        return convertObjectToClass(className);
    }

    /**
     * A singleton conversion manager is used to handle generic conversions.
     * This should not be used for conversion under the session context, these must go through the platform.
     * This allows for the singleton to be customized through setting the default to a user defined subclass.
     */
    public static ConversionManager getDefaultManager() {
        if (defaultManager == null) {
            setDefaultManager(new ConversionManager());
            defaultManager.setShouldUseClassLoaderFromCurrentThread(true);
        }
        return defaultManager;
    }

    /**
     * INTERNAL:
     * Allow for the null values for classes to be defaulted in one place.
     * Any nulls read from the database to be converted to the class will be given the specified null value.
     */
    public Object getDefaultNullValue(Class theClass) {
        if (this.defaultNullValues == null) return null;
        return getDefaultNullValues().get(theClass);
    }

    /**
     * INTERNAL:
     * Allow for the null values for classes to be defaulted in one place.
     * Any nulls read from the database to be converted to the class will be given the specified null value.
     */
    public Map getDefaultNullValues() {
        return defaultNullValues;
    }

    /**
     * INTERNAL:
     */
    @Override
    public ClassLoader getLoader() {
        if (shouldUseClassLoaderFromCurrentThread()) {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    return AccessController.doPrivileged(new PrivilegedGetContextClassLoader(Thread.currentThread()));
                } catch (PrivilegedActionException exception) {
                    // should not be thrown
                }
            } else {
                return PrivilegedAccessHelper.getContextClassLoader(Thread.currentThread());
            }
        }
        if (loader == null) {
            if (defaultLoader == null) {
                //CR 2621
                ClassLoader loader = null;
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    try{
                        loader = AccessController.doPrivileged(new PrivilegedGetClassLoaderForClass(ClassConstants.ConversionManager_Class));
                    } catch (PrivilegedActionException exc){
                        // will not be thrown
                    }
                } else {
                    loader = PrivilegedAccessHelper.getClassLoaderForClass(ClassConstants.ConversionManager_Class);
                }
                setLoader(loader);
            } else {
                setLoader(getDefaultLoader());
            }
        }
        return loader;
    }

    /**
     * INTERNAL
     */
    public boolean hasDefaultNullValues(){
        return this.defaultNullValues != null;
    }

    /**
     * INTERNAL:
     * Load the class using the default managers class loader.
     * This is a thread based class loader by default.
     * This should be used to load all classes as Class.forName can only
     * see classes on the same classpath as the eclipselink.jar.
     */
    public static Class loadClass(String className) {
        return (Class)getDefaultManager().convertObject(className, ClassConstants.CLASS);
    }

    /**
     * INTERNAL:
     * This is used to determine the wrapper class for a primitive.
     */
    public static Class getObjectClass(Class javaClass) {
        // Null means unknown always for classifications.
        if (javaClass == null) {
            return null;
        }

        if (javaClass.isPrimitive()) {
            if (javaClass == ClassConstants.PCHAR) {
                return ClassConstants.CHAR;
            }
            if (javaClass == ClassConstants.PINT) {
                return ClassConstants.INTEGER;
            }
            if (javaClass == ClassConstants.PDOUBLE) {
                return ClassConstants.DOUBLE;
            }
            if (javaClass == ClassConstants.PFLOAT) {
                return ClassConstants.FLOAT;
            }
            if (javaClass == ClassConstants.PLONG) {
                return ClassConstants.LONG;
            }
            if (javaClass == ClassConstants.PSHORT) {
                return ClassConstants.SHORT;
            }
            if (javaClass == ClassConstants.PBYTE) {
                return ClassConstants.BYTE;
            }
            if (javaClass == ClassConstants.PBOOLEAN) {
                return ClassConstants.BOOLEAN;
            }
            } else if (javaClass == ClassConstants.APBYTE) {
                return ClassConstants.APBYTE;
            } else if (javaClass == ClassConstants.APCHAR) {
                return ClassConstants.APCHAR;
            } else {
                return javaClass;
            }

        return javaClass;
    }

    /**
     * INTERNAL:
     * Returns a class based on the passed in string.
     */
    public static Class getPrimitiveClass(String classType) {
        if (classType.equals("int")) {
            return Integer.TYPE;
        } else if (classType.equals("boolean")) {
            return Boolean.TYPE;
        } else if (classType.equals("char")) {
            return Character.TYPE;
        } else if (classType.equals("short")) {
            return Short.TYPE;
        } else if (classType.equals("byte")) {
            return Byte.TYPE;
        } else if (classType.equals("float")) {
            return Float.TYPE;
        } else if (classType.equals("double")) {
            return Double.TYPE;
        } else if (classType.equals("long")) {
            return Long.TYPE;
        }

        return null;
    }

    /**
     * A singleton conversion manager is used to handle generic conversions.
     * This should not be used for conversion under the session context, these must go through the platform.
     * This allows for the singleton to be customized through setting the default to a user defined subclass.
     */
    public static void setDefaultManager(ConversionManager theManager) {
        defaultManager = theManager;
    }

    /**
     * INTERNAL:
     * Allow for the null values for classes to be defaulted in one place.
     * Any nulls read from the database to be converted to the class will be given the specified null value.
     * Primitive null values should be set to the wrapper class.
     */
    public void setDefaultNullValue(Class theClass, Object theValue) {
        if (this.defaultNullValues == null){
            this.defaultNullValues = new HashMap(5);
        }
        getDefaultNullValues().put(theClass, theValue);
    }

    /**
     * INTERNAL:
     * Allow for the null values for classes to be defaulted in one place.
     * Any nulls read from the database to be converted to the class will be given the specified null value.
     */
    public void setDefaultNullValues(Map defaultNullValues) {
        this.defaultNullValues = defaultNullValues;
    }

    /**
     * INTERNAL:
     */
    public void setLoader(ClassLoader classLoader) {
        shouldUseClassLoaderFromCurrentThread = false;
        loader = classLoader;
    }

    /**
     * INTERNAL:
     * Set the default class loader to use if no instance-level loader is set
     */
    public static void setDefaultLoader(ClassLoader classLoader) {
        defaultLoader = classLoader;
    }

    /**
     * INTERNAL:
     * Get the default class loader to use if no instance-level loader is set
     * @return java.lang.ClassLoader
     */
    public static ClassLoader getDefaultLoader() {
        return defaultLoader;
    }

    /**
     * ADVANCED:
     * This flag should be set if the current thread classLoader should be used.
     * This is the case in certain Application Servers were the class loader must be
     * retrieved from the current Thread.  If classNotFoundExceptions are being thrown then set
     * this flag.  In certain cases it will resolve the problem
     */
    public void setShouldUseClassLoaderFromCurrentThread(boolean useCurrentThread) {
        this.shouldUseClassLoaderFromCurrentThread = useCurrentThread;
    }

    /**
     * ADVANCED:
     *  This flag should be set if the current thread classLoader should be used.
     * This is the case in certain Application Servers were the class loader must be
     * retrieved from the current Thread.  If classNotFoundExceptions are being thrown then set
     * this flag.  In certain cases it will resolve the problem
     */
    public boolean shouldUseClassLoaderFromCurrentThread() {
        return this.shouldUseClassLoaderFromCurrentThread;
    }

    /**
     * PUBLIC:
     * Return the list of Classes that can be converted to from the passed in javaClass.
     * @param javaClass - the class that is converted from
     * @return - a vector of classes
     */
    public Vector getDataTypesConvertedFrom(Class javaClass) {
        if (dataTypesConvertedFromAClass.isEmpty()) {
            buildDataTypesConvertedFromAClass();
        }
        return (Vector)dataTypesConvertedFromAClass.get(javaClass);
    }

    /**
     * PUBLIC:
     * Return the list of Classes that can be converted from to the passed in javaClass.
     * @param javaClass - the class that is converted to
     * @return - a vector of classes
     */
    public Vector getDataTypesConvertedTo(Class javaClass) {
        if (dataTypesConvertedToAClass.isEmpty()) {
            buildDataTypesConvertedToAClass();
        }
        return (Vector)dataTypesConvertedToAClass.get(javaClass);
    }

    protected Vector buildNumberVec() {
        Vector vec = new Vector();
        vec.addElement(BigInteger.class);
        vec.addElement(BigDecimal.class);
        vec.addElement(Byte.class);
        vec.addElement(Double.class);
        vec.addElement(Float.class);
        vec.addElement(Integer.class);
        vec.addElement(Long.class);
        vec.addElement(Short.class);
        vec.addElement(Number.class);
        return vec;
    }

    protected Vector buildDateTimeVec() {
        Vector vec = new Vector();
        vec.addElement(java.util.Date.class);
        vec.addElement(Timestamp.class);
        vec.addElement(Calendar.class);
        return vec;
    }

    protected void buildDataTypesConvertedFromAClass() {
        dataTypesConvertedFromAClass.put(BigDecimal.class, buildFromBigDecimalVec());
        dataTypesConvertedFromAClass.put(BigInteger.class, buildFromBigIntegerVec());
        dataTypesConvertedFromAClass.put(Blob.class, buildFromBlobVec());
        dataTypesConvertedFromAClass.put(Boolean.class, buildFromBooleanVec());
        dataTypesConvertedFromAClass.put(byte[].class, buildFromByteArrayVec());
        dataTypesConvertedFromAClass.put(Byte.class, buildFromByteVec());
        dataTypesConvertedFromAClass.put(Calendar.class, buildFromCalendarVec());
        dataTypesConvertedFromAClass.put(Character.class, buildFromCharacterVec());
        dataTypesConvertedFromAClass.put(Clob.class, buildFromClobVec());
        dataTypesConvertedFromAClass.put(java.sql.Date.class, buildFromDateVec());
        dataTypesConvertedFromAClass.put(Double.class, buildFromDoubleVec());
        dataTypesConvertedFromAClass.put(Float.class, buildFromFloatVec());
        dataTypesConvertedFromAClass.put(Integer.class, buildFromIntegerVec());
        dataTypesConvertedFromAClass.put(Long.class, buildFromLongVec());
        dataTypesConvertedFromAClass.put(Number.class, buildFromNumberVec());
        dataTypesConvertedFromAClass.put(Short.class, buildFromShortVec());
        dataTypesConvertedFromAClass.put(String.class, buildFromStringVec());
        dataTypesConvertedFromAClass.put(Timestamp.class, buildFromTimestampVec());
        dataTypesConvertedFromAClass.put(Time.class, buildFromTimeVec());
        dataTypesConvertedFromAClass.put(java.util.Date.class, buildFromUtilDateVec());
        dataTypesConvertedFromAClass.put(Byte[].class, buildFromByteObjectArraryVec());
        dataTypesConvertedFromAClass.put(char[].class, buildFromCharArrayVec());
        dataTypesConvertedFromAClass.put(Character[].class, buildFromCharacterArrayVec());
    }

    protected Vector buildFromBooleanVec() {
        Vector vec = new Vector();
        vec.addElement(String.class);
        vec.addElement(Boolean.class);
        vec.addElement(Integer.class);
        vec.addElement(Long.class);
        vec.addElement(Short.class);
        vec.addElement(Number.class);
        vec.addElement(Character[].class);
        vec.addElement(char[].class);
        vec.addElement(boolean.class);
        vec.addElement(int.class);
        vec.addElement(long.class);
        vec.addElement(short.class);
        return vec;
    }

    protected Vector buildFromNumberVec() {
        Vector vec = buildNumberVec();
        vec.addElement(String.class);
        vec.addElement(Character.class);
        vec.addElement(Boolean.class);
        vec.addElement(Character[].class);
        vec.addElement(char[].class);
        vec.addElement(char.class);
        vec.addElement(int.class);
        vec.addElement(double.class);
        vec.addElement(float.class);
        vec.addElement(long.class);
        vec.addElement(short.class);
        vec.addElement(byte.class);
        vec.addElement(boolean.class);
        return vec;
    }

    protected Vector buildFromBigDecimalVec() {
        return buildFromNumberVec();
    }

    protected Vector buildFromBigIntegerVec() {
        return buildFromNumberVec();
    }

    protected Vector buildFromIntegerVec() {
        return buildFromNumberVec();
    }

    protected Vector buildFromFloatVec() {
        return buildFromNumberVec();
    }

    protected Vector buildFromDoubleVec() {
        return buildFromNumberVec();
    }

    protected Vector buildFromShortVec() {
        return buildFromNumberVec();
    }

    protected Vector buildFromByteVec() {
        return buildFromNumberVec();
    }

    protected Vector buildFromLongVec() {
        Vector vec = buildFromNumberVec();
        vec.addAll(buildDateTimeVec());
        vec.addElement(java.sql.Date.class);
        vec.addElement(Time.class);
        return vec;
    }

    protected Vector buildFromStringVec() {
        Vector vec = buildFromLongVec();
        vec.addElement(Byte[].class);
        vec.addElement(byte[].class);
        vec.addElement(Clob.class);
        return vec;
    }

    protected Vector buildFromCharacterVec() {
        Vector vec = new Vector();
        vec.addElement(String.class);
        vec.addElement(Boolean.class);
        vec.addElement(Character[].class);
        vec.addElement(Character.class);
        vec.addElement(char[].class);
        vec.addElement(char.class);
        vec.addElement(boolean.class);
        return vec;
    }

    protected Vector buildFromByteArrayVec() {
        Vector vec = new Vector();
        vec.addElement(String.class);
        vec.addElement(byte[].class);
        vec.addElement(Byte[].class);
        vec.addElement(Character[].class);
        vec.addElement(char[].class);
        return vec;
    }

    protected Vector buildFromClobVec() {
        Vector vec = new Vector();
        vec.addElement(String.class);
        vec.addElement(Character[].class);
        vec.addElement(char[].class);
        return vec;
    }

    protected Vector buildFromBlobVec() {
        Vector vec = new Vector();
        vec.addElement(String.class);
        vec.addElement(Byte[].class);
        vec.addElement(byte[].class);
        vec.addElement(Character[].class);
        vec.addElement(char[].class);
        return vec;
    }

    protected Vector buildFromUtilDateVec() {
        Vector vec = buildDateTimeVec();
        vec.addElement(String.class);
        vec.addElement(Long.class);
        vec.addElement(java.sql.Date.class);
        vec.addElement(Time.class);
        vec.addElement(long.class);
        vec.addElement(Character[].class);
        vec.addElement(char[].class);
        return vec;
    }

    protected Vector buildFromTimestampVec() {
        return buildFromUtilDateVec();
    }

    protected Vector buildFromCalendarVec() {
        return buildFromUtilDateVec();
    }

    protected Vector buildFromDateVec() {
        Vector vec = buildDateTimeVec();
        vec.addElement(String.class);
        vec.addElement(Long.class);
        vec.addElement(java.sql.Date.class);
        vec.addElement(long.class);
        vec.addElement(Character[].class);
        vec.addElement(char[].class);
        return vec;
    }

    protected Vector buildFromTimeVec() {
        Vector vec = buildDateTimeVec();
        vec.addElement(String.class);
        vec.addElement(Long.class);
        vec.addElement(Time.class);
        vec.addElement(long.class);
        vec.addElement(Character[].class);
        vec.addElement(char[].class);
        return vec;
    }

    protected Vector buildFromByteObjectArraryVec() {
        Vector vec = new Vector();
        vec.addElement(Blob.class);
        vec.addElement(byte[].class);
        return vec;
    }

    protected Vector buildFromCharArrayVec() {
        Vector vec = new Vector();
        vec.addElement(Clob.class);
        return vec;
    }

    protected Vector buildFromCharacterArrayVec() {
        Vector vec = new Vector();
        vec.addElement(Clob.class);
        return vec;
    }

    protected void buildDataTypesConvertedToAClass() {
        dataTypesConvertedToAClass.put(BigDecimal.class, buildToBigDecimalVec());
        dataTypesConvertedToAClass.put(BigInteger.class, buildToBigIntegerVec());
        dataTypesConvertedToAClass.put(Boolean.class, buildToBooleanVec());
        dataTypesConvertedToAClass.put(Byte.class, buildToByteVec());
        dataTypesConvertedToAClass.put(byte[].class, buildToByteArrayVec());
        dataTypesConvertedToAClass.put(Byte[].class, buildToByteObjectArrayVec());
        dataTypesConvertedToAClass.put(Calendar.class, buildToCalendarVec());
        dataTypesConvertedToAClass.put(Character.class, buildToCharacterVec());
        dataTypesConvertedToAClass.put(Character[].class, buildToCharacterArrayVec());
        dataTypesConvertedToAClass.put(char[].class, buildToCharArrayVec());
        dataTypesConvertedToAClass.put(java.sql.Date.class, buildToDateVec());
        dataTypesConvertedToAClass.put(Double.class, buildToDoubleVec());
        dataTypesConvertedToAClass.put(Float.class, buildToFloatVec());
        dataTypesConvertedToAClass.put(Integer.class, buildToIntegerVec());
        dataTypesConvertedToAClass.put(Long.class, buildToLongVec());
        dataTypesConvertedToAClass.put(Number.class, buildToNumberVec());
        dataTypesConvertedToAClass.put(Short.class, buildToShortVec());
        dataTypesConvertedToAClass.put(String.class, buildToStringVec());
        dataTypesConvertedToAClass.put(Timestamp.class, buildToTimestampVec());
        dataTypesConvertedToAClass.put(Time.class, buildToTimeVec());
        dataTypesConvertedToAClass.put(java.util.Date.class, buildToUtilDateVec());
        dataTypesConvertedToAClass.put(Clob.class, buildToClobVec());
        dataTypesConvertedToAClass.put(Blob.class, buildToBlobVec());
    }

    protected Vector buildAllTypesToAClassVec() {
        Vector vec = new Vector();
        vec.addElement(String.class);
        vec.addElement(Integer.class);
        vec.addElement(java.util.Date.class);
        vec.addElement(java.sql.Date.class);
        vec.addElement(Time.class);
        vec.addElement(Timestamp.class);
        vec.addElement(Calendar.class);
        vec.addElement(Character.class);
        vec.addElement(Double.class);
        vec.addElement(Float.class);
        vec.addElement(Long.class);
        vec.addElement(Short.class);
        vec.addElement(Byte.class);
        vec.addElement(BigInteger.class);
        vec.addElement(BigDecimal.class);
        vec.addElement(Number.class);
        vec.addElement(Boolean.class);
        vec.addElement(Character[].class);
        vec.addElement(Blob.class);
        vec.addElement(Clob.class);
        return vec;
    }

    protected Vector buildToBigDecimalVec() {
        Vector vec = buildNumberVec();
        vec.addElement(String.class);
        return vec;
    }

    protected Vector buildToBigIntegerVec() {
        return buildToBigDecimalVec();
    }

    protected Vector buildToBooleanVec() {
        Vector vec = buildToBigDecimalVec();
        vec.addElement(Character.class);
        vec.addElement(Boolean.class);
        return vec;
    }

    protected Vector buildToByteVec() {
        return buildToBigDecimalVec();
    }

    protected Vector buildToDoubleVec() {
        return buildToBigDecimalVec();
    }

    protected Vector buildToFloatVec() {
        return buildToBigDecimalVec();
    }

    protected Vector buildToIntegerVec() {
        Vector vec = buildToBigDecimalVec();
        vec.addElement(Boolean.class);
        return vec;
    }

    protected Vector buildToLongVec() {
        Vector vec = buildToIntegerVec();
        vec.addElement(Calendar.class);
        vec.addElement(java.util.Date.class);
        return vec;
    }

    protected Vector buildToNumberVec() {
        return buildToIntegerVec();
    }

    protected Vector buildToShortVec() {
        return buildToIntegerVec();
    }

    protected Vector buildToByteArrayVec() {
        Vector vec = new Vector();
        vec.addElement(String.class);
        vec.addElement(Blob.class);
        vec.addElement(byte[].class);
        vec.addElement(Byte[].class);
        return vec;
    }

    protected Vector buildToByteObjectArrayVec() {
        Vector vec = buildToByteArrayVec();
        vec.addElement(Byte[].class);
        return vec;
    }

    protected Vector buildToCharacterVec() {
        Vector vec = buildToBigDecimalVec();
        vec.addElement(Character.class);
        return vec;
    }

    protected Vector buildToCharacterArrayVec() {
        return buildAllTypesToAClassVec();
    }

    protected Vector buildToCharArrayVec() {
        return buildAllTypesToAClassVec();
    }

    protected Vector buildToStringVec() {
        return buildAllTypesToAClassVec();
    }

    protected Vector buildToCalendarVec() {
        Vector vec = buildDateTimeVec();
        vec.addElement(String.class);
        vec.addElement(Long.class);
        vec.addElement(java.sql.Date.class);
        vec.addElement(Time.class);
        return vec;
    }

    protected Vector buildToTimestampVec() {
        return buildToCalendarVec();
    }

    protected Vector buildToUtilDateVec() {
        return buildToCalendarVec();
    }

    protected Vector buildToDateVec() {
        Vector vec = buildDateTimeVec();
        vec.addElement(String.class);
        vec.addElement(Long.class);
        vec.addElement(java.sql.Date.class);
        return vec;
    }

    protected Vector buildToTimeVec() {
        Vector vec = buildDateTimeVec();
        vec.addElement(String.class);
        vec.addElement(Long.class);
        vec.addElement(Time.class);
        return vec;
    }

    protected Vector buildToBlobVec() {
        Vector vec = new Vector();
        vec.addElement(Byte[].class);
        vec.addElement(byte[].class);
        return vec;
    }

    protected Vector buildToClobVec() {
        Vector vec = new Vector();
        vec.addElement(String.class);
        vec.addElement(char[].class);
        vec.addElement(Character[].class);
        return vec;
    }
}
