/*
 * Copyright (c) 1998, 2021 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.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 HashMap defaultXMLTypes;
    protected static HashMap 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.
     *
     * @return
     */
    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
    public Object convertObject(Object sourceObject, Class 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 sourceObject;
        } else if (javaClass == CoreClassConstants.STRING) {
           if(sourceObject instanceof List){
               return convertListToString(sourceObject, null);
           } else if (sourceObject instanceof Character[]) {
               return convertObjectToString(sourceObject);
           } else if (sourceObject instanceof Object[]) {
               return convertArrayToString((Object[]) sourceObject, null);
           } else {
               return convertObjectToString(sourceObject);
           }
        } else if (javaClass == CoreClassConstants.ASTRING && sourceObject instanceof String) {
                return 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 convertObjectToQName(sourceObject);
        } else if ((javaClass == CoreClassConstants.List_Class) && (sourceObject instanceof String)) {
            return convertStringToList(sourceObject);
        } else if ((javaClass == CoreClassConstants.CALENDAR)) {
            return convertObjectToCalendar(sourceObject);
        } else if ((javaClass == CoreClassConstants.UTILDATE)) {
            return convertObjectToUtilDate(sourceObject, Constants.DATE_TIME_QNAME);
        } else if ((javaClass == CoreClassConstants.SQLDATE)) {
            return convertObjectToSQLDate(sourceObject, Constants.DATE_QNAME);
        } else if ((javaClass == CoreClassConstants.TIME)) {
            return convertObjectToSQLTime(sourceObject, Constants.TIME_QNAME);
        } else if ((javaClass == CoreClassConstants.TIMESTAMP)) {
            return convertObjectToTimestamp(sourceObject, Constants.DATE_TIME_QNAME);
        } else if ((javaClass == java.net.URI.class)) {
            return convertObjectToURI(sourceObject);
        } else if ((javaClass == CoreClassConstants.XML_GREGORIAN_CALENDAR)) {
            return convertObjectToXMLGregorianCalendar(sourceObject);
        } else if ((javaClass == CoreClassConstants.DURATION)) {
            return convertObjectToDuration(sourceObject);
        } else if ((javaClass == CoreClassConstants.FILE) && (sourceObject instanceof String)) {
            return convertStringToFile((String) sourceObject);
        } else if ((javaClass == Constants.UUID) && (sourceObject instanceof String)) {
            return 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
    public Object convertObject(Object sourceObject, Class 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 sourceObject;
        } else if ((javaClass == CoreClassConstants.CALENDAR) || (javaClass == CoreClassConstants.GREGORIAN_CALENDAR)) {
            return convertObjectToCalendar(sourceObject, schemaTypeQName);
        } else if (javaClass == CoreClassConstants.ABYTE) {
            if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.HEX_BINARY)) {
                return super.convertObjectToByteObjectArray(sourceObject);
            } else if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.BASE_64_BINARY)) {
                return convertSchemaBase64ToByteObjectArray(sourceObject);
            }
        } else if (javaClass == CoreClassConstants.APBYTE) {
            if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.HEX_BINARY)) {
                return super.convertObjectToByteArray(sourceObject);
            } else if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.BASE_64_BINARY)) {
                return convertSchemaBase64ToByteArray(sourceObject);
            }
        } else if ((javaClass == CoreClassConstants.List_Class) && (sourceObject instanceof String)) {
            return convertStringToList(sourceObject);
        } else if ((javaClass == CoreClassConstants.STRING) && (sourceObject instanceof List)) {
            return convertListToString(sourceObject, schemaTypeQName);
        } else if (sourceObject instanceof byte[]) {
            if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.BASE_64_BINARY)) {
                return buildBase64StringFromBytes((byte[]) sourceObject);
            }
            return Helper.buildHexStringFromBytes((byte[]) sourceObject);
        } else if (sourceObject instanceof Byte[]) {
            if (schemaTypeQName.getLocalPart().equalsIgnoreCase(Constants.BASE_64_BINARY)) {
                return buildBase64StringFromObjectBytes((Byte[]) sourceObject);
            }
            return buildHexStringFromObjectBytes((Byte[]) sourceObject);
        } else if ((javaClass == CoreClassConstants.STRING) && (sourceObject instanceof Object[])) {
            return convertArrayToString((Object[]) sourceObject, schemaTypeQName);
        } else if ((javaClass == CoreClassConstants.UTILDATE)) {
            return convertObjectToUtilDate(sourceObject, schemaTypeQName);
        } else if (javaClass == CoreClassConstants.SQLDATE) {
            return convertObjectToSQLDate(sourceObject, schemaTypeQName);
        } else if (javaClass == CoreClassConstants.TIME) {
            return convertObjectToSQLTime(sourceObject, schemaTypeQName);
        } else if (javaClass ==  CoreClassConstants.TIMESTAMP) {
            return convertObjectToTimestamp(sourceObject, schemaTypeQName);
        } else if (javaClass == Constants.QNAME_CLASS) {
            return convertObjectToQName(sourceObject);
        } else if (javaClass == CoreClassConstants.STRING) {
            return convertObjectToString(sourceObject, schemaTypeQName);
        } else if ((javaClass == java.net.URI.class)) {
            return convertObjectToURI(sourceObject);
        } else if ((javaClass == CoreClassConstants.XML_GREGORIAN_CALENDAR)) {
            return convertObjectToXMLGregorianCalendar(sourceObject, schemaTypeQName);
        } else if ((javaClass == CoreClassConstants.DURATION)) {
            return convertObjectToDuration(sourceObject);
        } else if ((javaClass == CoreClassConstants.CHAR)) {
            return 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.
     *
     * @param sourceObject
     * @param schemaTypeQName
     */
    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.
     *
     * @param 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.
     *
     * @param 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.
     *
     * @param 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.
     *
     * @param 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.
     *
     * @param sourceObject
     * @return
     * @throws ConversionException
     */
    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
     *
     * @param sourceString
     * @return
     */
    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.
     *
     * @param sourceString
     * @return
     */
    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().
     *
     * @param xmlFormat
     * @return
     */
    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 + 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);
        Date returnDate = cal.getTime();

        return returnDate;
    }

    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'}
     *
     * @param sourceDate
     * @return
     */
    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'.
     *
     * @param sourceDate
     * @param schemaType
     * @return
     */
    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'}
     *
     * @param sourceDate
     * @return
     */
    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'}.
     *
     * @param sourceDate
     * @param schemaType
     * @return
     */
    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 convertStringToList(Object sourceObject) throws ConversionException {
        ArrayList 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 Object convertStringToList(Object sourceObject, Class elementType, ContainerPolicy containerPolicy, QName schemaType) throws ConversionException {
        Collection collection = (Collection) 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((String)convertObject(next, String.class, 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((String)convertObject(next, String.class, schemaType));
        }
        return returnStringBuilder.toString();
    }

    public static HashMap getDefaultXMLTypes() {
        if (defaultXMLTypes == null) {
            defaultXMLTypes = buildXMLTypes();
        }
        return defaultXMLTypes;
    }

    public static HashMap getDefaultJavaTypes() {
        if (defaultJavaTypes == null) {
            defaultJavaTypes = buildJavaTypes();
        }
        return defaultJavaTypes;
    }

    /**
    * Build and return a Hashtable containing the default XML to Java conversion pairs
    */
    private static HashMap buildXMLTypes() {
        HashMap 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 HashMap buildJavaTypes() {
        HashMap 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.
     *
     * @param string
     * @param ts
     * @return
     */
    private String appendNanos(String string, Timestamp ts) {
        StringBuilder strBldr = new StringBuilder(string);
        int nanos = ts.getNanos();
        strBldr.append(nanos==0 ? "" : '.' + Helper.buildZeroPrefixAndTruncTrailZeros(nanos, TOTAL_NS_DIGITS));
        return strBldr.toString();
    }

    /**
     * Convenience method that appends millisecond values from a given
     * time to a given string.
     *
     * @param string
     * @param time
     * @return
     */
    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 ? "" : '.' + 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) {
                    continue;
                } else {
                    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
    public Class<?> javaType(QName schemaType) {
        return (Class<?>) 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 (QName) 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);
    }


}
