/*
 * Copyright (c) 1998, 2022 Oracle 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
package org.eclipse.persistence.internal.oxm;

import java.io.File;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.UUID;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.XMLConversionException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.core.queries.CoreContainerPolicy;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.helper.TimeZoneHolder;
import org.eclipse.persistence.internal.oxm.conversion.Base64;
import org.eclipse.persistence.internal.oxm.record.AbstractUnmarshalRecord;
import org.eclipse.persistence.internal.queries.ContainerPolicy;

/**
 * INTERNAL:
 * <p><b>Purpose</b>: Primarily used to convert objects from a given XML Schema type to a different type in Java.
 * Uses a singleton instance</p>
 * @since    OracleAS TopLink 10<i>g</i>
 */

public class XMLConversionManager extends ConversionManager implements org.eclipse.persistence.internal.oxm.ConversionManager, TimeZoneHolder {
    protected static final String GMT_ID = "GMT";
    protected static final String GMT_SUFFIX = "Z";

    protected static XMLConversionManager defaultXMLManager;

    // Static hash tables for the default conversion pairs
    protected static Map<QName, Class<?>> defaultXMLTypes;
    protected static Map<Class<?>, QName> defaultJavaTypes;

    protected boolean timeZoneQualified;
    protected TimeZone timeZone;

    protected static final int TOTAL_MS_DIGITS = 3;  // total digits for millisecond formatting
    protected static final int TOTAL_NS_DIGITS = 9;  // total digits for nanosecond  formatting

    private static final char PLUS = '+';

    protected DatatypeFactory datatypeFactory;

    public XMLConversionManager() {
        super();
        timeZoneQualified = false;
    }

    /**
     * INTERNAL:
     *
     * Return the DatatypeFactory instance.
     *
     */
    protected DatatypeFactory getDatatypeFactory() {
        if (datatypeFactory == null) {
            try {
                datatypeFactory = DatatypeFactory.newInstance();
            } catch (DatatypeConfigurationException e) {
                throw new RuntimeException(e);
            }
        }
        return datatypeFactory;
    }

    public static XMLConversionManager getDefaultXMLManager() {
        if (defaultXMLManager == null) {
            defaultXMLManager = new XMLConversionManager();
        }
        return defaultXMLManager;
    }

    /**
     * Return the specified TimeZone used for all String to date object
     * conversions.
     */
    @Override
    public TimeZone getTimeZone() {
        if (timeZone == null) {
            return TimeZone.getDefault();
        } else {
            return timeZone;
        }
    }

    /**
     * The specified TimeZone will be used for all String to date object
     * conversions.  By default the TimeZone from the JVM is used.
     */
    public void setTimeZone(TimeZone timeZone) {
        this.timeZone = timeZone;
    }

    /**
      *
      */
    public boolean isTimeZoneQualified() {
        return timeZoneQualified;
    }

    /**
     * Specify if
     * Specify if when date objects are converted to Strings in the XML Schema
     * time or dateTime format
     */

    public void setTimeZoneQualified(boolean timeZoneQualified) {
        this.timeZoneQualified = timeZoneQualified;
    }

    /**
     * Convert the given object to the appropriate type by invoking the appropriate
     * ConversionManager method.
     *
     * @param sourceObject - will always be a string if read from XML
     * @param javaClass - the class that the object must be converted to
     * @return - the newly converted object
     */
    @Override
    @SuppressWarnings({"unchecked"})
    public <T> T convertObject(Object sourceObject, Class<T> javaClass) throws ConversionException {
        if (sourceObject == null) {//Let the parent handle default null values
            return super.convertObject(null, javaClass);
        } else if (javaClass == null || javaClass == CoreClassConstants.OBJECT || sourceObject.getClass() == javaClass) {
            return (T) sourceObject;
        } else if (javaClass == CoreClassConstants.STRING) {
           if(sourceObject instanceof List){
               return (T) convertListToString(sourceObject, null);
           } else if (sourceObject instanceof Character[]) {
               return (T) convertObjectToString(sourceObject);
           } else if (sourceObject instanceof Object[]) {
               return (T) convertArrayToString((Object[]) sourceObject, null);
           } else {
               return (T) convertObjectToString(sourceObject);
           }
        } else if (javaClass == CoreClassConstants.ASTRING && sourceObject instanceof String) {
                return (T) convertStringToList(sourceObject).toArray(new String[] {});
        // TODO else if (javaClass == CoreClassConstants.ArrayList_class) {
        //        return convertStringToList((Object[]) sourceObject, null);
        } else if ((javaClass == Constants.QNAME_CLASS) && (sourceObject != null)) {
            return (T) convertObjectToQName(sourceObject);
        } else if ((javaClass == CoreClassConstants.List_Class) && (sourceObject instanceof String)) {
            return (T) convertStringToList(sourceObject);
        } else if ((javaClass == CoreClassConstants.CALENDAR)) {
            return (T) convertObjectToCalendar(sourceObject);
        } else if ((javaClass == CoreClassConstants.UTILDATE)) {
            return (T) convertObjectToUtilDate(sourceObject, Constants.DATE_TIME_QNAME);
        } else if ((javaClass == CoreClassConstants.SQLDATE)) {
            return (T) convertObjectToSQLDate(sourceObject, Constants.DATE_QNAME);
        } else if ((javaClass == CoreClassConstants.TIME)) {
            return (T) convertObjectToSQLTime(sourceObject, Constants.TIME_QNAME);
        } else if ((javaClass == CoreClassConstants.TIMESTAMP)) {
            return (T) convertObjectToTimestamp(sourceObject, Constants.DATE_TIME_QNAME);
        } else if ((javaClass == java.net.URI.class)) {
            return (T) convertObjectToURI(sourceObject);
        } else if ((javaClass == CoreClassConstants.XML_GREGORIAN_CALENDAR)) {
            return (T) convertObjectToXMLGregorianCalendar(sourceObject);
        } else if ((javaClass == CoreClassConstants.DURATION)) {
            return (T) convertObjectToDuration(sourceObject);
        } else if ((javaClass == CoreClassConstants.FILE) && (sourceObject instanceof String)) {
            return (T) convertStringToFile((String) sourceObject);
        } else if ((javaClass == Constants.UUID) && (sourceObject instanceof String)) {
            return (T) UUID.fromString((String) sourceObject);
        } else {
            try {
                return super.convertObject(sourceObject, javaClass);
            } catch (ConversionException ex) {
                if (sourceObject.getClass() == CoreClassConstants.STRING) {
                    return super.convertObject(((String) sourceObject).trim(), javaClass);
                }
                throw ex;
            }
        }
    }

    /**
     * Convert the given object to the appropriate type by invoking the appropriate
     * ConversionManager method.
     *
     * @param sourceObject - will always be a string if read from XML
     * @param javaClass - the class that the object must be converted to
     * @param schemaTypeQName - the XML schema that the object is being converted from
     * @return - the newly converted object
     */
    @Override
    @SuppressWarnings({"unchecked"})
    public <T> T convertObject(Object sourceObject, Class<T> javaClass, QName schemaTypeQName) throws ConversionException {
        if (schemaTypeQName == null) {
            return convertObject(sourceObject, javaClass);
        }

        if (sourceObject == null) {
            return super.convertObject(null, javaClass);
        } else if ((sourceObject.getClass() == javaClass) || (javaClass == null) || (javaClass == CoreClassConstants.OBJECT)) {
            return (T) sourceObject;
        } else if ((javaClass == CoreClassConstants.CALENDAR) || (javaClass == CoreClassConstants.GREGORIAN_CALENDAR)) {
            return (T) convertObjectToCalendar(sourceObject, schemaTypeQName);
        } else if (javaClass == CoreClassConstants.ABYTE) {
            if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.HEX_BINARY)) {
                return (T) super.convertObjectToByteObjectArray(sourceObject);
            } else if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.BASE_64_BINARY)) {
                return (T) convertSchemaBase64ToByteObjectArray(sourceObject);
            }
        } else if (javaClass == CoreClassConstants.APBYTE) {
            if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.HEX_BINARY)) {
                return (T) super.convertObjectToByteArray(sourceObject);
            } else if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.BASE_64_BINARY)) {
                return (T) convertSchemaBase64ToByteArray(sourceObject);
            }
        } else if ((javaClass == CoreClassConstants.List_Class) && (sourceObject instanceof String)) {
            return (T) convertStringToList(sourceObject);
        } else if ((javaClass == CoreClassConstants.STRING) && (sourceObject instanceof List)) {
            return (T) convertListToString(sourceObject, schemaTypeQName);
        } else if (sourceObject instanceof byte[]) {
            if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.BASE_64_BINARY)) {
                return (T) buildBase64StringFromBytes((byte[]) sourceObject);
            }
            return (T) Helper.buildHexStringFromBytes((byte[]) sourceObject);
        } else if (sourceObject instanceof Byte[]) {
            if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.BASE_64_BINARY)) {
                return (T) buildBase64StringFromObjectBytes((Byte[]) sourceObject);
            }
            return (T) buildHexStringFromObjectBytes((Byte[]) sourceObject);
        } else if ((javaClass == CoreClassConstants.STRING) && (sourceObject instanceof Object[])) {
            return (T) convertArrayToString((Object[]) sourceObject, schemaTypeQName);
        } else if ((javaClass == CoreClassConstants.UTILDATE)) {
            return (T) convertObjectToUtilDate(sourceObject, schemaTypeQName);
        } else if (javaClass == CoreClassConstants.SQLDATE) {
            return (T) convertObjectToSQLDate(sourceObject, schemaTypeQName);
        } else if (javaClass == CoreClassConstants.TIME) {
            return (T) convertObjectToSQLTime(sourceObject, schemaTypeQName);
        } else if (javaClass ==  CoreClassConstants.TIMESTAMP) {
            return (T) convertObjectToTimestamp(sourceObject, schemaTypeQName);
        } else if (javaClass == Constants.QNAME_CLASS) {
            return (T) convertObjectToQName(sourceObject);
        } else if (javaClass == CoreClassConstants.STRING) {
            return (T) convertObjectToString(sourceObject, schemaTypeQName);
        } else if ((javaClass == java.net.URI.class)) {
            return (T) convertObjectToURI(sourceObject);
        } else if ((javaClass == CoreClassConstants.XML_GREGORIAN_CALENDAR)) {
            return (T) convertObjectToXMLGregorianCalendar(sourceObject, schemaTypeQName);
        } else if ((javaClass == CoreClassConstants.DURATION)) {
            return (T) convertObjectToDuration(sourceObject);
        } else if ((javaClass == CoreClassConstants.CHAR)) {
            return (T) convertObjectToChar(sourceObject, schemaTypeQName);
        } else {
            try {
                return super.convertObject(sourceObject, javaClass);
            } catch (ConversionException ex) {
                if (sourceObject.getClass() == CoreClassConstants.STRING) {
                    return super.convertObject(((String) sourceObject).trim(), javaClass);
                }
                throw ex;
            }
        }

        throw ConversionException.couldNotBeConverted(sourceObject, javaClass);
    }

    /**
     * Build a valid instance of XMLGregorianCalendar from the provided sourceObject.
     *
     */
    protected XMLGregorianCalendar convertObjectToXMLGregorianCalendar(Object sourceObject, QName schemaTypeQName) throws ConversionException {
        if (sourceObject instanceof XMLGregorianCalendar) {
            return (XMLGregorianCalendar) sourceObject;
        }

        if (sourceObject instanceof String) {
            return convertStringToXMLGregorianCalendar((String) sourceObject, schemaTypeQName);
        }
        throw ConversionException.couldNotBeConverted(sourceObject, CoreClassConstants.XML_GREGORIAN_CALENDAR);
    }

    /**
     * Build a valid instance of XMLGregorianCalendar from the provided sourceObject.
     *
     */
    protected XMLGregorianCalendar convertObjectToXMLGregorianCalendar(Object sourceObject) throws ConversionException {
        if (sourceObject instanceof XMLGregorianCalendar) {
            return (XMLGregorianCalendar) sourceObject;
        }

        if (sourceObject instanceof String) {
            return convertStringToXMLGregorianCalendar((String) sourceObject);
        }
        throw ConversionException.couldNotBeConverted(sourceObject, CoreClassConstants.XML_GREGORIAN_CALENDAR);
    }

    /**
     * Build a valid instance of Duration from the provided sourceObject.
     *
     */
    protected Duration convertObjectToDuration(Object sourceObject) throws ConversionException {
        if (sourceObject instanceof Duration) {
            return (Duration) sourceObject;
        }
        if (sourceObject instanceof String) {
            return convertStringToDuration((String) sourceObject);
        }
        throw ConversionException.couldNotBeConverted(sourceObject, CoreClassConstants.DURATION);
    }

    /**
     * Build a valid instance of Character from the provided sourceObject.
     *
     */
    protected Character convertObjectToChar(Object sourceObject, QName schemaTypeQName) throws ConversionException {

        if (sourceObject == null || sourceObject.equals(Constants.EMPTY_STRING)) {
            return (char) 0;
        }

        if(sourceObject instanceof String && isNumericQName(schemaTypeQName)){
            int integer = Integer.parseInt((String)sourceObject);

            return (char) integer;

        }

        return super.convertObjectToChar(sourceObject);

    }

    /**
     * Build a valid instance of Character from the provided sourceObject.
     *
     */
    @Override
    protected Character convertObjectToChar(Object sourceObject) throws ConversionException {
        if (sourceObject == null || sourceObject.equals(Constants.EMPTY_STRING)) {
            return (char) 0;
        }

        return super.convertObjectToChar(sourceObject);
    }

    /**
     * Convert a String to a URI.
     *
     */
    protected java.net.URI convertObjectToURI(Object sourceObject) throws ConversionException {
        if (sourceObject instanceof String) {
            try {
                return new java.net.URI((String) sourceObject);
            } catch (Exception ex) {
            }
        }

        throw ConversionException.couldNotBeConverted(sourceObject, java.net.URI.class);
    }

    /**
     * INTERNAL:
     * Converts given object to a QName object
     */
    protected QName convertObjectToQName(Object sourceObject) throws ConversionException {
        if (sourceObject instanceof QName) {
            return (QName) sourceObject;
        }

        if (sourceObject instanceof String) {
            return qnameFromString((String) sourceObject);
        }

        throw ConversionException.couldNotBeConverted(sourceObject, Constants.QNAME_CLASS);
    }

    /**
     * INTERNAL:
     * Converts given object to a Calendar object
     */
    @Override
    protected Calendar convertObjectToCalendar(Object sourceObject) throws ConversionException {
        if (sourceObject instanceof String) {
            String sourceString = (String) sourceObject;
            if (sourceString.lastIndexOf('T') != -1) {
                return convertStringToCalendar((String) sourceObject, Constants.DATE_TIME_QNAME);
            } else {
                if (sourceString.lastIndexOf(Constants.COLON) != -1) {
                    return convertStringToCalendar((String) sourceObject, Constants.TIME_QNAME);
                } else {
                    return convertStringToCalendar((String) sourceObject, Constants.DATE_QNAME);
                }
            }
        }
        return super.convertObjectToCalendar(sourceObject);
    }

    /**
     * INTERNAL:
     * Converts objects to their string representations.
     */
    @Override
    protected String convertObjectToString(Object sourceObject) throws ConversionException {
        if (sourceObject instanceof Calendar) {
            return stringFromCalendar((Calendar) sourceObject);
        }
        if (sourceObject instanceof Character && sourceObject.equals((char) 0)) {
            return Constants.EMPTY_STRING;
        }
        if (sourceObject instanceof QName) {
            return stringFromQName((QName) sourceObject);
        }
        if (sourceObject instanceof java.sql.Date) {
            return stringFromSQLDate((java.sql.Date) sourceObject);
        }
        if (sourceObject instanceof java.sql.Time) {
            return stringFromSQLTime((java.sql.Time) sourceObject);
        }
        if (sourceObject instanceof java.sql.Timestamp) {
            return stringFromTimestamp((Timestamp) sourceObject);
        }
        if (sourceObject instanceof java.util.Date) {
            return stringFromDate((java.util.Date) sourceObject);
        }
        if (sourceObject instanceof XMLGregorianCalendar) {
            return stringFromXMLGregorianCalendar((XMLGregorianCalendar) sourceObject);
        }
        if (sourceObject instanceof Duration) {
            return stringFromDuration((Duration) sourceObject);
        }
        if(sourceObject instanceof Double){
            if(Double.POSITIVE_INFINITY == ((Double)sourceObject)){
                return Constants.POSITIVE_INFINITY;
            }
            if(Double.NEGATIVE_INFINITY == ((Double)sourceObject)){
                return Constants.NEGATIVE_INFINITY;
            }
            return sourceObject.toString();
        }
        if(sourceObject instanceof Float){
            if(Float.POSITIVE_INFINITY == ((Float)sourceObject)){
                return Constants.POSITIVE_INFINITY;
            }
            if(Float.NEGATIVE_INFINITY == ((Float)sourceObject)){
                return Constants.NEGATIVE_INFINITY;
            }
            return sourceObject.toString();
        }
        // Bug 21561562 - use plain, non-scientific notation for BigDecimal->String conversion
        if (sourceObject instanceof java.math.BigDecimal) {
            return ((java.math.BigDecimal) sourceObject).toPlainString();
        }

        return super.convertObjectToString(sourceObject);
    }

    protected String convertObjectToString(Object sourceObject, QName schemaTypeQName) throws ConversionException {
        if (sourceObject instanceof Calendar) {
            return stringFromCalendar((Calendar) sourceObject, schemaTypeQName);
        }
        if (sourceObject instanceof Character){

            if(isNumericQName(schemaTypeQName)){
                return Integer.toString((Character)sourceObject);
            } else {
                    if(sourceObject.equals((char) 0)) {
                        return Constants.EMPTY_STRING;
                    }
                   super.convertObjectToString(sourceObject);
            }
        }
        if (sourceObject instanceof QName) {
            return stringFromQName((QName) sourceObject);
        }
        if (sourceObject instanceof java.sql.Date) {
            return stringFromSQLDate((java.sql.Date) sourceObject, schemaTypeQName);
        }
        if (sourceObject instanceof java.sql.Time) {
            return stringFromSQLTime((java.sql.Time) sourceObject, schemaTypeQName);
        }
        if (sourceObject instanceof java.sql.Timestamp) {
            return stringFromTimestamp((Timestamp) sourceObject, schemaTypeQName);
        }
        if (sourceObject instanceof java.util.Date) {
            return stringFromDate((java.util.Date) sourceObject, schemaTypeQName);
        }
        if (sourceObject instanceof XMLGregorianCalendar) {
            return stringFromXMLGregorianCalendar((XMLGregorianCalendar) sourceObject, schemaTypeQName);
        }
        if (sourceObject instanceof Duration) {
            return stringFromDuration((Duration) sourceObject);
        }
        if(sourceObject instanceof Double){
            if(Double.POSITIVE_INFINITY == ((Double)sourceObject)){
                return Constants.POSITIVE_INFINITY;
            }
            if(Double.NEGATIVE_INFINITY == ((Double)sourceObject)){
                return Constants.NEGATIVE_INFINITY;
            }
            return sourceObject.toString();
        }
        if(sourceObject instanceof Float){
            if(Float.POSITIVE_INFINITY == ((Float)sourceObject)){
                return Constants.POSITIVE_INFINITY;
            }
            if(Float.NEGATIVE_INFINITY == ((Float)sourceObject)){
                return Constants.NEGATIVE_INFINITY;
            }
            return sourceObject.toString();
        }
        // Bug 21561562 - use plain, non-scientific notation for BigDecimal->String conversion
        if (sourceObject instanceof java.math.BigDecimal) {
            return ((java.math.BigDecimal) sourceObject).toPlainString();
        }

        return super.convertObjectToString(sourceObject);

    }

    private Calendar convertObjectToCalendar(Object sourceObject, QName schemaTypeQName) {
        if (sourceObject instanceof String) {
            return convertStringToCalendar((String) sourceObject, schemaTypeQName);
        }
        return super.convertObjectToCalendar(sourceObject);
    }

    @Override
    protected java.sql.Date convertObjectToDate(Object sourceObject) throws ConversionException {
        Object o = sourceObject;
        if (sourceObject instanceof Calendar) {
            // Clone the calendar, because calling get() methods
            // later on will alter the original calendar
            o = ((Calendar) sourceObject).clone();
        }
        return super.convertObjectToDate(o);
    }

    /**
     * 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.
     */
   @Override
   protected Double convertObjectToDouble(Object sourceObject) throws ConversionException {
       if (sourceObject instanceof String) {
           if(((String) sourceObject).length() == 0) {
               return 0d;
           }else if(Constants.POSITIVE_INFINITY.equals(sourceObject)){
               return Double.POSITIVE_INFINITY;
           }else if(Constants.NEGATIVE_INFINITY.equals(sourceObject)){
               return Double.NEGATIVE_INFINITY;
           }else{
               return super.convertObjectToDouble(sourceObject);
           }
       }else{
           return super.convertObjectToDouble(sourceObject);
       }
   }

   /**
    * 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.
    */
   @Override
   protected Float convertObjectToFloat(Object sourceObject) throws ConversionException {
       if (sourceObject instanceof String) {
           if(((String) sourceObject).length() == 0) {
               return 0f;
           } else if(Constants.POSITIVE_INFINITY.equals(sourceObject)){
               return Float.POSITIVE_INFINITY;
           }else if(Constants.NEGATIVE_INFINITY.equals(sourceObject)){
               return Float.NEGATIVE_INFINITY;
           }
       }
       return super.convertObjectToFloat(sourceObject);
   }

   /**
    * 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.
    */
   @Override
   protected Integer convertObjectToInteger(Object sourceObject) throws ConversionException {
       if(sourceObject instanceof String) {
           String sourceString = (String) sourceObject;
           if(sourceString.length() == 0) {
               return 0;
           } else if(sourceString.charAt(0) == PLUS) {
               return super.convertObjectToInteger(sourceString.substring(1));
           }
       }
       return super.convertObjectToInteger(sourceObject);
   }

   /**
    * 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.
    *
    */
  @Override
  protected Long convertObjectToLong(Object sourceObject) throws ConversionException {
      if(sourceObject instanceof String) {
          String sourceString = (String) sourceObject;
          if(sourceString.length() == 0) {
              return 0L;
          } else if(sourceString.charAt(0) == PLUS) {
              return super.convertObjectToLong(sourceString.substring(1));
          }
      }
      return super.convertObjectToLong(sourceObject);
  }

  /**
   * 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.
   */
  @Override
  protected Short convertObjectToShort(Object sourceObject) throws ConversionException {
      if(sourceObject instanceof String) {
          String sourceString = (String) sourceObject;
          if(sourceString.length() == 0) {
              return 0;
          } else if(sourceString.charAt(0) == PLUS) {
              return super.convertObjectToShort(sourceString.substring(1));
          }
      }
      return super.convertObjectToShort(sourceObject);
  }

  /**
   * 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.
   */
  @Override
  protected BigDecimal convertObjectToNumber(Object sourceObject) throws ConversionException {
      if(sourceObject instanceof String) {
          String sourceString = (String) sourceObject;
          if(sourceString.length() == 0) {
              return BigDecimal.ZERO;
          } else if(sourceString.charAt(0) == PLUS) {
              return super.convertObjectToNumber(sourceString.substring(1));
          }
      }
      return super.convertObjectToNumber(sourceObject);
  }

   /**
    * Build a valid instance of BigInteger from the provided sourceObject.
    *    @param sourceObject    Valid instance of String, BigDecimal, or any Number
    */
   @Override
   protected BigInteger convertObjectToBigInteger(Object sourceObject) throws ConversionException {
       if(sourceObject instanceof String) {
           String sourceString = (String) sourceObject;
           if(sourceString.length() == 0) {
               return null;
           } else if(sourceString.charAt(0) == PLUS) {
               return super.convertObjectToBigInteger(sourceString.substring(1));
           }
       }
       return super.convertObjectToBigInteger(sourceObject);
   }

   /**
    * Build a valid instance of BigDecimal from the given sourceObject
    *    @param sourceObject    Valid instance of String, BigInteger, any Number
    */
   @Override
   protected BigDecimal convertObjectToBigDecimal(Object sourceObject) throws ConversionException {
       if(sourceObject instanceof String) {
           String sourceString = (String) sourceObject;
           if(sourceString.length() == 0) {
               return null;
           }
           try {
               return new BigDecimal(sourceString);
           } catch (NumberFormatException exception) {
               throw ConversionException.couldNotBeConverted(sourceObject, CoreClassConstants.BIGDECIMAL, exception);
           }
       }
       return super.convertObjectToBigDecimal(sourceObject);
    }

   @Override
   protected Boolean convertObjectToBoolean(Object sourceObject) {
       if (sourceObject == null || sourceObject.equals(Constants.EMPTY_STRING)) {
           return false;
       }

       return super.convertObjectToBoolean(sourceObject);
   }

/**
    * 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.
    *
    */
    @Override
    protected Byte convertObjectToByte(Object sourceObject) throws ConversionException {
        if(sourceObject instanceof String) {
            String sourceString = (String) sourceObject;
            if(sourceString.length() == 0) {
                return 0;
            } else if(sourceString.charAt(0) == PLUS) {
                return super.convertObjectToByte(sourceString.substring(1));
            }
        }
        return super.convertObjectToByte(sourceObject);
    }

    public XMLGregorianCalendar convertStringToXMLGregorianCalendar(String sourceString, QName schemaTypeQName) {
        XMLGregorianCalendar xmlGregorianCalender = null;
        try {
            xmlGregorianCalender = convertStringToXMLGregorianCalendar(sourceString);
        } catch (Exception ex) {
             if (Constants.DATE_QNAME.equals(schemaTypeQName)) {
                 throw ConversionException.incorrectDateFormat(sourceString);
             } else if (Constants.TIME_QNAME.equals(schemaTypeQName)) {
                 throw ConversionException.incorrectTimeFormat(sourceString);
             } else if (Constants.G_DAY_QNAME.equals(schemaTypeQName)) {
                 throw XMLConversionException.incorrectGDayFormat(sourceString);
             } else if (Constants.G_MONTH_QNAME.equals(schemaTypeQName)) {
                 throw XMLConversionException.incorrectGMonthFormat(sourceString);
             } else if (Constants.G_MONTH_DAY_QNAME.equals(schemaTypeQName)) {
                 throw XMLConversionException.incorrectGMonthDayFormat(sourceString);
             } else if (Constants.G_YEAR_QNAME.equals(schemaTypeQName)) {
                 throw XMLConversionException.incorrectGYearFormat(sourceString);
             } else if (Constants.G_YEAR_MONTH_QNAME.equals(schemaTypeQName)) {
                 throw XMLConversionException.incorrectGYearMonthFormat(sourceString);
             } else if (Constants.DURATION_QNAME.equals(schemaTypeQName)) {
                 throw new IllegalArgumentException();
             } else {
                 throw ConversionException.incorrectDateTimeFormat(sourceString);
             }
        }

        if(xmlGregorianCalender == null){
            return null;
        }

        QName calendarQName = xmlGregorianCalender.getXMLSchemaType();
        if (!calendarQName.equals(schemaTypeQName)) {
            if (Constants.DATE_QNAME.equals(schemaTypeQName)) {
                if (calendarQName.equals(Constants.DATE_TIME_QNAME)) {
                    //clear out the time portion
                    xmlGregorianCalender.setHour(DatatypeConstants.FIELD_UNDEFINED);
                    xmlGregorianCalender.setMinute(DatatypeConstants.FIELD_UNDEFINED);
                    xmlGregorianCalender.setSecond(DatatypeConstants.FIELD_UNDEFINED);
                    xmlGregorianCalender.setMillisecond(DatatypeConstants.FIELD_UNDEFINED);
                    return xmlGregorianCalender;
                } else {
                    throw ConversionException.incorrectDateFormat(sourceString);
                }
             } else if (Constants.TIME_QNAME.equals(schemaTypeQName)) {
                 throw ConversionException.incorrectTimeFormat(sourceString);
             } else if (Constants.G_DAY_QNAME.equals(schemaTypeQName)) {
                 throw XMLConversionException.incorrectGDayFormat(sourceString);
             } else if (Constants.G_MONTH_QNAME.equals(schemaTypeQName)) {
                 throw XMLConversionException.incorrectGMonthFormat(sourceString);
             } else if (Constants.G_MONTH_DAY_QNAME.equals(schemaTypeQName)) {
                 throw XMLConversionException.incorrectGMonthDayFormat(sourceString);
             } else if (Constants.G_YEAR_QNAME.equals(schemaTypeQName)) {
                 throw XMLConversionException.incorrectGYearFormat(sourceString);
             } else if (Constants.G_YEAR_MONTH_QNAME.equals(schemaTypeQName)) {
                 throw XMLConversionException.incorrectGYearMonthFormat(sourceString);
             } else if (Constants.DURATION_QNAME.equals(schemaTypeQName)) {
                 throw new IllegalArgumentException();
             } else if (Constants.DATE_TIME_QNAME.equals(schemaTypeQName)) {
                 throw ConversionException.incorrectDateTimeFormat(sourceString);
             }
        }
        return xmlGregorianCalender;
    }

    /**
     * Return an XMLGregorianCalander created with a given date string
     *
     */
    public XMLGregorianCalendar convertStringToXMLGregorianCalendar(String sourceString) {
        // Trim in case of leading or trailing whitespace
        String trimmedSourceString = sourceString.trim();
        if(trimmedSourceString.length() == 0) {
            return null;
        }
        XMLGregorianCalendar calToReturn = null;
        try {
            calToReturn = getDatatypeFactory().newXMLGregorianCalendar(trimmedSourceString);
        } catch (IllegalArgumentException e1) {
            try {
                // GMonths may have different representations:
                // JDK 1.5: "--MM--"   JDK 1.6: "--MM"
                // If we caught an IllegalArgumentException, try the other syntax

                int length = trimmedSourceString.length();
                String retryString = null;
                if (length >= 6 && (trimmedSourceString.charAt(4) == '-') && (trimmedSourceString.charAt(5) == '-')) {
                    // Try to omit the trailing dashes if any (--MM--),
                    // but preserve time zone specifier, if any.
                    retryString = new StringBuilder(
                            trimmedSourceString.substring(0, 4)).append(
                            length > 6 ? trimmedSourceString.substring(6) : "")
                            .toString();
                } else if (length >= 4) {
                    // For "--MM" add the trailing dashes, preserving
                    // any trailing time zone specifier.
                    retryString = new StringBuilder(
                            trimmedSourceString.substring(0, 4)).append("--").append(
                            length > 4 ? trimmedSourceString.substring(4) : "")
                            .toString();
                }
                if (retryString != null) {
                    calToReturn = getDatatypeFactory().newXMLGregorianCalendar(retryString);
                } else {
                    throw e1;
                }
            } catch (IllegalArgumentException e2) {
                throw e1;
            }
        }

        return calToReturn;
    }

    /**
     * Return a Duration created with a given date string.
     *
     */
    public Duration convertStringToDuration(String sourceString) {
        if(sourceString == null || sourceString.length() == 0) {
            return null;
        }
        return getDatatypeFactory().newDuration(sourceString);
    }

    public Calendar convertStringToCalendar(String sourceString, QName schemaTypeQName) {
        XMLGregorianCalendar xmlGregorianCalender = convertStringToXMLGregorianCalendar(sourceString, schemaTypeQName);
        if(xmlGregorianCalender == null) {
            return null;
        }
        return toCalendar(xmlGregorianCalender);
    }

    private Date convertObjectToUtilDate(Object sourceObject, QName schemaTypeQName) {
        if (sourceObject instanceof String) {
            return convertStringToDate((String) sourceObject, schemaTypeQName);
        }
        return super.convertObjectToUtilDate(sourceObject);
    }

    protected java.sql.Date convertObjectToSQLDate(Object sourceObject, QName schemaTypeQName) {
        if (sourceObject instanceof String) {
            Date date = convertStringToDate((String) sourceObject, schemaTypeQName);
            return new java.sql.Date((date.getTime() / 1000) * 1000);
        }
        return convertObjectToDate(sourceObject);
    }

    protected Time convertObjectToSQLTime(Object sourceObject, QName schemaTypeQName) {
        if (sourceObject instanceof String) {
            Date date = convertStringToDate((String) sourceObject, schemaTypeQName);
            return new java.sql.Time((date.getTime() / 1000) * 1000);
        }
        return super.convertObjectToTime(sourceObject);
    }

    protected Timestamp convertStringToTimestamp(String sourceObject) {
        return convertStringToTimestamp(sourceObject, Constants.DATE_TIME_QNAME);
    }

    protected Timestamp convertObjectToTimestamp(Object sourceObject, QName schemaTypeQName) {
        if (sourceObject instanceof String) {
            return convertStringToTimestamp((String) sourceObject, schemaTypeQName);
        }
        return super.convertObjectToTimestamp(sourceObject);
    }

    public java.sql.Timestamp convertStringToTimestamp(String sourceString, QName schemaType) {

        XMLGregorianCalendar xmlGregorianCalender = null;
        try {
            xmlGregorianCalender = convertStringToXMLGregorianCalendar(sourceString);
        } catch(Exception ex) {

             if (Constants.DATE_QNAME.equals(schemaType)) {
                 throw ConversionException.incorrectDateFormat(sourceString);
             }else if (Constants.TIME_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectTimestampTimeFormat(sourceString);
             }else if (Constants.G_DAY_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectGDayFormat(sourceString);
             } else if (Constants.G_MONTH_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectGMonthFormat(sourceString);
             }else if (Constants.G_MONTH_DAY_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectGMonthDayFormat(sourceString);
             }else if (Constants.G_YEAR_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectGYearFormat(sourceString);
             }else if (Constants.G_YEAR_MONTH_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectGYearMonthFormat(sourceString);
             }else if (Constants.DURATION_QNAME.equals(schemaType)) {
                 throw new IllegalArgumentException();
             }else{
                 throw XMLConversionException.incorrectTimestampDateTimeFormat(sourceString);
             }
        }
        if(xmlGregorianCalender == null) {
            return null;
        }
        // Obtain a Calendar from the XMLGregorianCalendar for further usage
        Calendar cal = this.toCalendar(xmlGregorianCalender);
        if(xmlGregorianCalender.getTimezone() == DatatypeConstants.FIELD_UNDEFINED) {
            cal.setTimeZone(getTimeZone());
        }
        QName  calendarQName = xmlGregorianCalender.getXMLSchemaType();
        if(!calendarQName.equals(schemaType)){
            if (Constants.DATE_QNAME.equals(schemaType)){
                if(calendarQName.equals(Constants.DATE_TIME_QNAME)) {
                    //clear out the time portion
                    cal.clear(Calendar.HOUR_OF_DAY);
                    cal.clear(Calendar.MINUTE);
                    cal.clear(Calendar.SECOND);
                    cal.clear(Calendar.MILLISECOND);
                    return Helper.timestampFromCalendar(cal);

                }else{
                    throw ConversionException.incorrectDateFormat(sourceString);
                }
             }else if (Constants.TIME_QNAME.equals(schemaType)){
                 throw XMLConversionException.incorrectTimestampTimeFormat(sourceString);
             }else if (Constants.G_DAY_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectGDayFormat(sourceString);

             } else if (Constants.G_MONTH_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectGMonthFormat(sourceString);

             }else if (Constants.G_MONTH_DAY_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectGMonthDayFormat(sourceString);

             }else if (Constants.G_YEAR_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectGYearFormat(sourceString);

             }else if (Constants.G_YEAR_MONTH_QNAME.equals(schemaType)) {
                 throw XMLConversionException.incorrectGYearMonthFormat(sourceString);

             }else if (Constants.DURATION_QNAME.equals(schemaType)) {
                 throw new IllegalArgumentException();

             }else if (Constants.DATE_TIME_QNAME.equals(schemaType)) { //&& Constants.DATE_QNAME.equals(calendarQName)) {
                 throw XMLConversionException.incorrectTimestampDateTimeFormat(sourceString);

             }
        }
        Timestamp timestamp = Helper.timestampFromCalendar(cal);
        String trimmedSourceString = sourceString.trim();
        int decimalIndex = trimmedSourceString.lastIndexOf('.');

        if(-1 == decimalIndex) {
            return timestamp;
        }else{
            int timeZoneIndex = trimmedSourceString.lastIndexOf(GMT_SUFFIX);
            if(-1 == timeZoneIndex) {
                timeZoneIndex = trimmedSourceString.lastIndexOf('-');
                if(timeZoneIndex < decimalIndex) {
                    timeZoneIndex = -1;
                }
                if(-1 == timeZoneIndex) {
                    timeZoneIndex = trimmedSourceString.lastIndexOf('+');
                }

            }

            String nsString;
            if(-1 == timeZoneIndex) {
                nsString = trimmedSourceString.substring(decimalIndex + 1);
            } else {
                nsString = trimmedSourceString.substring((decimalIndex + 1), timeZoneIndex);
            }
            double ns = Long.valueOf(nsString).doubleValue();
            ns = ns * Math.pow(10, 9 - nsString.length());
            timestamp.setNanos((int) ns);
            return timestamp;
        }

    }

    public String stringFromCalendar(Calendar sourceCalendar, QName schemaTypeQName) {
        // Clone the calendar, because calling get() methods will
        // alter the original calendar
        Calendar cal = (Calendar) sourceCalendar.clone();

        XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();
        // use the timezone info on source calendar, if any
        boolean isTimeZoneSet = sourceCalendar.isSet(Calendar.ZONE_OFFSET);
        if (isTimeZoneSet) {
            if(sourceCalendar.isSet(Calendar.DST_OFFSET)) {
                xgc.setTimezone((cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / 60000);
            } else {
                xgc.setTimezone((cal.get(Calendar.ZONE_OFFSET)) / 60000);
            }
        }

        // gDay
        if (Constants.G_DAY_QNAME.equals(schemaTypeQName)) {
            xgc.setDay(cal.get(Calendar.DATE));
            return xgc.toXMLFormat();
        }
        // gMonth
        if (Constants.G_MONTH_QNAME.equals(schemaTypeQName)) {
            //There was previously some workaround in the method for handling gMonth and the older/invalid
            //--MM-- format.  Output should now always be in the --MM format
            //bug #410084
            xgc.setMonth(cal.get(Calendar.MONTH) + 1);
            String xmlFormat = xgc.toXMLFormat();
            int lastDashIndex = xmlFormat.lastIndexOf('-');
            if(lastDashIndex > 1){
                //this means the format is the --MM--, --MM--Z, --MM--+03:00 and we need to trim the String
                String pre = xmlFormat.substring(0, 4);
                if(xmlFormat.length() > 6){
                    String post = xmlFormat.substring(6, xmlFormat.length());
                    return pre + post;
                }else{
                    return pre;
                }
            }
            return xmlFormat;

        }
        // gMonthDay
        if (Constants.G_MONTH_DAY_QNAME.equals(schemaTypeQName)) {
            xgc.setMonth(cal.get(Calendar.MONTH) + 1);
            xgc.setDay(cal.get(Calendar.DATE));
            return xgc.toXMLFormat();
        }
        // gYear
        if (Constants.G_YEAR_QNAME.equals(schemaTypeQName)) {
            if (cal.get(Calendar.ERA) == GregorianCalendar.BC){
                xgc.setYear(-cal.get(Calendar.YEAR));
            } else {
                xgc.setYear(cal.get(Calendar.YEAR));
            }
            return xgc.toXMLFormat();
        }
        // gYearMonth
        if (Constants.G_YEAR_MONTH_QNAME.equals(schemaTypeQName)) {
            if (cal.get(Calendar.ERA) == GregorianCalendar.BC){
                xgc.setYear(-cal.get(Calendar.YEAR));
            } else {
                xgc.setYear(cal.get(Calendar.YEAR));
            }
            xgc.setMonth(cal.get(Calendar.MONTH) + 1);
            return xgc.toXMLFormat();
        }
        // Date
        if (Constants.DATE_QNAME.equals(schemaTypeQName)) {
            if (cal.get(Calendar.ERA) == GregorianCalendar.BC){
                xgc.setYear(-cal.get(Calendar.YEAR));
            } else {
                xgc.setYear(cal.get(Calendar.YEAR));
            }
            xgc.setMonth(cal.get(Calendar.MONTH) + 1);
            xgc.setDay(cal.get(Calendar.DATE));
            return xgc.toXMLFormat();
        }
        // Time
        if (Constants.TIME_QNAME.equals(schemaTypeQName)) {
            int milliseconds = cal.get(Calendar.MILLISECOND);
            if(0 == milliseconds) {
                milliseconds = DatatypeConstants.FIELD_UNDEFINED;
            }
            xgc.setTime(
                    cal.get(Calendar.HOUR_OF_DAY),
                    cal.get(Calendar.MINUTE),
                    cal.get(Calendar.SECOND),
                    milliseconds);
            if(!isTimeZoneSet && isTimeZoneQualified()) {
                xgc.setTimezone(getTimeZone().getOffset(sourceCalendar.getTimeInMillis()) / 60000);
            }
            return truncateMillis(xgc.toXMLFormat());
        }
        // DateTime
        if (cal.get(Calendar.ERA) == GregorianCalendar.BC){
            xgc.setYear(-cal.get(Calendar.YEAR));
        } else {
            xgc.setYear(cal.get(Calendar.YEAR));
        }
        xgc.setMonth(cal.get(Calendar.MONTH) + 1);
        xgc.setDay(cal.get(Calendar.DATE));
        int milliseconds = cal.get(Calendar.MILLISECOND);
        if(0 == milliseconds) {
            milliseconds = DatatypeConstants.FIELD_UNDEFINED;
        }
        xgc.setTime(
                cal.get(Calendar.HOUR_OF_DAY),
                cal.get(Calendar.MINUTE),
                cal.get(Calendar.SECOND),
                milliseconds);
        if(!isTimeZoneSet && isTimeZoneQualified()) {
            xgc.setTimezone(getTimeZone().getOffset(sourceCalendar.getTimeInMillis()) / 60000);
        }
        return truncateMillis(xgc.toXMLFormat());
    }

    /**
     * Truncate any trailing zeros from the millisecond portion of a given string.
     * The string is assumed to be in dateTime or time format, as returned by
     * XMLGregorianCalendar.toXMLFormat().
     *
     */
    private String truncateMillis(String xmlFormat) {
        String result = xmlFormat;
        int dotIdx = xmlFormat.indexOf('.');
        if (dotIdx > 0) {
            String pre = xmlFormat.substring(0, dotIdx);
            String post = Constants.EMPTY_STRING;
            if (xmlFormat.length() > (dotIdx + 4)) {
                post = xmlFormat.substring(dotIdx + 4, xmlFormat.length());
            }
            String milliStr = xmlFormat.substring(dotIdx + 1, dotIdx + 4);
            char[] numbChar = new char[milliStr.length()];
            milliStr.getChars(0, milliStr.length(), numbChar, 0);
            int truncIndex = 2;
            while (truncIndex >= 1 && numbChar[truncIndex] == '0') {
                truncIndex--;
            }
            milliStr = new String(numbChar, 0, truncIndex + 1);
            if (milliStr.length() > 0 && !"0".equals(milliStr)) {
                milliStr = '.' + milliStr;
                result = pre + milliStr + post;
            } else {
                result = pre + OXMSystemProperties.xmlConversionTimeSuffix + post;
            }
        }
        return result;
    }

    private String stringFromCalendar(Calendar sourceCalendar) {
        if (!(sourceCalendar.isSet(Calendar.HOUR) || sourceCalendar.isSet(Calendar.MINUTE) || sourceCalendar.isSet(Calendar.SECOND) || sourceCalendar.isSet(Calendar.MILLISECOND))) {
            return stringFromCalendar(sourceCalendar, Constants.DATE_QNAME);
        } else if (!(sourceCalendar.isSet(Calendar.YEAR) || sourceCalendar.isSet(Calendar.MONTH) || sourceCalendar.isSet(Calendar.DATE))) {
            return stringFromCalendar(sourceCalendar, Constants.TIME_QNAME);
        } else {
            return stringFromCalendar(sourceCalendar, Constants.DATE_TIME_QNAME);
        }
    }

    public java.util.Date convertStringToDate(String sourceString, QName schemaType) {
        XMLGregorianCalendar xmlGregorianCalender = convertStringToXMLGregorianCalendar(sourceString, schemaType);
        if(xmlGregorianCalender == null) {
            return null;
        }
        Calendar cal = toCalendar(xmlGregorianCalender);

        return cal.getTime();
    }

    private Calendar toCalendar(XMLGregorianCalendar xgc) {
        TimeZone tz = null;

        if (xgc.getTimezone() == DatatypeConstants.FIELD_UNDEFINED) {
            tz = getTimeZone();
        } else {
            tz = xgc.getTimeZone(xgc.getTimezone());
        }


        Calendar cal = Calendar.getInstance(tz, Locale.getDefault());
        cal.clear();

        if (xgc.getTimezone() != DatatypeConstants.FIELD_UNDEFINED) {
            cal.set(Calendar.ZONE_OFFSET, xgc.getTimezone() * 60000);
        }

        BigInteger year = xgc.getEonAndYear();
        if (year != null) {
            cal.set(Calendar.ERA, year.signum() < 0 ? GregorianCalendar.BC : GregorianCalendar.AD);
            cal.set(Calendar.YEAR, year.abs().intValue());
        }

        if (xgc.getDay() != DatatypeConstants.FIELD_UNDEFINED)
            cal.set(Calendar.DAY_OF_MONTH, xgc.getDay());

        if (xgc.getMonth() != DatatypeConstants.FIELD_UNDEFINED)
            cal.set(Calendar.MONTH, xgc.getMonth() - 1);

        if (xgc.getHour() != DatatypeConstants.FIELD_UNDEFINED)
            cal.set(Calendar.HOUR_OF_DAY, xgc.getHour());

        if (xgc.getMinute() != DatatypeConstants.FIELD_UNDEFINED)
            cal.set(Calendar.MINUTE, xgc.getMinute());

        if (xgc.getSecond() != DatatypeConstants.FIELD_UNDEFINED)
            cal.set(Calendar.SECOND, xgc.getSecond());

        if (xgc.getFractionalSecond() != null)
            cal.set(Calendar.MILLISECOND, xgc.getMillisecond());

        return cal;
    }

    /**
     * This method returns a dateTime string representing a given
     * java.util.Date.
     *
     * BC dates {@code (sourceDate.getTime() < YEAR_ONE_AD_TIME)} are handled
     * as follows: {@code '2007 BC' --> '-2006 AD'}
     *
     */
    private String stringFromDate(java.util.Date sourceDate) {
        GregorianCalendar cal = new GregorianCalendar(getTimeZone());
        cal.setTime(sourceDate);
        XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar(cal);

        String string =  xgc.toXMLFormat();
        string = truncateMillis(string);
        return string;
    }

    /**
     * This method returns a string representing a given java.util.Date
     * based on a given schema type QName.
     *
     * BC dates (sourceDate.getTime() &lt; YEAR_ONE_AD_TIME) are handled
     * as follows: '2007 BC' --&gt; '-2006 AD'.
     *
     */
    public String stringFromDate(java.util.Date sourceDate, QName schemaType) {

        XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();


        if (Constants.DATE_QNAME.equals(schemaType)) {

            GregorianCalendar cal = new GregorianCalendar(getTimeZone());
            cal.setTime(sourceDate);

            xgc.setDay(cal.get(Calendar.DAY_OF_MONTH));
            xgc.setMonth(cal.get(Calendar.MONTH)+1);
            if(cal.get(Calendar.ERA) == GregorianCalendar.BC){
                xgc.setYear(-cal.get(Calendar.YEAR));
            }else{
                xgc.setYear(cal.get(Calendar.YEAR));
            }

            return xgc.toXMLFormat();

        }
        if (Constants.TIME_QNAME.equals(schemaType)) {

            GregorianCalendar cal = new GregorianCalendar(getTimeZone());
            cal.setTime(sourceDate);

            xgc.setHour(cal.get(Calendar.HOUR_OF_DAY));
            xgc.setMinute(cal.get(Calendar.MINUTE));
            xgc.setSecond(cal.get(Calendar.SECOND));

            String string = xgc.toXMLFormat();
            string = appendMillis(string, sourceDate.getTime());
            return appendTimeZone(string, sourceDate);
        }
        if (Constants.G_DAY_QNAME.equals(schemaType)) {
            GregorianCalendar cal = new GregorianCalendar(getTimeZone());
            cal.setTime(sourceDate);
            xgc.setDay(cal.get(Calendar.DATE));
            return xgc.toXMLFormat();
        }
        if (Constants.G_MONTH_QNAME.equals(schemaType)) {
            GregorianCalendar cal = new GregorianCalendar(getTimeZone());
            cal.setTime(sourceDate);

            xgc.setMonth(cal.get(Calendar.MONTH)+1);

            return stringFromXMLGregorianCalendar(xgc, schemaType);
        }
        if (Constants.G_MONTH_DAY_QNAME.equals(schemaType)) {
            GregorianCalendar cal = new GregorianCalendar(getTimeZone());
            cal.setTime(sourceDate);
            xgc.setMonth(cal.get(Calendar.MONTH)+1);
            xgc.setDay(cal.get(Calendar.DAY_OF_MONTH));
            return xgc.toXMLFormat();
        }
        if (Constants.G_YEAR_QNAME.equals(schemaType)) {
            GregorianCalendar cal = new GregorianCalendar(getTimeZone());
            cal.setTime(sourceDate);
            if(cal.get(Calendar.ERA) == GregorianCalendar.BC){
                xgc.setYear(-cal.get(Calendar.YEAR));
            }else{
                xgc.setYear(cal.get(Calendar.YEAR));
            }

            return xgc.toXMLFormat();
        }
        if (Constants.G_YEAR_MONTH_QNAME.equals(schemaType)) {
            GregorianCalendar cal = new GregorianCalendar(getTimeZone());
            cal.setTime(sourceDate);
            if(cal.get(Calendar.ERA) == GregorianCalendar.BC){
                xgc.setYear(-cal.get(Calendar.YEAR));
            }else{
                xgc.setYear(cal.get(Calendar.YEAR));
            }
            xgc.setMonth(cal.get(Calendar.MONTH)+1);

            return xgc.toXMLFormat();
        }
        if (Constants.DURATION_QNAME.equals(schemaType)) {
            throw new IllegalArgumentException();
        }
        // default is dateTime
        return stringFromDate(sourceDate);
    }

    private String stringFromSQLDate(java.sql.Date sourceDate) {
        XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();

        Calendar cal = Calendar.getInstance(getTimeZone());
        cal.setTime(sourceDate);

        if(cal.get(Calendar.ERA) == GregorianCalendar.BC){
            xgc.setYear(-cal.get(Calendar.YEAR));
        }else{
            xgc.setYear(cal.get(Calendar.YEAR));
        }
        xgc.setMonth(cal.get(Calendar.MONTH)+1);
        xgc.setDay(cal.get(Calendar.DAY_OF_MONTH));

        return xgc.toXMLFormat();
    }

    private String stringFromSQLDate(java.sql.Date sourceDate, QName schemaType) {
        if(null == schemaType) {
            return stringFromSQLDate(sourceDate);
        } else {
            return stringFromDate(sourceDate, schemaType);
        }
    }

    private String stringFromSQLTime(Time sourceTime) {
        XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();

        Calendar cal = Calendar.getInstance(getTimeZone());
        cal.setTime(sourceTime);

        xgc.setHour(cal.get(Calendar.HOUR_OF_DAY));
        xgc.setMinute(cal.get(Calendar.MINUTE));
        xgc.setSecond(cal.get(Calendar.SECOND));

        String string= xgc.toXMLFormat();
        string = appendMillis(string, sourceTime.getTime());
        return appendTimeZone(string, sourceTime);
    }

    private String stringFromSQLTime(Time sourceTime, QName schemaType) {
        if(null == schemaType) {
            return stringFromSQLTime(sourceTime);
        } else {
            return stringFromDate(sourceTime, schemaType);
        }
    }


    /**
     * This method returns a dateTime string representing a given
     * Timestamp.
     *
     * BC dates {@code (sourceDate.getTime() < YEAR_ONE_AD_TIME)} are handled
     * as follows: {@code '2007 BC' --> '-2006 AD'}
     *
     */
    private String stringFromTimestamp(Timestamp sourceDate) {
        Calendar cal = Calendar.getInstance(getTimeZone());
        cal.setTime(sourceDate);

        XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();
        if(cal.get(Calendar.ERA)== GregorianCalendar.BC){
            xgc.setYear(-cal.get(Calendar.YEAR));
        }else{
            xgc.setYear(cal.get(Calendar.YEAR));
        }
        xgc.setMonth(cal.get(Calendar.MONTH)+1);
        xgc.setDay(cal.get(Calendar.DAY_OF_MONTH));

        xgc.setHour(cal.get(Calendar.HOUR_OF_DAY));
        xgc.setMinute(cal.get(Calendar.MINUTE));
        xgc.setSecond(cal.get(Calendar.SECOND));

        String string= xgc.toXMLFormat();
        string = appendNanos(string, sourceDate);
        return appendTimeZone(string, sourceDate);
    }

    /**
     * This method returns a string representing a given Timestamp
     * based on a given schema type QName.
     *
     * BC dates {@code (sourceDate.getTime() < YEAR_ONE_AD_TIME)} are handled
     * as follows: {@code '2007 BC' --> '-2006 AD'}.
     *
     */
    private String stringFromTimestamp(Timestamp sourceDate, QName schemaType) {

        if (Constants.DATE_QNAME.equals(schemaType)) {
            Calendar cal = Calendar.getInstance(getTimeZone());
            cal.setTime(sourceDate);

            XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();

            if(cal.get(Calendar.ERA) == GregorianCalendar.BC){
                xgc.setYear(-cal.get(Calendar.YEAR));
            }else{
                xgc.setYear(cal.get(Calendar.YEAR));
            }
            xgc.setMonth(cal.get(Calendar.MONTH)+1);
            xgc.setDay(cal.get(Calendar.DAY_OF_MONTH));

            return xgc.toXMLFormat();
        }
        if (Constants.TIME_QNAME.equals(schemaType)) {

            Calendar cal = Calendar.getInstance(getTimeZone());
            cal.setTimeInMillis(sourceDate.getTime());

            XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();
            xgc.setHour(cal.get(Calendar.HOUR_OF_DAY));
            xgc.setMinute(cal.get(Calendar.MINUTE));
            xgc.setSecond(cal.get(Calendar.SECOND));

            String string = xgc.toXMLFormat();
            string = appendNanos(string, sourceDate);
            return appendTimeZone(string, sourceDate);
        }
        if (Constants.G_DAY_QNAME.equals(schemaType)) {
            XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();
            Calendar cal = Calendar.getInstance(getTimeZone());
            cal.setTime(sourceDate);

            xgc.setDay(cal.get(Calendar.DAY_OF_MONTH));

            return xgc.toXMLFormat();
        }
        if (Constants.G_MONTH_QNAME.equals(schemaType)) {
             XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();
             Calendar cal = Calendar.getInstance(getTimeZone());
             cal.setTime(sourceDate);

            xgc.setMonth(cal.get(Calendar.MONTH)+1);

            return stringFromXMLGregorianCalendar(xgc, schemaType);
        }
        if (Constants.G_MONTH_DAY_QNAME.equals(schemaType)) {

             XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();
             Calendar cal = Calendar.getInstance(getTimeZone());
             cal.setTime(sourceDate);

             xgc.setMonth(cal.get(Calendar.MONTH)+1);
             xgc.setDay(cal.get(Calendar.DAY_OF_MONTH));
             return xgc.toXMLFormat();
        }
        if (Constants.G_YEAR_QNAME.equals(schemaType)) {
             XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();
             Calendar cal = Calendar.getInstance(getTimeZone());
             cal.setTime(sourceDate);

            if(cal.get(Calendar.ERA) == GregorianCalendar.BC){
                xgc.setYear(-cal.get(Calendar.YEAR));
            }else{
                xgc.setYear(cal.get(Calendar.YEAR));
            }

            return xgc.toXMLFormat();
        }
        if (Constants.G_YEAR_MONTH_QNAME.equals(schemaType)) {
            XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();
            Calendar cal = Calendar.getInstance(getTimeZone());
            cal.setTime(sourceDate);
            if(cal.get(Calendar.ERA) == GregorianCalendar.BC){
                xgc.setYear(-cal.get(Calendar.YEAR));
            }else{
                xgc.setYear(cal.get(Calendar.YEAR));
            }
            xgc.setMonth(cal.get(Calendar.MONTH)+1);

            return xgc.toXMLFormat();
        }
        if (Constants.DURATION_QNAME.equals(schemaType)) {
            throw new IllegalArgumentException();
        }
        // default is dateTime
        XMLGregorianCalendar xgc = getDatatypeFactory().newXMLGregorianCalendar();
        Calendar cal = Calendar.getInstance(getTimeZone());
        cal.setTime(sourceDate);
        if(cal.get(Calendar.ERA) == GregorianCalendar.BC){
            xgc.setYear(-cal.get(Calendar.YEAR));
        }else{
            xgc.setYear(cal.get(Calendar.YEAR));
        }
        xgc.setMonth(cal.get(Calendar.MONTH)+1);
        xgc.setDay(cal.get(Calendar.DAY_OF_MONTH));

        xgc.setHour(cal.get(Calendar.HOUR_OF_DAY));
        xgc.setMinute(cal.get(Calendar.MINUTE));
        xgc.setSecond(cal.get(Calendar.SECOND));

        String string= xgc.toXMLFormat();

        string = appendNanos(string, sourceDate);
        return appendTimeZone(string, sourceDate);
    }

    private String stringFromXMLGregorianCalendar(XMLGregorianCalendar cal, QName schemaTypeQName) {
        if(schemaTypeQName !=null && schemaTypeQName.equals(cal.getXMLSchemaType()) && schemaTypeQName != Constants.G_MONTH_QNAME){
          return cal.toXMLFormat();
        }
        GregorianCalendar gCal = cal.toGregorianCalendar();
        if(cal.getTimezone() == DatatypeConstants.FIELD_UNDEFINED) {
            gCal.clear(Calendar.ZONE_OFFSET);
        }
        return  stringFromCalendar(gCal, schemaTypeQName);
    }

    private String stringFromXMLGregorianCalendar(XMLGregorianCalendar cal) {
        return cal.toXMLFormat();
    }

    private String stringFromDuration(Duration dur) {
        return dur.toString();
    }

    private String stringFromQName(QName sourceQName) {
        // String will be formatted as: {namespaceURI}localPart
        return sourceQName.toString();
    }

    private QName qnameFromString(String sourceString) {
        // String will be formatted as: {namespaceURI}localPart
        if (sourceString.indexOf('{') != -1) {
            String uri = sourceString.substring(sourceString.indexOf('{') + 1, sourceString.indexOf('}'));
            String localpart = sourceString.substring(sourceString.indexOf('}') + 1);
            return new QName(uri, localpart);
        } else {
            return new QName(sourceString);
        }
    }

    /**
     * INTERNAL:
     * Converts a String which is in Base64 format to a Byte[]
     */
    @Override
    public byte[] convertSchemaBase64ToByteArray(Object sourceObject) throws ConversionException {
        if (sourceObject instanceof String) {
            //the base64 string may have contained embedded whitespaces. Try again after
            //Removing any whitespaces.
            StringTokenizer tokenizer = new StringTokenizer((String)sourceObject);
            StringBuilder builder = new StringBuilder();
            while(tokenizer.hasMoreTokens()) {
                builder.append(tokenizer.nextToken());
            }
            byte[] bytes = Base64.base64Decode(builder.toString().getBytes());
            return bytes;
        }
        return convertObjectToByteArray(sourceObject);
    }

    @Override
    public Object convertSchemaBase64ListToByteArrayList(Object sourceObject, CoreContainerPolicy containerPolicy, CoreAbstractSession session) throws ConversionException {
        if (sourceObject instanceof String) {
            StringTokenizer tokenizer = new StringTokenizer((String) sourceObject, " ");
            Object container = containerPolicy.containerInstance();
            while (tokenizer.hasMoreElements()) {
                String token = tokenizer.nextToken();
                byte[] bytes = Base64.base64Decode(token.getBytes());
                containerPolicy.addInto(bytes, container, session);
            }
            return container;
        }
        throw ConversionException.couldNotBeConverted(sourceObject, CoreClassConstants.ABYTE);
    }


    protected Byte[] convertSchemaBase64ToByteObjectArray(Object sourceObject) throws ConversionException {
        byte[] bytes = convertSchemaBase64ToByteArray(sourceObject);
        Byte[] objectBytes = new Byte[bytes.length];
        for (int index = 0; index < bytes.length; index++) {
            objectBytes[index] = bytes[index];
        }
        return objectBytes;
    }

    @Override
    public String buildBase64StringFromBytes(byte[] bytes) {
        byte[] convertedBytes = Base64.base64Encode(bytes);
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < convertedBytes.length; i++) {
            buffer.append((char) convertedBytes[i]);
        }
        return buffer.toString();
    }

    public String buildBase64StringFromObjectBytes(Byte[] bytes) {
        byte[] primitiveBytes = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            primitiveBytes[i] = bytes[i];
        }
        return buildBase64StringFromBytes(primitiveBytes);
    }

    protected String buildHexStringFromObjectBytes(Byte[] bytes) {
        byte[] primitiveBytes = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            primitiveBytes[i] = bytes[i];
        }
        return Helper.buildHexStringFromBytes(primitiveBytes);
    }

    protected List<String> convertStringToList(Object sourceObject) throws ConversionException {
        List<String> list = new ArrayList<>();
        if (sourceObject instanceof String) {
            StringTokenizer tokenizer = new StringTokenizer((String) sourceObject, " ");
            while (tokenizer.hasMoreElements()) {
                String token = tokenizer.nextToken();
                list.add(token);
            }
        }
        return list;
    }

    protected File convertStringToFile(String path) {
        if(path == null || path.length() == 0) {
            return null;
        }
        return new File(path);
    }

    /**
     * Convert the given sourceObject (String) to the appropriate collection type specified by the
     * containerPolicy, using the elementType to properly convert each element of the list.
     *
     * @param sourceObject - will always be a string if read from XML
     * @param elementType - the type of the elements contained in the list
     * @return - the newly converted object
     */
    public <T> Collection<T> convertStringToList(Object sourceObject, Class<T> elementType, ContainerPolicy containerPolicy, QName schemaType) throws ConversionException {
        Collection<T> collection = (Collection<T>) containerPolicy.containerInstance();

        if (sourceObject instanceof String) {
            StringTokenizer tokenizer = new StringTokenizer((String) sourceObject, " ");
            while (tokenizer.hasMoreElements()) {
                String token = tokenizer.nextToken();
                collection.add(convertObject(token, elementType,schemaType ));
            }
        }

        return collection;
    }

    public String convertListToString(Object sourceObject, QName schemaType) throws ConversionException {
        StringBuilder returnStringBuilder = new StringBuilder();
        if (sourceObject instanceof List) {
            List<?> list = (List<?>) sourceObject;
            for (int i = 0, listSize = list.size(); i < listSize; i++) {
                Object next = list.get(i);
                if (i > 0) {
                    returnStringBuilder.append(' ');
                }
                returnStringBuilder.append(convertObject(next, next.getClass().getComponentType(), schemaType));
            }
        }
        return returnStringBuilder.toString();
    }

    public String convertArrayToString(Object[] sourceObject, QName schemaType) throws ConversionException {
        StringBuilder returnStringBuilder = new StringBuilder();
        for (int i = 0, listSize = sourceObject.length; i < listSize; i++) {
            Object next = sourceObject[i];
            if (i > 0) {
                returnStringBuilder.append(' ');
            }
            returnStringBuilder.append(convertObject(next, next.getClass().getComponentType(), schemaType));
        }
        return returnStringBuilder.toString();
    }

    public static Map<QName, Class<?>> getDefaultXMLTypes() {
        if (defaultXMLTypes == null) {
            defaultXMLTypes = buildXMLTypes();
        }
        return defaultXMLTypes;
    }

    public static Map<Class<?>, QName> getDefaultJavaTypes() {
        if (defaultJavaTypes == null) {
            defaultJavaTypes = buildJavaTypes();
        }
        return defaultJavaTypes;
    }

    /**
    * Build and return a Hashtable containing the default XML to Java conversion pairs
    */
    private static Map<QName, Class<?>> buildXMLTypes() {
        Map<QName, Class<?>> XMLTypes = new HashMap<>();

        //jaxb 1.0 spec pairs
        XMLTypes.put(Constants.ANY_SIMPLE_TYPE_QNAME, CoreClassConstants.STRING);
        XMLTypes.put(Constants.BASE_64_BINARY_QNAME, CoreClassConstants.APBYTE);
        XMLTypes.put(Constants.BOOLEAN_QNAME, CoreClassConstants.PBOOLEAN);
        XMLTypes.put(Constants.BYTE_QNAME, CoreClassConstants.PBYTE);
        XMLTypes.put(Constants.DATE_QNAME, CoreClassConstants.CALENDAR);
        XMLTypes.put(Constants.DATE_TIME_QNAME, CoreClassConstants.CALENDAR);
        XMLTypes.put(Constants.DECIMAL_QNAME, CoreClassConstants.BIGDECIMAL);
        XMLTypes.put(Constants.DOUBLE_QNAME, CoreClassConstants.PDOUBLE);
        XMLTypes.put(Constants.FLOAT_QNAME, CoreClassConstants.PFLOAT);
        XMLTypes.put(Constants.HEX_BINARY_QNAME, CoreClassConstants.APBYTE);
        XMLTypes.put(Constants.INT_QNAME, CoreClassConstants.PINT);
        XMLTypes.put(Constants.INTEGER_QNAME, CoreClassConstants.BIGINTEGER);
        XMLTypes.put(Constants.LONG_QNAME, CoreClassConstants.PLONG);
        XMLTypes.put(Constants.NAME_QNAME, CoreClassConstants.STRING);
        XMLTypes.put(Constants.NCNAME_QNAME, CoreClassConstants.STRING);
        XMLTypes.put(Constants.QNAME_QNAME, Constants.QNAME_CLASS);
        XMLTypes.put(Constants.SHORT_QNAME, CoreClassConstants.PSHORT);
        XMLTypes.put(Constants.STRING_QNAME, CoreClassConstants.STRING);
        XMLTypes.put(Constants.TIME_QNAME, CoreClassConstants.CALENDAR);
        XMLTypes.put(Constants.UNSIGNED_BYTE_QNAME, CoreClassConstants.PSHORT);
        XMLTypes.put(Constants.UNSIGNED_INT_QNAME, CoreClassConstants.PLONG);
        XMLTypes.put(Constants.UNSIGNED_SHORT_QNAME, CoreClassConstants.PINT);

        XMLTypes.put(Constants.DURATION_QNAME,  CoreClassConstants.DURATION);
        XMLTypes.put(Constants.G_DAY_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR);
        XMLTypes.put(Constants.G_MONTH_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR);
        XMLTypes.put(Constants.G_MONTH_DAY_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR);
        XMLTypes.put(Constants.G_YEAR_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR);
        XMLTypes.put(Constants.G_YEAR_MONTH_QNAME, CoreClassConstants.XML_GREGORIAN_CALENDAR);

        XMLTypes.put(Constants.NEGATIVE_INTEGER_QNAME, CoreClassConstants.BIGINTEGER);
        XMLTypes.put(Constants.NOTATION_QNAME, Constants.QNAME_CLASS);
        XMLTypes.put(Constants.NON_NEGATIVE_INTEGER_QNAME, CoreClassConstants.BIGINTEGER);
        XMLTypes.put(Constants.NON_POSITIVE_INTEGER_QNAME,CoreClassConstants.BIGINTEGER);
        XMLTypes.put(Constants.NORMALIZEDSTRING_QNAME, CoreClassConstants.STRING);
        XMLTypes.put(Constants.POSITIVE_INTEGER_QNAME, CoreClassConstants.BIGINTEGER);
        XMLTypes.put(Constants.UNSIGNED_LONG_QNAME, CoreClassConstants.BIGINTEGER);


        return XMLTypes;
    }

    /**
     * Build and return a Hashtable containing the default Java to XML conversion pairs
     */
    private static Map<Class<?>, QName> buildJavaTypes() {
        Map<Class<?>, QName> javaTypes = new HashMap<>();

        //jaxb 1.0 spec pairs
        javaTypes.put(CoreClassConstants.APBYTE, Constants.HEX_BINARY_QNAME);
        javaTypes.put(CoreClassConstants.BIGDECIMAL, Constants.DECIMAL_QNAME);
        javaTypes.put(CoreClassConstants.BIGINTEGER, Constants.INTEGER_QNAME);
        javaTypes.put(CoreClassConstants.PBOOLEAN, Constants.BOOLEAN_QNAME);
        javaTypes.put(CoreClassConstants.PBYTE, Constants.BYTE_QNAME);
        javaTypes.put(CoreClassConstants.CALENDAR, Constants.DATE_TIME_QNAME);
        javaTypes.put(CoreClassConstants.PDOUBLE, Constants.DOUBLE_QNAME);
        javaTypes.put(CoreClassConstants.PFLOAT, Constants.FLOAT_QNAME);
        javaTypes.put(CoreClassConstants.PINT, Constants.INT_QNAME);
        javaTypes.put(CoreClassConstants.PLONG, Constants.LONG_QNAME);
        javaTypes.put(CoreClassConstants.PSHORT, Constants.SHORT_QNAME);
        javaTypes.put(Constants.QNAME_CLASS, Constants.QNAME_QNAME);
        javaTypes.put(CoreClassConstants.STRING, Constants.STRING_QNAME);

        //other pairs
        javaTypes.put(CoreClassConstants.ABYTE, Constants.HEX_BINARY_QNAME);
        javaTypes.put(CoreClassConstants.BOOLEAN, Constants.BOOLEAN_QNAME);
        javaTypes.put(CoreClassConstants.BYTE, Constants.BYTE_QNAME);
        javaTypes.put(CoreClassConstants.GREGORIAN_CALENDAR, Constants.DATE_TIME_QNAME);
        javaTypes.put(CoreClassConstants.DOUBLE, Constants.DOUBLE_QNAME);
        javaTypes.put(CoreClassConstants.FLOAT, Constants.FLOAT_QNAME);
        javaTypes.put(CoreClassConstants.INTEGER, Constants.INT_QNAME);
        javaTypes.put(CoreClassConstants.LONG, Constants.LONG_QNAME);
        javaTypes.put(CoreClassConstants.SHORT, Constants.SHORT_QNAME);
        javaTypes.put(CoreClassConstants.UTILDATE, Constants.DATE_TIME_QNAME);

        javaTypes.put(CoreClassConstants.CHAR, Constants.UNSIGNED_INT_QNAME);
        javaTypes.put(CoreClassConstants.PCHAR, Constants.UNSIGNED_INT_QNAME);
        javaTypes.put(CoreClassConstants.DURATION, Constants.DURATION_QNAME);
        javaTypes.put(Constants.UUID, Constants.STRING_QNAME);
        javaTypes.put(Constants.URI, Constants.STRING_QNAME);
        javaTypes.put(CoreClassConstants.URL_Class, Constants.ANY_URI_QNAME);

        return javaTypes;
    }

    private String appendTimeZone(String string, Date date) {
        StringBuilder stringBuilder = new StringBuilder(string);

        // GMT Time Zone
        int rawMinuteOffset = getTimeZone().getOffset(date.getTime()) / 60000;
        if (0 == rawMinuteOffset) {
            stringBuilder.append(GMT_SUFFIX);
            return stringBuilder.toString();
        }

        // +HH:MM
        if (rawMinuteOffset < 0) {
            stringBuilder.append('-');
            rawMinuteOffset = Math.abs(rawMinuteOffset);
        } else {
            stringBuilder.append('+');
        }
        int hourOffset = rawMinuteOffset / 60;
        if (hourOffset < 10) {
            stringBuilder.append('0');
        }
        stringBuilder.append(hourOffset);
        stringBuilder.append(Constants.COLON);
        int minuteOffset = rawMinuteOffset % 60;
        if (minuteOffset < 10) {
            stringBuilder.append('0');
        }
        stringBuilder.append(minuteOffset);
        return stringBuilder.toString();
    }

    /**
     * INTERNAL:
     */
    @Override
    public Object clone() {
        XMLConversionManager clone = (XMLConversionManager) super.clone();
        return clone;
    }

    /**
     * Convenience method that appends nanosecond values from a given
     * time to a given string.
     *
     */
    private String appendNanos(String string, Timestamp ts) {
        StringBuilder strBldr = new StringBuilder(string);
        int nanos = ts.getNanos();
        strBldr.append(nanos==0 ? OXMSystemProperties.xmlConversionTimeSuffix : '.' + Helper.buildZeroPrefixAndTruncTrailZeros(nanos, TOTAL_NS_DIGITS));
        return strBldr.toString();
    }

    /**
     * Convenience method that appends millisecond values from a given
     * time to a given string.
     *
     */
    private String appendMillis(String string, long time) {
        StringBuilder strBldr = new StringBuilder(string);
        int msns = (int) (time % 1000);
        if (msns < 0) {
            // adjust for negative time values, i.e. before Epoch
            msns = msns + 1000;
        }
        strBldr.append(msns==0 ? OXMSystemProperties.xmlConversionTimeSuffix : '.' + Helper.buildZeroPrefixAndTruncTrailZeros(msns, TOTAL_MS_DIGITS));
        return strBldr.toString();
    }

    @Override
    public QName buildQNameFromString(String stringValue, AbstractUnmarshalRecord record){
        stringValue = stringValue.trim();
        int index = stringValue.lastIndexOf(Constants.COLON);
        if(index > -1) {
            String prefix =  stringValue.substring(0, index);
            String localName = stringValue.substring(index + 1);

            if(record.isNamespaceAware()){
                String namespaceURI = record.resolveNamespacePrefix(prefix);
                return new QName(namespaceURI, localName, prefix);
            }else{
                return new QName(null, localName, prefix);
            }
        } else {
            String namespaceURI = record.resolveNamespacePrefix(Constants.EMPTY_STRING);
            if(namespaceURI == null){
                namespaceURI = record.resolveNamespacePrefix(null);
            }
            return new QName(namespaceURI, stringValue);
        }
    }

    /**
     * Replaces any CR, Tab or LF characters in the string with a single ' ' character.
     */
    @Override
    public String normalizeStringValue(String value) {
        int i = 0;
        int length = value.length();

        //check for the first whitespace
        while(i < length) {
            if(isWhitespace(value.charAt(i), false)) {
                break;
            }
            i++;
        }
        if(i == length) {
            return value;
        }

        char[] buffer = value.toCharArray();
        buffer[i] = ' ';
        i++;
        for(; i < length; i++) {
            if(isWhitespace(buffer[i], false)) {
                buffer[i] = ' ';
            }
        }
        return new String(buffer);
    }

    /**
     * Removes all leading and trailing whitespaces, and replaces any sequences of whitespaces
     * that occur in the string with a single ' ' character.
     */
    @Override
    public String collapseStringValue(String value) {
        int length = value.length();

        int start = 0;
        while(start < length) {
            if(isWhitespace(value.charAt(start), true)) {
                break;
            }
            start++;
        }
        if(start == length) {
            return value;
        }

        StringBuilder collapsedString = new StringBuilder(length);
        if(start != 0) {
            for(int i = 0; i < start; i++) {
                collapsedString.append(value.charAt(i));
            }
            collapsedString.append(' ');
        }

        boolean inSequence = true;
        for(int i = start + 1; i < length; i++) {
            char nextCharacter = value.charAt(i);
            if(!isWhitespace(nextCharacter, true)) {
                collapsedString.append(nextCharacter);
                inSequence = false;
            } else {
                if(!inSequence) {
                    collapsedString.append(' ');
                    inSequence = true;
                }
            }
        }
        length = collapsedString.length();
        if(length > 0 && collapsedString.charAt(length -1) == ' ') {
            collapsedString.setLength(length - 1);
        }
        return collapsedString.toString();
    }

    private boolean isWhitespace(char character, boolean includeSpace) {
        if(character > 0x20) {
            return false;
        }
        if(character == 0x9 || character == 0xA || character == 0xD) {
            return true;
        }
        if(includeSpace) {
            return character == 0x20;
        }
        return false;
    }

    private boolean isNumericQName(QName schemaTypeQName){
        if(schemaTypeQName == null){
            return false;
        }
        return(schemaTypeQName.equals(Constants.BYTE_QNAME ))
              ||(schemaTypeQName.equals(Constants.DECIMAL_QNAME ))
              ||(schemaTypeQName.equals(Constants.INT_QNAME ))
              ||(schemaTypeQName.equals(Constants.INTEGER_QNAME ))
              ||(schemaTypeQName.equals(Constants.FLOAT_QNAME ))
              ||(schemaTypeQName.equals(Constants.LONG_QNAME ))
            ||(schemaTypeQName.equals(Constants.NEGATIVE_INTEGER_QNAME))
              ||(schemaTypeQName.equals(Constants.NON_NEGATIVE_INTEGER_QNAME))
              ||(schemaTypeQName.equals(Constants.NON_POSITIVE_INTEGER_QNAME))
              ||(schemaTypeQName.equals(Constants.POSITIVE_INTEGER_QNAME))
              ||(schemaTypeQName.equals(Constants.SHORT_QNAME ))
              ||(schemaTypeQName.equals(Constants.UNSIGNED_SHORT_QNAME ))
              ||(schemaTypeQName.equals(Constants.UNSIGNED_LONG_QNAME ))
              ||(schemaTypeQName.equals(Constants.UNSIGNED_INT_QNAME ))
              ||(schemaTypeQName.equals(Constants.UNSIGNED_BYTE_QNAME ));
    }

    /**
     * @since EclipseLink 2.6.0
     * @param schemaType The type you want to find a corresponding Java class for.
     * @return the Java class for the XML schema type.
     */
    @Override
    @SuppressWarnings({"unchecked"})
    public <T> Class<T> javaType(QName schemaType) {
        return (Class<T>) getDefaultXMLTypes().get(schemaType);
    }

    /**
     * @since EclipseLink 2.6.0
     * @param javaType The type you want to find a corresponding schema type for.
     * @return the schema type for the Java class.
     */
    @Override
    public QName schemaType(Class<?> javaType) {
         return getDefaultJavaTypes().get(javaType);
    }

    @Override
    public Object convertHexBinaryListToByteArrayList(Object sourceObject,
            CoreContainerPolicy containerPolicy, CoreAbstractSession session) {
        if (sourceObject instanceof String) {
            StringTokenizer tokenizer = new StringTokenizer((String) sourceObject, " ");
            Object container = containerPolicy.containerInstance();
            while (tokenizer.hasMoreElements()) {
                String token = tokenizer.nextToken();
                byte[] bytes = Helper.buildBytesFromHexString(token);
                containerPolicy.addInto(bytes, container, session);
            }
            return container;
        }
        throw ConversionException.couldNotBeConverted(sourceObject, CoreClassConstants.ABYTE);
    }


}
