/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.axis2.databinding.utils;

import org.apache.axiom.attachments.ByteArrayDataSource;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.util.AXIOMUtil;
import org.apache.axiom.util.base64.Base64Utils;
import org.apache.axiom.util.stax.XMLStreamReaderUtils;
import org.apache.axiom.util.stax.XMLStreamWriterUtils;
import org.apache.axis2.databinding.ADBBean;
import org.apache.axis2.databinding.ADBException;
import org.apache.axis2.databinding.i18n.ADBMessages;
import org.apache.axis2.databinding.types.Day;
import org.apache.axis2.databinding.types.Duration;
import org.apache.axis2.databinding.types.Entities;
import org.apache.axis2.databinding.types.Entity;
import org.apache.axis2.databinding.types.HexBinary;
import org.apache.axis2.databinding.types.IDRef;
import org.apache.axis2.databinding.types.IDRefs;
import org.apache.axis2.databinding.types.Id;
import org.apache.axis2.databinding.types.Language;
import org.apache.axis2.databinding.types.Month;
import org.apache.axis2.databinding.types.MonthDay;
import org.apache.axis2.databinding.types.NCName;
import org.apache.axis2.databinding.types.NMToken;
import org.apache.axis2.databinding.types.NMTokens;
import org.apache.axis2.databinding.types.Name;
import org.apache.axis2.databinding.types.NegativeInteger;
import org.apache.axis2.databinding.types.NonNegativeInteger;
import org.apache.axis2.databinding.types.NonPositiveInteger;
import org.apache.axis2.databinding.types.NormalizedString;
import org.apache.axis2.databinding.types.Notation;
import org.apache.axis2.databinding.types.PositiveInteger;
import org.apache.axis2.databinding.types.Time;
import org.apache.axis2.databinding.types.Token;
import org.apache.axis2.databinding.types.URI;
import org.apache.axis2.databinding.types.UnsignedByte;
import org.apache.axis2.databinding.types.UnsignedInt;
import org.apache.axis2.databinding.types.UnsignedLong;
import org.apache.axis2.databinding.types.UnsignedShort;
import org.apache.axis2.databinding.types.Year;
import org.apache.axis2.databinding.types.YearMonth;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.activation.DataHandler;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;

/**
 * Converter methods to go from 1. simple type -> String 2. simple type -> Object 3. String ->
 * simpletype 4. Object list -> array
 */
public class ConverterUtil {

    private static Log log = LogFactory.getLog(ConverterUtil.class);

    private static final String POSITIVE_INFINITY = "INF";
    private static final String NEGATIVE_INFINITY = "-INF";

    public static final String SYSTEM_PROPERTY_ADB_CONVERTERUTIL = "adb.converterutil";

    private static boolean isCustomClassPresent;
    private static Class customClass;

    /* String conversion methods */
    public static String convertToString(int i) {
        return Integer.toString(i);
    }

    public static String convertToString(float i) {
        return Float.toString(i);
    }

    public static String convertToString(long i) {
        return Long.toString(i);
    }

    public static String convertToString(double i) {
        return Double.toString(i);
    }

    public static String convertToString(byte i) {
        return Byte.toString(i);
    }

    public static String convertToString(char i) {
        return Character.toString(i);
    }

    public static String convertToString(short i) {
        return Short.toString(i);
    }

    public static String convertToString(boolean i) {
        return Boolean.toString(i);
    }

    public static String convertToString(Date value) {

        if (isCustomClassPresent) {
            // this means user has define a seperate converter util class
            return invokeToStringMethod(value,Date.class);
        } else {
            // lexical form of the date is '-'? yyyy '-' mm '-' dd zzzzzz?
            Calendar calendar = Calendar.getInstance();
            calendar.clear();
            calendar.setTime(value);
            if (!calendar.isSet(Calendar.ZONE_OFFSET)){
                calendar.setTimeZone(TimeZone.getDefault());
            }
            StringBuffer dateString = new StringBuffer(16);
            appendDate(dateString, calendar);
            appendTimeZone(calendar, dateString);
            return dateString.toString();
        }
    }

    public static void appendTimeZone(Calendar calendar, StringBuffer dateString) {
        int timezoneOffSet = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
        int timezoneOffSetInMinits = timezoneOffSet / 60000;
        if (timezoneOffSetInMinits < 0){
            dateString.append("-");
            timezoneOffSetInMinits = timezoneOffSetInMinits * -1;
        } else {
            dateString.append("+");
        }
        int hours = timezoneOffSetInMinits / 60;
        int minits = timezoneOffSetInMinits % 60;

        if (hours < 10) {
            dateString.append("0");
        }
        dateString.append(hours).append(":");

        if (minits < 10){
            dateString.append("0");
        }

        dateString.append(minits);
    }

    public static void appendDate(StringBuffer dateString, Calendar calendar) {

        int year = calendar.get(Calendar.YEAR);

        if (year < 1000){
            dateString.append("0");
        }
        if (year < 100){
            dateString.append("0");
        }
        if (year < 10) {
            dateString.append("0");
        }
        dateString.append(year).append("-");

        // xml date month is started from 1 and calendar month is
        // started from 0. so have to add one
        int month = calendar.get(Calendar.MONTH) + 1;
        if (month < 10){
            dateString.append("0");
        }
        dateString.append(month).append("-");
        if (calendar.get(Calendar.DAY_OF_MONTH) < 10){
            dateString.append("0");
        }
        dateString.append(calendar.get(Calendar.DAY_OF_MONTH));
    }

    private static String invokeToStringMethod(Object value, Class type) {

        try {
            Method method = customClass.getMethod("convertToString", new Class[]{type});
            String result = (String) method.invoke(null,new Object[]{value});
            return result;
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("can not find the method convertToString("
                    + type.getName() + ") in converter util class " + customClass.getName(), e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("can not access the method convertToString("
                    + type.getName() + ") in converter util class " + customClass.getName(), e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException("can not invocate the method convertToString("
                    + type.getName() + ") in converter util class " + customClass.getName(), e);
        }
    }

    public static String convertToString(Calendar value) {
        if (isCustomClassPresent) {
            return invokeToStringMethod(value,Calendar.class);
        } else {
            // lexical form of the calendar is '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
            if (value.get(Calendar.ZONE_OFFSET) == -1){
                value.setTimeZone(TimeZone.getDefault());
            }
            StringBuffer dateString = new StringBuffer(28);
            appendDate(dateString, value);
            dateString.append("T");
            //adding hours
            appendTime(value, dateString);
            appendTimeZone(value, dateString);
            return dateString.toString();
        }
    }

    public static void appendTime(Calendar value, StringBuffer dateString) {
        if (value.get(Calendar.HOUR_OF_DAY) < 10) {
            dateString.append("0");
        }
        dateString.append(value.get(Calendar.HOUR_OF_DAY)).append(":");
        if (value.get(Calendar.MINUTE) < 10) {
            dateString.append("0");
        }
        dateString.append(value.get(Calendar.MINUTE)).append(":");
        if (value.get(Calendar.SECOND) < 10) {
            dateString.append("0");
        }
        dateString.append(value.get(Calendar.SECOND)).append(".");
        if (value.get(Calendar.MILLISECOND) < 10) {
            dateString.append("0");
        }
        if (value.get(Calendar.MILLISECOND) < 100) {
            dateString.append("0");
        }
        dateString.append(value.get(Calendar.MILLISECOND));
    }

    public static String convertToString(Day o) {
        return o.toString();
    }

    public static String convertToString(YearMonth o) {
        return o.toString();
    }

    public static String convertToString(Year o) {
        return o.toString();
    }

    public static String convertToString(HexBinary o) {
        return o.toString();
    }

    public static String convertToString(MonthDay o) {
        return o.toString();
    }

    public static String convertToString(Time o) {
        return o.toString();
    }

    public static String convertToString(Byte o) {
        return o.toString();
    }

    public static String convertToString(BigInteger o) {
        return o.toString();
    }

    public static String convertToString(Integer o) {
        return o.toString();
    }

    public static String convertToString(Long o) {
        return o.toString();
    }

    public static String convertToString(Short o) {
        return o.toString();
    }

    public static String convertToString(UnsignedByte o) {
        return o.toString();
    }

    public static String convertToString(UnsignedInt o) {
        return o.toString();
    }

    public static String convertToString(UnsignedLong o) {
        return o.toString();
    }

    public static String convertToString(QName o) {
        if (o != null) {
            return o.getLocalPart();
        } else {
            return "";
        }
    }

    public static String convertToString(Object o) {
        return o.toString();
    }

    public static String convertToString(BigDecimal o) {
        return o.toPlainString();
    }

    public static String convertToString(Double o) {
        return o.toString();
    }

    public static String convertToString(Duration o) {
        return o.toString();
    }

    public static String convertToString(Float o) {
        return o.toString();
    }

    public static String convertToString(Month o) {
        return o.toString();
    }

    public static String convertToString(byte[] bytes) {
        return Base64Utils.encode(bytes);
    }

    public static String convertToString(javax.activation.DataHandler handler) {
        return getStringFromDatahandler(handler);
    }

    /* ################################################################################ */
    /* String to java type conversions
       These methods have a special signature structure
       <code>convertTo</code> followed by the schema type name
       Say for int, convertToint(String) is the converter method

       Not very elegant but it seems to be the only way!

    */


    public static int convertToInt(String s) {
        if ((s == null) || s.equals("")){
            return Integer.MIN_VALUE;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return Integer.parseInt(s);
    }

    public static BigDecimal convertToBigDecimal(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new BigDecimal(s);
    }

    public static double convertToDouble(String s) {
        if ((s == null) || s.equals("")){
            return Double.NaN;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        if (POSITIVE_INFINITY.equals(s)) {
            return Double.POSITIVE_INFINITY;
        } else if (NEGATIVE_INFINITY.equals(s)) {
            return Double.NEGATIVE_INFINITY;
        }
        return Double.parseDouble(s);
    }

    public static BigDecimal convertToDecimal(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new BigDecimal(s);
    }

    public static BigDecimal convertToStandardDecimalNotation(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return BigDecimal.valueOf(Math.pow(10, Integer.parseInt(s)));
    }

    public static float convertToFloat(String s) {
        if ((s == null) || s.equals("")){
            return Float.NaN;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        if (POSITIVE_INFINITY.equals(s)) {
            return Float.POSITIVE_INFINITY;
        } else if (NEGATIVE_INFINITY.equals(s)) {
            return Float.NEGATIVE_INFINITY;
        }
        return Float.parseFloat(s);
    }

    public static String convertToString(String s) {
        return s;
    }

    public static long convertToLong(String s) {
        if ((s == null) || s.equals("")){
            return Long.MIN_VALUE;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return Long.parseLong(s);
    }

    public static short convertToShort(String s) {
        if ((s == null) || s.equals("")){
            return Short.MIN_VALUE;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return Short.parseShort(s);
    }

    public static boolean convertToBoolean(String s) {

        boolean returnValue = false;
        if ((s != null) && (s.length() > 0)) {
            if ("1".equals(s) || s.toLowerCase().equals("true")) {
                returnValue = true;
            } else if (!"0".equals(s) && !s.toLowerCase().equals("false")) {
                throw new RuntimeException("in valid string -" + s + " for boolean value");
            }
        }
        return returnValue;
    }

    public static String convertToAnySimpleType(String s) {
        return s;
    }

    public static OMElement convertToAnyType(String s) {
        try {
            return AXIOMUtil.stringToOM(s);
        } catch (XMLStreamException e) {
            return null;
        }
    }

    public static YearMonth convertToGYearMonth(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new YearMonth(s);
    }

    public static MonthDay convertToGMonthDay(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new MonthDay(s);
    }

    public static Year convertToGYear(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Year(s);
    }

    public static Month convertToGMonth(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Month(s);
    }

    public static Day convertToGDay(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Day(s);
    }

    public static Duration convertToDuration(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Duration(s);
    }


    public static HexBinary convertToHexBinary(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new HexBinary(s);
    }

    public static javax.activation.DataHandler convertToBase64Binary(String s) {
        // reusing the byteArrayDataSource from the Axiom classes
        if ((s == null) || s.equals("")){
            return null;
        }
        ByteArrayDataSource byteArrayDataSource = new ByteArrayDataSource(
                Base64Utils.decode(s)
        );
        return new DataHandler(byteArrayDataSource);
    }

    public static javax.activation.DataHandler convertToDataHandler(String s) {
        return convertToBase64Binary(s);
    }

    /**
     * Converts a given string into a date. Code from Axis1 DateDeserializer.
     *
     * @param source
     * @return Returns Date.
     */
    public static Date convertToDate(String source) {

        // the lexical form of the date is '-'? yyyy '-' mm '-' dd zzzzzz?
        if ((source == null) || source.trim().equals("")) {
            return null;
        }
        source = source.trim();
        boolean bc = false;
        if (source.startsWith("-")) {
            source = source.substring(1);
            bc = true;
        }

        int year = 0;
        int month = 0;
        int day = 0;
        int timeZoneOffSet = TimeZone.getDefault().getRawOffset();

        if (source.length() >= 10) {
            //first 10 numbers must give the year
            if ((source.charAt(4) != '-') || (source.charAt(7) != '-')){
                throw new RuntimeException("invalid date format (" + source + ") with out - s at correct place ");
            }
            year = Integer.parseInt(source.substring(0,4));
            month = Integer.parseInt(source.substring(5,7));
            day = Integer.parseInt(source.substring(8,10));

            if (source.length() > 10) {
                String restpart = source.substring(10);
                if (restpart.startsWith("Z")) {
                    // this is a gmt time zone value
                    timeZoneOffSet = 0;
                } else if (restpart.startsWith("+") || restpart.startsWith("-") || restpart.startsWith("T")) {
                    // this is a specific time format string
                    if (restpart.charAt(3) != ':'){
                        throw new RuntimeException("invalid time zone format (" + source
                                + ") without : at correct place");
                    }
                    int hours = Integer.parseInt(restpart.substring(1,3));
                    int minits = Integer.parseInt(restpart.substring(4,6));
                    timeZoneOffSet = ((hours * 60) + minits) * 60000;
                    if (restpart.startsWith("-")){
                        timeZoneOffSet = timeZoneOffSet * -1;
                    }
                } else {
                    throw new RuntimeException("In valid string sufix");
                }
            }
        } else {
            throw new RuntimeException("In valid string to parse");
        }

        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setLenient(false);
        calendar.set(Calendar.YEAR, year);
        //xml month stars from the 1 and calendar month is starts with 0
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DAY_OF_MONTH, day);
        calendar.set(Calendar.ZONE_OFFSET, timeZoneOffSet);

        // set the day light off set only if time zone
        if (source.length() >= 10) {
            calendar.set(Calendar.DST_OFFSET, 0);
        }
        calendar.getTimeInMillis();
        if (bc){
            calendar.set(Calendar.ERA, GregorianCalendar.BC);
        }

        return calendar.getTime();

    }    
    
    /**
     * Convert lexical representation of date to java.util.Date.
     * 
     * @param source
     *            the source
     * @return the date
     * 
     * This method used to parse the lexical string representation
     * defined in XML Schema 1.0 Part 2, Section 3.2.[7-14].1 to a
     * java.util.Date based on XMLGregorianCalendar. This replaced the
     * behavior of convertToDate() method that copied from Axis1 .
     */
    public static Date convertXmlToDate(String source) {
        try {
            XMLGregorianCalendar cal = DatatypeFactory.newInstance()
                    .newXMLGregorianCalendar(source);
            return cal.toGregorianCalendar().getTime();
        } catch (DatatypeConfigurationException e) {
            e.printStackTrace();
        }
        return null;

    }

    public static Time convertToTime(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Time(s);
    }

    public static Token convertToToken(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Token(s);
    }


    public static NormalizedString convertToNormalizedString(String s) {
        if ((s == null)){
            return null;
        }
        return new NormalizedString(s);
    }

    public static UnsignedLong convertToUnsignedLong(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new UnsignedLong(s);
    }

    public static UnsignedInt convertToUnsignedInt(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new UnsignedInt(s);
    }

    public static UnsignedShort convertToUnsignedShort(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new UnsignedShort(s);
    }

    public static UnsignedByte convertToUnsignedByte(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new UnsignedByte(s);
    }

    public static NonNegativeInteger convertToNonNegativeInteger(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new NonNegativeInteger(s);
    }

    public static NegativeInteger convertToNegativeInteger(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new NegativeInteger(s);
    }

    public static PositiveInteger convertToPositiveInteger(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new PositiveInteger(s);
    }

    public static NonPositiveInteger convertToNonPositiveInteger(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new NonPositiveInteger(s);
    }

    public static Name convertToName(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Name(s);
    }

    public static NCName convertToNCName(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new NCName(s);
    }

    public static Id convertToID(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Id(s);
    }

    public static Id convertToId(String s) {
        return convertToID(s);
    }

    public static Language convertToLanguage(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Language(s);
    }

    public static NMToken convertToNMTOKEN(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new NMToken(s);
    }

    public static NMTokens convertToNMTOKENS(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new NMTokens(s);
    }

    public static Notation convertToNOTATION(String s) {
        return null; //todo Need to fix this
        // return new Notation(s);
    }

    public static Entity convertToENTITY(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Entity(s);
    }

    public static Entities convertToENTITIES(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new Entities(s);
    }

    public static IDRef convertToIDREF(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new IDRef(s);
    }

    public static IDRefs convertToIDREFS(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        return new IDRefs(s);
    }

    public static URI convertToURI(String s){
        if ((s == null) || s.equals("")){
            return null;
        }
        return convertToAnyURI(s);
    }

    public static URI convertToAnyURI(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        try {
            return new URI(s);
        } catch (URI.MalformedURIException e) {
            throw new ObjectConversionException(
                    ADBMessages.getMessage("converter.cannotParse", s), e);
        }
    }

    public static BigInteger convertToInteger(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return new BigInteger(s);
    }

    public static BigInteger convertToBigInteger(String s) {
        if ((s == null) || s.equals("")){
            return null;
        }
        if (s.startsWith("+")) {
            s = s.substring(1);
        }
        return convertToInteger(s);
    }

    public static byte convertToByte(String s) {
        if ((s == null) || s.equals("")){
            return Byte.MIN_VALUE;
        }
        return Byte.parseByte(s);
    }

    /**
     * Code from Axis1 code base Note - We only follow the convention in the latest schema spec
     *
     * @param source
     * @return Returns Calendar.
     */
    public static Calendar convertToDateTime(String source) {

        if ((source == null) || source.trim().equals("")) {
            return null;
        }
        source = source.trim();
        // the lexical representation of the date time as follows
        // '-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?
        Date date = null;
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setLenient(false);


        if (source.startsWith("-")) {
            source = source.substring(1);
            calendar.set(Calendar.ERA, GregorianCalendar.BC);
        }

        int year = 0;
        int month = 0;
        int day = 0;
        int hour = 0;
        int minite = 0;
        int second = 0;
        long miliSecond = 0;
        int timeZoneOffSet = TimeZone.getDefault().getRawOffset();
        boolean haveTimeZone;


        if ((source != null) && (source.length() >= 19)) {
            if ((source.charAt(4) != '-') ||
                    (source.charAt(7) != '-') ||
                    (source.charAt(10) != 'T') ||
                    (source.charAt(13) != ':') ||
                    (source.charAt(16) != ':')) {
                throw new RuntimeException("invalid date format (" + source + ") with out - s at correct place ");
            }
            year = Integer.parseInt(source.substring(0, 4));
            month = Integer.parseInt(source.substring(5, 7));
            day = Integer.parseInt(source.substring(8, 10));
            hour = Integer.parseInt(source.substring(11, 13));
            minite = Integer.parseInt(source.substring(14, 16));
            second = Integer.parseInt(source.substring(17, 19));

            int milliSecondPartLength = 0;

            if (source.length() == 19) {
                haveTimeZone = false;
            } else {
                String rest = source.substring(19);
                if (rest.startsWith(".")) {
                    // i.e this have the ('.'s+) part
                    if (rest.endsWith("Z")) {
                        // this is in gmt time zone
                        haveTimeZone = true;
                        timeZoneOffSet = 0;
                        calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
                        miliSecond = Integer.parseInt(rest.substring(1, rest.lastIndexOf("Z")));
                        milliSecondPartLength = rest.substring(1,rest.lastIndexOf("Z")).trim().length();
                    } else if ((rest.lastIndexOf("+") > 0) || (rest.lastIndexOf("-") > 0)) {
                        // this is given in a general time zione
                        haveTimeZone = true;
                        String timeOffSet = null;
                        if (rest.lastIndexOf("+") > 0) {
                            timeOffSet = rest.substring(rest.lastIndexOf("+") + 1);
                            miliSecond = Integer.parseInt(rest.substring(1, rest.lastIndexOf("+")));
                            milliSecondPartLength = rest.substring(1, rest.lastIndexOf("+")).trim().length();
                            // we keep +1 or -1 to finally calculate the value
                            timeZoneOffSet = 1;

                        } else if (rest.lastIndexOf("-") > 0) {
                            timeOffSet = rest.substring(rest.lastIndexOf("-") + 1);
                            miliSecond = Integer.parseInt(rest.substring(1, rest.lastIndexOf("-")));
                            milliSecondPartLength = rest.substring(1, rest.lastIndexOf("-")).trim().length();
                            // we keep +1 or -1 to finally calculate the value
                            timeZoneOffSet = -1;
                        }
                        if (timeOffSet.charAt(2) != ':') {
                            throw new RuntimeException("invalid time zone format (" + source
                                    + ") without : at correct place");
                        }
                        int hours = Integer.parseInt(timeOffSet.substring(0, 2));
                        int minits = Integer.parseInt(timeOffSet.substring(3, 5));
                        timeZoneOffSet = ((hours * 60) + minits) * 60000 * timeZoneOffSet;

                    } else {
                        // i.e it does not have time zone
                        haveTimeZone = false;
                        miliSecond = Integer.parseInt(rest.substring(1));
                        milliSecondPartLength = rest.substring(1).trim().length();
                    }

                } else {
                    if (rest.startsWith("Z")) {
                        calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
                        // this is in gmt time zone
                        haveTimeZone = true;
                        timeZoneOffSet = 0;
                    } else if (rest.startsWith("+") || rest.startsWith("-")) {
                        // this is given in a general time zione
                        haveTimeZone = true;
                        if (rest.charAt(3) != ':') {
                            throw new RuntimeException("invalid time zone format (" + source
                                    + ") without : at correct place");
                        }
                        int hours = Integer.parseInt(rest.substring(1, 3));
                        int minits = Integer.parseInt(rest.substring(4, 6));
                        timeZoneOffSet = ((hours * 60) + minits) * 60000;
                        if (rest.startsWith("-")) {
                            timeZoneOffSet = timeZoneOffSet * -1;
                        }
                    } else {
                        throw new NumberFormatException("in valid time zone attribute");
                    }
                }
            }
            calendar.set(Calendar.YEAR, year);
            // xml month is started from 1 and calendar month is started from 0
            calendar.set(Calendar.MONTH, month - 1);
            calendar.set(Calendar.DAY_OF_MONTH, day);
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            calendar.set(Calendar.MINUTE, minite);
            calendar.set(Calendar.SECOND, second);
            if (milliSecondPartLength != 3){
                // milisecond part represenst the fraction of the second so we have to
                // find the fraction and multiply it by 1000. So if milisecond part
                // has three digits nothing required
                miliSecond = miliSecond * 1000;
                for (int i = 0; i < milliSecondPartLength; i++) {
                    miliSecond = miliSecond / 10;
                }
            }
            calendar.set(Calendar.MILLISECOND, (int)miliSecond);
            calendar.set(Calendar.ZONE_OFFSET, timeZoneOffSet);
            // set the day light offset only if the time zone is present
            // set the day light offset only if the time zone is present
            if (haveTimeZone) {
                calendar.set(Calendar.DST_OFFSET, 0);
            }


        } else {
            throw new NumberFormatException("date string can not be less than 19 characters");
        }

        return calendar;
    }

    /**
     * Code from Axis1 code base
     *
     * @param source
     * @return Returns QName.
     */
    public static QName convertToQName(String source, String nameSpaceuri) {
        source = source.trim();
        int colon = source.lastIndexOf(":");
        //context.getNamespaceURI(source.substring(0, colon));
        String localPart = colon < 0 ? source : source.substring(colon + 1);
        String perfix = colon <= 0 ? "" : source.substring(0, colon);
        return new QName(nameSpaceuri, localPart, perfix);
    }

    /* ################################################################# */

    /* java Primitive types to Object conversion methods */
    public static Object convertToObject(String i) {
        return i;
    }

    public static Object convertToObject(boolean i) {
        return Boolean.valueOf(i);
    }

    public static Object convertToObject(double i) {
        return new Double(i);
    }

    public static Object convertToObject(byte i) {
        return new Byte(i);
    }

    public static Object convertToObject(char i) {
        return new Character(i);
    }

    public static Object convertToObject(short i) {
        return new Short(i);
    }

    /* list to array conversion methods */

    public static Object convertToArray(Class baseArrayClass, String[] valueArray) {
        //create a list using the string array
        List valuesList = new ArrayList(valueArray.length);
        for (int i = 0; i < valueArray.length; i++) {
            valuesList.add(valueArray[i]);

        }

        return convertToArray(baseArrayClass, valuesList);
    }


    /**
     * @param baseArrayClass
     * @param objectList     -> for primitive type array conversion we assume the content to be
     *                       strings!
     * @return Returns Object.
     */
    public static Object convertToArray(Class baseArrayClass, List objectList) {
        int listSize = objectList.size();
        Object returnArray = null;
        if (int.class.equals(baseArrayClass)) {
            int[] array = new int[listSize];
            for (int i = 0; i < listSize; i++) {
                Object o = objectList.get(i);
                if (o != null) {
                    array[i] = Integer.parseInt(o.toString());
                } else {
                    array[i] = Integer.MIN_VALUE;
                }
            }
            returnArray = array;
        } else if (float.class.equals(baseArrayClass)) {
            float[] array = new float[listSize];
            for (int i = 0; i < listSize; i++) {
                Object o = objectList.get(i);
                if (o != null) {
                    array[i] = Float.parseFloat(o.toString());
                } else {
                    array[i] = Float.NaN;
                }
            }
            returnArray = array;
        } else if (short.class.equals(baseArrayClass)) {
            short[] array = new short[listSize];
            for (int i = 0; i < listSize; i++) {
                Object o = objectList.get(i);
                if (o != null) {
                    array[i] = Short.parseShort(o.toString());
                } else {
                    array[i] = Short.MIN_VALUE;
                }
            }
            returnArray = array;
        } else if (byte.class.equals(baseArrayClass)) {
            byte[] array = new byte[listSize];
            for (int i = 0; i < listSize; i++) {
                Object o = objectList.get(i);
                if (o != null) {
                    array[i] = Byte.parseByte(o.toString());
                } else {
                    array[i] = Byte.MIN_VALUE;
                }
            }
            returnArray = array;
        } else if (long.class.equals(baseArrayClass)) {
            long[] array = new long[listSize];
            for (int i = 0; i < listSize; i++) {
                Object o = objectList.get(i);
                if (o != null) {
                    array[i] = Long.parseLong(o.toString());
                } else {
                    array[i] = Long.MIN_VALUE;
                }
            }
            returnArray = array;
        } else if (boolean.class.equals(baseArrayClass)) {
            boolean[] array = new boolean[listSize];
            for (int i = 0; i < listSize; i++) {
                Object o = objectList.get(i);
                if (o != null) {
                    array[i] = o.toString().equalsIgnoreCase("true");
                }
            }
            returnArray = array;
        } else if (char.class.equals(baseArrayClass)) {
            char[] array = new char[listSize];
            for (int i = 0; i < listSize; i++) {
                Object o = objectList.get(i);
                if (o != null) {
                    array[i] = o.toString().toCharArray()[0];
                }
            }
            returnArray = array;
        } else if (double.class.equals(baseArrayClass)) {
            double[] array = new double[listSize];
            for (int i = 0; i < listSize; i++) {
                Object o = objectList.get(i);
                if (o != null) {
                    array[i] = Double.parseDouble(o.toString());
                } else {
                    array[i] = Double.NaN;
                }
            }
            returnArray = array;
        } else if (Calendar.class.equals(baseArrayClass)) {
            Calendar[] array = new Calendar[listSize];
            for (int i = 0; i < listSize; i++) {
                Object o = objectList.get(i);
                if (o != null) {
                    if (o instanceof String) {
                        array[i] = ConverterUtil.convertToDateTime(o.toString());
                    } else if (o instanceof Calendar) {
                        array[i] = (Calendar) o;
                    }
                }
            }
            returnArray = array;
        } else if (Date.class.equals(baseArrayClass)) {
            Date[] array = new Date[listSize];
            for (int i = 0; i < listSize; i++) {
                Object o = objectList.get(i);
                if (o != null) {
                    if (o instanceof String) {
                        array[i] = ConverterUtil.convertToDate(o.toString());
                    } else if (o instanceof Date) {
                        array[i] = (Date) o;
                    }
                }
            }
            returnArray = array;
        } else {
            returnArray = Array.newInstance(baseArrayClass, listSize);
            ConvertToArbitraryObjectArray(returnArray, baseArrayClass, objectList);
        }
        return returnArray;
    }

    /**
     * @param returnArray
     * @param baseArrayClass
     * @param objectList
     */
    private static void ConvertToArbitraryObjectArray(Object returnArray,
                                                      Class baseArrayClass,
                                                      List objectList) {
        if (!(ADBBean.class.isAssignableFrom(baseArrayClass))) {
            try {
                for (int i = 0; i < objectList.size(); i++) {
                    Object o = objectList.get(i);
                    if (o == null) {
                        // if the string is null the object value must be null
                        Array.set(returnArray, i, null);
                    } else {
                        Array.set(returnArray, i, getObjectForClass(
                                baseArrayClass,
                                o.toString()));
                    }

                }
                return;
            } catch (Exception e) {
                //oops! - this cannot be converted fall through and
                //try the other alternative
            }
        }

        try {
            objectList.toArray((Object[])returnArray);
        } catch (Exception e) {
            //we are over with alternatives - throw the
            //converison exception
            throw new ObjectConversionException(e);
        }
    }

    /**
     * We could have used the Arraya.asList() method but that returns an *immutable* list !!!!!
     *
     * @param array
     * @return list
     */
    public static List toList(Object[] array) {
        if (array == null) {
            return new ArrayList();
        } else {
            ArrayList list = new ArrayList();
            for (int i = 0; i < array.length; i++) {
                list.add(array[i]);
            }
            return list;
        }
    }

    /**
     * @param intValue
     * @param value
     * @return 0 if equal , + value if greater than , - value if less than
     */
    public static int compare(int intValue, String value) {
        int other = Integer.parseInt(value);
        return intValue < other ? -1 : (intValue == other ? 0 : 1);

    }

    /**
     * @param doubleValue
     * @param value
     * @return 0 if equal , + value if greater than , - value if less than
     */
    public static double compare(double doubleValue, String value) {
        return doubleValue - Double.parseDouble(value);
    }


    /**
     * @param floatValue
     * @param value
     * @return 0 if equal , + value if greater than , - value if less than
     */
    public static float compare(float floatValue, String value) {
        return floatValue - Float.parseFloat(value);
    }

    /**
     * @param longValue
     * @param value
     * @return 0 if equal , + value if greater than , - value if less than
     */
    public static long compare(long longValue, String value) {
        return longValue - Long.parseLong(value);
    }

    /**
     * @param shortValue
     * @param value
     * @return 0 if equal , + value if greater than , - value if less than
     */
    public static int compare(short shortValue, String value) {
        return shortValue - Short.parseShort(value);
    }

    /**
     * @param byteVlaue
     * @param value
     * @return 0 if equal , + value if greater than , - value if less than
     */
    public static int compare(byte byteVlaue, String value) {
        return byteVlaue - Byte.parseByte(value);
    }


    /**
     * @param binBigInteger
     * @param value
     * @return 0 if equal , + value if greater than , - value if less than
     */
    public static long compare(BigInteger binBigInteger, String value) {
        return binBigInteger.longValue() - Long.parseLong(value);
    }

    /**
     * @param binBigDecimal
     * @param value
     * @return 0 if equal , + value if greater than , - value if less than
     */
    public static double compare(BigDecimal binBigDecimal, String value) {
        return binBigDecimal.doubleValue() - Double.parseDouble(value);
    }

    public static long compare(Duration duration, String value) {
        Duration compareValue = new Duration(value);
        return duration.compare(compareValue);
    }

    public static long compare(Date date, String value) {
        Date newDate = convertToDate(value);
        return date.getTime() - newDate.getTime();
    }

    public static long compare(Time time, String value) {
        Time newTime = new Time(value);
        return time.getAsCalendar().getTimeInMillis() - newTime.getAsCalendar().getTimeInMillis();
    }

    public static long compare(Calendar calendar, String value) {
        Calendar newCalendar = convertToDateTime(value);
        return calendar.getTimeInMillis() - newCalendar.getTimeInMillis();
    }

    public static long compare(UnsignedLong unsignedLong, String value) {
        return compare(unsignedLong.longValue(), value);
    }

    /**
     * Converts the given .datahandler to a string
     *
     * @return string
     */
	public static String getStringFromDatahandler(DataHandler dataHandler) {
		InputStream inStream = null;
		try {
			if (dataHandler == null) {
				return "";
			}
			inStream = dataHandler.getDataSource().getInputStream();
			byte[] data = IOUtils.toByteArray(inStream);
			return Base64Utils.encode(data);
		} catch (Exception e) {
			throw new RuntimeException(e);

		} finally {
			try {
				if (inStream != null)
					inStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
    }

    /**
     * A reflection based method to generate an instance of a given class and populate it with a
     * given value
     *
     * @param clazz
     * @param value
     * @return object
     */
    public static Object getObjectForClass(Class clazz, String value) {
        //first see whether this class has a constructor that can
        //take the string as an argument.
        try {
            Constructor stringConstructor = clazz.getConstructor(new Class[] { String.class });
            return stringConstructor.newInstance(new Object[] { value });
        } catch (NoSuchMethodException e) {
            //oops - no such constructors - continue with the
            //parse method
        } catch (Exception e) {
            throw new ObjectConversionException(
                    ADBMessages.getMessage("converter.cannotGenerate",
                                           clazz.getName()), e);
        }

        try {
            Method parseMethod = clazz.getMethod("parse", new Class[] { String.class });
            Object instance = clazz.newInstance();
            return parseMethod.invoke(instance, new Object[] { value });
        } catch (NoSuchMethodException e) {
            throw new ObjectConversionException(e);
        } catch (Exception e) {
            throw new ObjectConversionException(
                    ADBMessages.getMessage("converter.cannotGenerate",
                                           clazz.getName()),
                    e);
        }

    }

    /** A simple exception that is thrown when the conversion fails */
    public static class ObjectConversionException extends RuntimeException {
        public ObjectConversionException() {
        }

        public ObjectConversionException(String message) {
            super(message);
        }

        public ObjectConversionException(Throwable cause) {
            super(cause);
        }

        public ObjectConversionException(String message, Throwable cause) {
            super(message, cause);
        }

    }

    // serialization methods for xsd any type
    public static void serializeAnyType(Object value, XMLStreamWriter xmlStreamWriter) throws XMLStreamException {
        if (value instanceof String) {
            serializeAnyType("string", value.toString(), xmlStreamWriter);
        } else if (value instanceof Integer) {
            serializeAnyType("int", value.toString(), xmlStreamWriter);
        } else if (value instanceof Boolean) {
            serializeAnyType("boolean", value.toString(), xmlStreamWriter);
        } else if (value instanceof URI) {
            serializeAnyType("anyURI", value.toString(), xmlStreamWriter);
        } else if (value instanceof Byte) {
            serializeAnyType("byte", value.toString(), xmlStreamWriter);
        } else if (value instanceof Date) {
            serializeAnyType("date", convertToString((Date) value), xmlStreamWriter);
        } else if (value instanceof Calendar) {
            serializeAnyType("dateTime", convertToString((Calendar) value), xmlStreamWriter);
        } else if (value instanceof Time) {
            serializeAnyType("time", convertToString((Time) value), xmlStreamWriter);
        } else if (value instanceof Float) {
            serializeAnyType("float", value.toString(), xmlStreamWriter);
        } else if (value instanceof Long) {
            serializeAnyType("long", value.toString(), xmlStreamWriter);
        } else if (value instanceof Double) {
            serializeAnyType("double", value.toString(), xmlStreamWriter);
        } else if (value instanceof Short) {
            serializeAnyType("short", value.toString(), xmlStreamWriter);
        } else if (value instanceof BigDecimal) {
            serializeAnyType("decimal", ((BigDecimal)value).toPlainString(), xmlStreamWriter);
        } else if (value instanceof DataHandler) {
            addTypeAttribute(xmlStreamWriter,"base64Binary");
            try {
                XMLStreamWriterUtils.writeDataHandler(xmlStreamWriter, (DataHandler)value, null, true);
            } catch (IOException ex) {
                throw new XMLStreamException("Unable to read data handler", ex);
            }
        } else if (value instanceof QName) {
            QName qNameValue = (QName) value;
            String prefix = xmlStreamWriter.getPrefix(qNameValue.getNamespaceURI());
            if (prefix == null) {
                prefix = BeanUtil.getUniquePrefix();
                xmlStreamWriter.writeNamespace(prefix, qNameValue.getNamespaceURI());
                xmlStreamWriter.setPrefix(prefix, qNameValue.getNamespaceURI());
            }
            String attributeValue = qNameValue.getLocalPart();
            if (!prefix.equals("")) {
                attributeValue = prefix + ":" + attributeValue;
            }
            serializeAnyType("QName", attributeValue, xmlStreamWriter);
        } else if (value instanceof UnsignedByte) {
            serializeAnyType("unsignedByte", convertToString((UnsignedByte) value), xmlStreamWriter);
        } else if (value instanceof UnsignedLong) {
            serializeAnyType("unsignedLong", convertToString((UnsignedLong) value), xmlStreamWriter);
        } else if (value instanceof UnsignedShort) {
            serializeAnyType("unsignedShort", convertToString((UnsignedShort) value), xmlStreamWriter);
        } else if (value instanceof UnsignedInt) {
            serializeAnyType("unsignedInt", convertToString((UnsignedInt) value), xmlStreamWriter);
        } else if (value instanceof PositiveInteger) {
            serializeAnyType("positiveInteger", convertToString((PositiveInteger) value), xmlStreamWriter);
        } else if (value instanceof NegativeInteger) {
            serializeAnyType("negativeInteger", convertToString((NegativeInteger) value), xmlStreamWriter);
        } else if (value instanceof NonNegativeInteger) {
            serializeAnyType("nonNegativeInteger", convertToString((NonNegativeInteger) value), xmlStreamWriter);
        } else if (value instanceof NonPositiveInteger) {
            serializeAnyType("nonPositiveInteger", convertToString((NonPositiveInteger) value), xmlStreamWriter);
        } else {
            throw new XMLStreamException("Unknow type can not serialize");
        }
    }


    /**
     * this method writes the xsi:type attrubte and the value to the xmlstreamwriter
     * to serialize the anytype object
     * @param type  - xsd type of the attribute
     * @param value - string value of the object
     * @param xmlStreamWriter
     * @throws XMLStreamException
     */
    private static void serializeAnyType(String type,
                                         String value,
                                         XMLStreamWriter xmlStreamWriter)
            throws XMLStreamException {

        addTypeAttribute(xmlStreamWriter, type);
        xmlStreamWriter.writeCharacters(value);
    }

    private static void addTypeAttribute(XMLStreamWriter xmlStreamWriter, String type) throws XMLStreamException {
        String prefix = xmlStreamWriter.getPrefix(Constants.XSI_NAMESPACE);
        if (prefix == null) {
            prefix = BeanUtil.getUniquePrefix();
            xmlStreamWriter.writeNamespace(prefix, Constants.XSI_NAMESPACE);
            xmlStreamWriter.setPrefix(prefix, Constants.XSI_NAMESPACE);
        }

        prefix = xmlStreamWriter.getPrefix(Constants.XSD_NAMESPACE);
        if (prefix == null) {
            prefix = BeanUtil.getUniquePrefix();
            xmlStreamWriter.writeNamespace(prefix, Constants.XSD_NAMESPACE);
            xmlStreamWriter.setPrefix(prefix, Constants.XSD_NAMESPACE);
        }

        String attributeValue = null;
        if (prefix.equals("")) {
            attributeValue = type;
        } else {
            attributeValue = prefix + ":" + type;
        }

        xmlStreamWriter.writeAttribute(Constants.XSI_NAMESPACE, "type", attributeValue);
    }

    public static Object getAnyTypeObject(XMLStreamReader xmlStreamReader,
                                          Class extensionMapperClass) throws XMLStreamException {
        Object returnObject = null;

        // make sure reader is at the first element.
        while(!xmlStreamReader.isStartElement()){
            xmlStreamReader.next();
        }
        // first check whether this element is null or not
        String nillableValue = xmlStreamReader.getAttributeValue(Constants.XSI_NAMESPACE, "nil");
        if ("true".equals(nillableValue) || "1".equals(nillableValue)){
            returnObject = null;
            xmlStreamReader.next();
        } else {
            String attributeType = xmlStreamReader.getAttributeValue(Constants.XSI_NAMESPACE, "type");
            if (attributeType != null) {
                String attributeTypePrefix = "";
                if (attributeType.indexOf(":") > -1) {
                    attributeTypePrefix = attributeType.substring(0,attributeType.indexOf(":"));
                    attributeType = attributeType.substring(attributeType.indexOf(":") + 1);
                }
                NamespaceContext namespaceContext = xmlStreamReader.getNamespaceContext();
                String attributeNameSpace = namespaceContext.getNamespaceURI(attributeTypePrefix);

                if (Constants.XSD_NAMESPACE.equals(attributeNameSpace)) {
                    if ("base64Binary".equals(attributeType)) {
                        returnObject = XMLStreamReaderUtils.getDataHandlerFromElement(xmlStreamReader);
                    } else {
                        String attribValue = xmlStreamReader.getElementText();
                        if (attribValue != null) {
                            if (attributeType.equals("string")) {
                                returnObject = attribValue;
                            } else if (attributeType.equals("int")) {
                                returnObject = new Integer(attribValue);
                            } else if (attributeType.equals("QName")) {
                                String namespacePrefix = null;
                                String localPart = null;
                                if (attribValue.indexOf(":") > -1) {
                                    namespacePrefix = attribValue.substring(0, attribValue.indexOf(":"));
                                    localPart = attribValue.substring(attribValue.indexOf(":") + 1);
                                    returnObject = new QName(namespaceContext.getNamespaceURI(namespacePrefix), localPart);
                                }
                            } else if ("boolean".equals(attributeType)) {
                                returnObject = new Boolean(attribValue);
                            } else if ("anyURI".equals(attributeType)) {
                                try {
                                    returnObject = new URI(attribValue);
                                } catch (URI.MalformedURIException e) {
                                    throw new XMLStreamException("Invalid URI");
                                }
                            } else if ("date".equals(attributeType)) {
                                returnObject = ConverterUtil.convertXmlToDate(attribValue);
                            } else if ("dateTime".equals(attributeType)) {
                                returnObject = ConverterUtil.convertToDateTime(attribValue);
                            } else if ("time".equals(attributeType)) {
                                returnObject = ConverterUtil.convertToTime(attribValue);
                            } else if ("byte".equals(attributeType)) {
                                returnObject = new Byte(attribValue);
                            } else if ("short".equals(attributeType)) {
                                returnObject = new Short(attribValue);
                            } else if ("float".equals(attributeType)) {
                                returnObject = new Float(attribValue);
                            } else if ("long".equals(attributeType)) {
                                returnObject = new Long(attribValue);
                            } else if ("double".equals(attributeType)) {
                                returnObject = new Double(attribValue);
                            } else if ("decimal".equals(attributeType)) {
                                returnObject = new BigDecimal(attribValue);
                            } else if ("unsignedLong".equals(attributeType)) {
                                returnObject = new UnsignedLong(attribValue);
                            } else if ("unsignedInt".equals(attributeType)) {
                                returnObject = new UnsignedInt(attribValue);
                            } else if ("unsignedShort".equals(attributeType)) {
                                returnObject = new UnsignedShort(attribValue);
                            } else if ("unsignedByte".equals(attributeType)) {
                                returnObject = new UnsignedByte(attribValue);
                            } else if ("positiveInteger".equals(attributeType)) {
                                returnObject = new PositiveInteger(attribValue);
                            } else if ("negativeInteger".equals(attributeType)) {
                                returnObject = new NegativeInteger(attribValue);
                            } else if ("nonNegativeInteger".equals(attributeType)) {
                                returnObject = new NonNegativeInteger(attribValue);
                            } else if ("nonPositiveInteger".equals(attributeType)) {
                                returnObject = new NonPositiveInteger(attribValue);
                            } else {
                                throw new ADBException("Unknown type ==> " + attributeType);
                            }
                        } else {
                            throw new ADBException("Attribute value is null");
                        }
                    }
                } else {
                    try {
                        Method getObjectMethod = extensionMapperClass.getMethod("getTypeObject",
                                new Class[]{String.class, String.class, XMLStreamReader.class});
                        returnObject = getObjectMethod.invoke(null,
                                new Object[]{attributeNameSpace, attributeType, xmlStreamReader});
                    } catch (NoSuchMethodException e) {
                        throw new ADBException("Can not find the getTypeObject method in the " +
                                "extension mapper class ", e);
                    } catch (IllegalAccessException e) {
                        throw new ADBException("Can not access the getTypeObject method in the " +
                                "extension mapper class ", e);
                    } catch (InvocationTargetException e) {
                        throw new ADBException("Can not invoke the getTypeObject method in the " +
                                "extension mapper class ", e);
                    }

                }

            } else {
                throw new ADBException("Any type element type has not been given");
            }
        }
        return returnObject;
    }

    static {
        isCustomClassPresent = (System.getProperty(SYSTEM_PROPERTY_ADB_CONVERTERUTIL) != null);
        if (isCustomClassPresent){
            String className = System.getProperty(SYSTEM_PROPERTY_ADB_CONVERTERUTIL);
            try {
                customClass = Class.forName(className);
            } catch (ClassNotFoundException e) {
                log.error("Can not load the converter util class "
                        + className + " using default org.apache.axis2.databinding.utils.ConverterUtil class");
                isCustomClassPresent = false;
            }
        }
    }


}
