/*
 * 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 Character.valueOf((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.valueOf(Double.POSITIVE_INFINITY);
           }else if(Constants.NEGATIVE_INFINITY.equals(sourceObject)){
               return Double.valueOf(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.valueOf(Float.POSITIVE_INFINITY);
           }else if(Constants.NEGATIVE_INFINITY.equals(sourceObject)){
               return Float.valueOf(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: '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: '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: '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].byteValue();
        }
        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].byteValue();
        }
        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);
    }


}
