/*
 *   Copyright 2003-2004 The Apache Software Foundation.
// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved
 *
 *   Licensed 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.
 */


// !!! This include file must be first thing in file !!!
#include "../platforms/PlatformAutoSense.hpp"

#include <list>
#include <iostream>

#include <axis/Axis.hpp>
#include <axis/GDefine.hpp>

#include "SoapDeSerializer.h"
#include "SoapEnvelope.h"
#include "SoapKeywordMapping.h"
#include "URIMapping.h"
#include "SoapHeader.h"
#include "SoapMethod.h"
#include "SoapBody.h"
#include "SoapFault.h"
#include "ComplexElement.h"
#include "CharacterElement.h"
#include "apr_base64.h"
#include "HexCoder.h"
#include "../engine/XMLParserFactory.h"
#include "../xml/XMLParser.h"
#include "../xml/QName.h"
#include "../xml/AxisParseException.h"
#include "AxisSoapException.h"
#include "../common/AxisGenException.h"

#include "../common/AxisTrace.h"



AxisChar * pBodyContent;

AXIS_CPP_NAMESPACE_START

SoapDeSerializer::
SoapDeSerializer ()
{
    logEntryEngine("SoapDeSerializer::SoapDeSerializer")

    m_pParser = XMLParserFactory::getParserObject ();
    m_pEnv = NULL;
    m_pHeader = NULL;
    m_pCurrNode = NULL;
    m_pNode = NULL;
    m_pInputStream = NULL;
    m_nStatus = AXIS_SUCCESS;
    m_nSoapVersion = VERSION_LAST;
    
    m_doNotSkip = false;
    m_pStub = NULL;

    logExit()
}

SoapDeSerializer::
~SoapDeSerializer ()
{
    logEntryEngine("SoapDeSerializer::~SoapDeSerializer")

    delete m_pEnv;
    delete m_pHeader;
    if (m_pParser)
        XMLParserFactory::destroyParserObject (m_pParser);
    delete pBodyContent;
    
    logExit()
}

int SoapDeSerializer::
setInputStream (SOAPTransport * pInputStream)
{
    logEntryEngine("SoapDeSerializer::setInputStream")

    int iStatus = AXIS_FAIL;
    
    if (NULL != pInputStream)
    {
        m_pInputStream = pInputStream;
        iStatus        = m_pParser->setInputStream (pInputStream);
    }
    
    logExitWithReturnCode(iStatus)
    
    return iStatus;
}

/*
 * Routine to help obtain parser information and throw it as an exception
 */
void SoapDeSerializer::
throwParserException()
{
    logEntryEngine("SoapDeSerializer::throwParserException")

    AxisParseException e;
    
    if (m_pParser->getStatus() != AXIS_SUCCESS)
        e.setMessage(m_pParser->getErrorCode(), "AxisParseException:", m_pParser->getErrorString());
    else
        e.setMessage(SERVER_PARSE_PARSER_FAILED, "AxisParseException:");
        
    logThrowExceptionWithData("AxisParseException", e.what())
    
    throw e;
}

/*
 * Routine that handles getting next node, in the future when we sync
 * up rpc and doc processing and eliminate peek, we should be able to 
 * get rid of the first parameter!
 */
int SoapDeSerializer::
getNextNode(bool ifNotSet, bool characterMode, bool throwExcOnError)
{
    logSetFunctionNameEngine("SoapDeSerializer::getNextNode")
    
    int iStatus = AXIS_FAIL;

    // If node pointer is set and user requested that we 
    // only get next element if not set, return.
    if (ifNotSet && m_pNode)
        iStatus = AXIS_SUCCESS;
    else
    {
        // Ensure m_pNode is NULL before calling parser in case of exceptions.
        m_pNode = NULL;
        
        // Just a sanity check
        if (m_pParser)
        {
            try
            { 
                m_pNode = m_pParser->next(characterMode);
            }
            catch (AxisException &e)
            {
            	m_nStatus = AXIS_FAIL;
                if (throwExcOnError)
                    throw e;
            }
            
            // If no node obtained, either there is no more data to read (at this time
            // we treat this as an error but we do not throw an exception for this) or the 
            // parser had an exception, in which case we throw an exception if requested.
            if (!m_pNode)
            {
                m_nStatus = AXIS_FAIL;
                if (throwExcOnError && (AXIS_FAIL == m_pParser->getStatus()))
                    throwParserException();
            }
            else
                iStatus = AXIS_SUCCESS;
        }
    }
    
    if (AXIS_SUCCESS != iStatus)
    {
        logDebug("Status being returned is AXIS_FAIL")
    }

    return iStatus;
}


/*
 * Routine that ensures we are actually skipping the expected node...usually an end node.
 */
int SoapDeSerializer::
skipNode(bool verifyIfEndNode, bool throwExcOnError)
{
    logEntryEngine("SoapDeSerializer::skipNode")

    int rc = getNextNode(false, false, throwExcOnError);
    
    if (rc == AXIS_SUCCESS)
    {
        if (verifyIfEndNode)
        {
            // TODO add code to determine if in fact 
            // TODO the node we are about to skip is an end node. If not, we need 
            // TODO to throw an exception since there could be extra elements that 
            // TODO is due to server/client differences in wsdl being used, etc.  
            // TODO in addition, a check is another safeguard.            
        }
        
        m_pNode = NULL;
    }
    
    logExitWithReturnCode(rc)

    return rc;
}

SoapEnvelope *SoapDeSerializer::
getEnvelope ()
{
    logEntryEngine("SoapDeSerializer::getEnvelope")

    if (AXIS_FAIL == getNextNode(true))  
    {
        logExitWithPointer(NULL)

        return NULL;
    }
            
    // Better be a start-element.
    if (START_ELEMENT != m_pNode->m_type)
    {
        m_nStatus = AXIS_FAIL;
        
        logThrowExceptionWithData("AxisSoapException - CLIENT_SOAP_SOAP_CONTENT_ERROR", "Start-element for SOAP Envelope not found.")

        throw AxisSoapException (CLIENT_SOAP_SOAP_CONTENT_ERROR, "Start-element for SOAP Envelope not found.");
    }
            
    // We are expecting a SOAP envelope.  
    if (0 != strcmp(m_pNode->m_pchNameOrValue,SoapKeywordMapping::map(SOAP_VER_1_2).pchWords[SKW_ENVELOPE]))
    {
        m_nStatus = AXIS_FAIL;
        
        logThrowExceptionWithData("AxisSoapException - CLIENT_SOAP_SOAP_CONTENT_ERROR", "Element is not a SOAP Envelope.")

        throw AxisSoapException (CLIENT_SOAP_SOAP_CONTENT_ERROR, "Element is not a SOAP Envelope.");
    }
    
    // No try/catch block needed here since we already have the node
    SoapEnvelope *m_pEnvl = new SoapEnvelope ();
    
    // set all attributes of SoapEnvelope 
    std::list<Attribute*> attributeList0;
    Attribute * pAttr = new Attribute ( attributeList0);

    pAttr->setValue (m_pNode->m_pchNamespace);
    m_pEnvl->addNamespaceDecl (pAttr);

    if (0 == strcmp (m_pNode->m_pchNamespace, SoapKeywordMapping::map (SOAP_VER_1_1).pchNamespaceUri))
        m_nSoapVersion = SOAP_VER_1_1;
    else if (0 == strcmp (m_pNode->m_pchNamespace, SoapKeywordMapping::map (SOAP_VER_1_2).pchNamespaceUri))
        m_nSoapVersion = SOAP_VER_1_2;
    else
        m_nSoapVersion = VERSION_LAST;

    // Set Attributes 
    for (int i = 0; m_pNode->m_pchAttributes[i]; i += 3)
    {
        std::list<Attribute*> attributeList1;
        pAttr = new Attribute (attributeList1);
        pAttr->setLocalName (m_pNode->m_pchAttributes[i]);
        pAttr->setURI (m_pNode->m_pchAttributes[i + 1]);
        pAttr->setValue (m_pNode->m_pchAttributes[i + 2]);
        m_pEnvl->addAttribute (pAttr);
    }

    // indicate node consumed and return envelope
    m_pNode = NULL;  
    
    logExitWithPointer(m_pEnvl)
    
    return m_pEnvl;
}

/*
 * Header block parsing should be done differently for different SOAP versions.
 * Since the Header blocks may be requested in a different order than it is in 
 * the SOAP stream there must be a mechanism to manage the situation. Possibly 
 * to re-parse the stream part which has unused header blocks.
 */
IHeaderBlock *SoapDeSerializer::
getHeaderBlock (const AxisChar * pName, const AxisChar * pNamespace)
{
    logEntryEngine("SoapDeSerializer::getHeaderBlock")

    IHeaderBlock * returnValue = NULL;
    
    if (m_pHeader)
        returnValue = m_pHeader->getHeaderBlock (pName, pNamespace, true);
    
    logExitWithPointer(returnValue)

    return returnValue;
}

int SoapDeSerializer::
getHeader ()
{
    logEntryEngine("SoapDeSerializer::getHeader")

    if (m_pHeader || AXIS_FAIL == getNextNode())
    {
        logExitWithReturnCode(m_nStatus)

        return m_nStatus;
    }

    if ((START_ELEMENT == m_pNode->m_type) 
            && (m_nSoapVersion != VERSION_LAST)
            && (0 == strcmp (m_pNode->m_pchNameOrValue,SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_HEADER])))
    {
        delete m_pHeader;
        m_pHeader = new SoapHeader ();
        
        // Set any attributes/namspaces to the SoapHeader object
        while (true)
        {
            if (AXIS_FAIL == getNextNode(false, true, false))       
                break;
    
            if ((END_ELEMENT == m_pNode->m_type) &&
                (0 == strcmp (m_pNode->m_pchNameOrValue,SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_HEADER])))
            {
                m_pNode = NULL; // indicate node consumed
                break;
            }
    
            // following is done to ignore anything (eg : the toplevel whitespaces) but a start element.
            if (START_ELEMENT != m_pNode->m_type)
            {
                m_pNode = NULL; // indicate node consumed
                continue;
            }
    
            HeaderBlock *pHeaderBlock = new HeaderBlock ();
    
            if (m_pNode->m_pchNamespace)
                pHeaderBlock->setURI (m_pNode->m_pchNamespace);
    
            pHeaderBlock->setLocalName (m_pNode->m_pchNameOrValue);
    
            if ((m_pNode->m_pchAttributes[0]) != NULL)
            {
                int iAttributeArrayIndex = 0;
        
                while (true)
                {
                    std::list<Attribute*> attributeList2;
                    Attribute *pAttribute = new Attribute (attributeList2);
                    pAttribute->setLocalName (m_pNode->m_pchAttributes[iAttributeArrayIndex++]);
                    pAttribute->setURI (m_pNode->m_pchAttributes[iAttributeArrayIndex++]);
                    pAttribute->setValue (m_pNode->m_pchAttributes[iAttributeArrayIndex++]);
        
                    pHeaderBlock->addAttribute (pAttribute);
        
                    if (m_pNode->m_pchAttributes[iAttributeArrayIndex] == '\0')
                        break;
                }
            }
    
            BasicNode *pNodeList[10];
            pNodeList[0] = NULL;
            int iListPos = 0;
            int iLevel = 0;
    
            while (true)
            {
                if (AXIS_FAIL == getNextNode(false, true, false))
                    break;
        
                if (END_ELEMENT == m_pNode->m_type)
                {
                    if (iLevel == 0)
                    {
                        //do nothing
                        m_pHeader->addHeaderBlock (pHeaderBlock);
                        break;
                    }
                    else if (iLevel == 1)
                    {
                        if ((pNodeList[0]) != NULL)
                        {
                            pHeaderBlock->addChild (pNodeList[0]);
                            iListPos--;
                            iLevel--;
                        }
                    }
                    else
                    {
                        (pNodeList[iListPos - 2])->addChild (pNodeList[iListPos - 1]);
                        iListPos--;
                        iLevel--;
                    }
                }
                else if (START_ELEMENT == m_pNode->m_type)
                {
                    //createBaisNode and setValue
                    BasicNode *pComplexElement = new ComplexElement ();
        
                    if (m_pNode->m_pchNamespace)
                        pComplexElement->setURI (m_pNode->m_pchNamespace);
        
                    pComplexElement->setLocalName (m_pNode->m_pchNameOrValue);
        
                    //addtoList
                    pNodeList[iListPos] = pComplexElement;
                    iListPos++;
                    iLevel++;
                }
                else if (CHARACTER_ELEMENT == m_pNode->m_type)
                {
                    //createBasicNode and setValue
                    BasicNode *pBasicNode = new CharacterElement (m_pNode->m_pchNameOrValue);
        
                    //addToImmidiateParent
                    if (iLevel == 0)
                        pHeaderBlock->addChild (pBasicNode);
                    else
                        (pNodeList[iListPos - 1])->addChild (pBasicNode);
                }
            } // end while
        }
    }

    logExitWithReturnCode(m_nStatus)

    return m_nStatus;
}

// This method adds to allow "all" & "choice" constructs to peek head next element.
const char*SoapDeSerializer::
peekNextElementName ()
{ 
    logEntryEngine("SoapDeSerializer::peekNextElementName")

    const char*name = NULL;
    
    if (m_pParser)
        name = m_pParser->peek ();
            
    logExitWithString(name)

    return name;
}

int SoapDeSerializer::
getBody ()
{
    logEntryEngine("SoapDeSerializer::getBody")

    int iStatus = AXIS_FAIL;
    
    if (AXIS_FAIL == getNextNode(true))
        iStatus = m_nStatus;
    else
    {
        // previous header searching may have left a node unidentified
        if ((START_ELEMENT == m_pNode->m_type) 
                && (m_nSoapVersion != VERSION_LAST)
                && (0 == strcmp (m_pNode->m_pchNameOrValue,SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY])))
        {
            // indicate node consumed
            m_pNode = NULL; 
    
            // peek for the method name
            m_strMethodNameToInvoke = m_pParser->peek();
            
            iStatus = AXIS_SUCCESS;
        }
    }

    logExitWithReturnCode(iStatus)

    return iStatus;
}

int SoapDeSerializer::
checkMessageBody (const AxisChar * pName, const AxisChar * pNamespace)
{
    return validateMessageBody(pName, pNamespace, true);
}

int SoapDeSerializer::
validateMessageBody(const AxisChar * pName, const AxisChar * pNamespace, bool consumeIt)
{
    logEntryEngine("SoapDeSerializer::validateMessageBody")

    int iStatus = AXIS_FAIL;
    
    // Will throw exception if failure in parser
    if (AXIS_FAIL != getNextNode(true))
    {
        if (START_ELEMENT != m_pNode->m_type)
        {
            logThrowExceptionWithData("AxisSoapException - CLIENT_SOAP_SOAP_CONTENT_ERROR", "Start-element was not found.")

            throw AxisSoapException (CLIENT_SOAP_SOAP_CONTENT_ERROR, "Start-element was not found.");
        }
    
        // If a fault has occurred or the node name is unexpected, throw exception
        // deserialize it as doc literal by setting style. 
        if (0 != strcmp (m_pNode->m_pchNameOrValue, pName))
        {
            setStyle (DOC_LITERAL);
            
            logThrowException("AxisGenException - AXISC_NODE_VALUE_MISMATCH_EXCEPTION")
                    
            throw AxisGenException (AXISC_NODE_VALUE_MISMATCH_EXCEPTION);
        }
    
        // indicate node consumed
        if (consumeIt)
            m_pNode = NULL; 
        
        iStatus = AXIS_SUCCESS;
    }
    
    logExitWithReturnCode(iStatus)

    return iStatus;
}

// Used for one-way message processing, to initiate a fault.
void SoapDeSerializer::
initiateFault (const AxisChar * pNamespace)
{
    logEntryEngine("SoapDeSerializer::initiateFault")

    // Will throw exception if failure in parser
    if (AXIS_FAIL != getNextNode(true))
    {
        if (START_ELEMENT != m_pNode->m_type)
        {
            logThrowExceptionWithData("AxisSoapException - CLIENT_SOAP_SOAP_CONTENT_ERROR", "Start-element was not found.")
            
            throw AxisSoapException (CLIENT_SOAP_SOAP_CONTENT_ERROR, "Start-element was not found.");
        }
    
        setStyle (DOC_LITERAL);
        
        logThrowException("AxisGenException - AXISC_NODE_VALUE_MISMATCH_EXCEPTION")

        throw AxisGenException (AXISC_NODE_VALUE_MISMATCH_EXCEPTION); 
    }
    
    logExit()
}

void *SoapDeSerializer::
checkForFault (const AxisChar * pName, const AxisChar * pNamespace)
{
    logEntryEngine("SoapDeSerializer::checkForFault")

    if (0 != strcmp ("Fault", pName))
    {
        logThrowExceptionWithData("AxisGenException - AXISC_NODE_VALUE_MISMATCH_EXCEPTION", "Fault element name not valid.")

        throw AxisGenException (AXISC_NODE_VALUE_MISMATCH_EXCEPTION, 
                                "Fault element name not valid.");
    }
        
    if (0 != strcmp (m_pNode->m_pchNameOrValue, pName))
    {
        m_nStatus = AXIS_SUCCESS;
        m_pNode = NULL;
        
        logThrowException("AxisGenException - AXISC_NODE_VALUE_MISMATCH_EXCEPTION")

        throw AxisGenException (AXISC_NODE_VALUE_MISMATCH_EXCEPTION);
    }

    char *pcDetail = NULL;
    char *pcFaultCode = NULL;
    char *pcFaultstring = NULL;
    char *pcFaultactor = NULL;
    
    SoapFault *pFault = new SoapFault ();
    pFault->setDeSerializer (this);

    // indicate node consumed
    m_nStatus = AXIS_SUCCESS;
    m_pNode = NULL;  

    // We deserialize fault code in doc literal. 
    m_nStyle = getStyle ();
    setStyle (DOC_LITERAL);
    
    // getElement or peek will throw exceptions, so need to clean up memory allocations
    try
    {
        // Get fault code
        pcFaultCode = getElementAsString ("faultcode", 0);
        pFault->setFaultcode (pcFaultCode == NULL ? "" : pcFaultCode);
        delete [] pcFaultCode;
        
        // Get fault string
        pcFaultstring = getElementAsString ("faultstring", 0);
        pFault->setFaultstring (pcFaultstring == NULL ? "" : pcFaultstring);
        delete [] pcFaultstring;
     
        // faultactor is optional
        const char* elementName = peekNextElementName();
        if (strcmp(elementName, "faultactor") == 0)
        {
            pcFaultactor = getElementAsString ("faultactor", 0);
            pFault->setFaultactor (pcFaultactor == NULL ? "" : pcFaultactor);
            delete [] pcFaultactor;
        }      
         
        // detail is optional.   
        // Changed the namespace from null to a single space (an impossible
        // value) to help method know that it is parsing a fault message.
        elementName = peekNextElementName();
        if (strcmp(elementName, "detail") == 0)
        {
            pcDetail = getElementAsString ("detail", " ");
            
            if (pcDetail)
            {
                pFault->setFaultDetail (pcDetail);
                delete [] pcDetail;          
            }
            else
            {
                const char *pcCmplxFaultName = "";
                
                if ((AXIS_SUCCESS == getNextNode(true)) && m_pNode->m_pchNameOrValue)
                    pcCmplxFaultName = m_pNode->m_pchNameOrValue;
                    
                pFault->setCmplxFaultObjectName (pcCmplxFaultName);
            }
        }
    }
    catch ( ... )
    {
        setStyle (m_nStyle);
        
        delete [] pcFaultCode;
        delete [] pcFaultstring;
        delete [] pcFaultactor;
        delete [] pcDetail;
        delete pFault;
        
        logRethrowException()
        
        throw;
    }

    setStyle (m_nStyle);
    
    logExitWithPointer(pFault)
    
    return pFault;
}

int SoapDeSerializer::
init ()
{
    logEntryEngine("SoapDeSerializer::init")

    m_pNode = NULL;
    m_pCurrNode = NULL;

    delete m_pEnv;
    m_pEnv = NULL;

    delete m_pHeader;
    m_pHeader = NULL;

    m_nSoapVersion = VERSION_LAST;
    m_nStatus = AXIS_SUCCESS;

    m_pStub = NULL;

    logExitWithReturnCode(m_nStatus)

    return m_nStatus;
}

int SoapDeSerializer::
getVersion ()
{
    logEntryEngine("SoapDeSerializer::getVersion")

    if (VERSION_LAST == m_nSoapVersion)
    {
        delete m_pEnv;
        m_pEnv = NULL;
        m_pEnv = getEnvelope ();
    }

    logExitWithInteger(m_nSoapVersion)
    
    return m_nSoapVersion;
}

/*
 * Get Size of the single dimension array from arrayType attribute
 * Ex : enc:arrayType="xs:string[6]"
 * RPC/Encoded only processing.
 */
int SoapDeSerializer::
getArraySize ()
{
    logEntryEngine("SoapDeSerializer::getArraySize")

    int nSize = 0;
    
    // If not RPC or failure in getNextNode, return zero.
    if (RPC_ENCODED != m_nStyle || (AXIS_FAIL == getNextNode()))
    {
        logExitWithInteger(nSize)

        return nSize;
    }
    
    // first check whether this is a start element node
    if (START_ELEMENT == m_pNode->m_type)
    {
        // If start-end element, then empty array
        if (START_END_ELEMENT == m_pNode->m_type2)
        {
            skipNode();
            
            logExitWithInteger(nSize)

            return nSize;
        }
    }
    else if (END_ELEMENT == m_pNode->m_type)
    {
        logExitWithInteger(nSize)

        return nSize;
    }

    for (int i = 0; m_pNode->m_pchAttributes[i]; i += 3)
    {
        if (URI_ENC == URIMapping::getURI (m_pNode->m_pchAttributes[i + 1])
            && (0 == strcmp (m_pNode->m_pchAttributes[i],
                             SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_ARRAYTYPE])))
        {
            QName qn;
    
            qn.splitQNameString (m_pNode->m_pchAttributes[i + 2], '[');
            nSize = strtol (qn.localname, &m_pEndptr, 10);
            qn.mergeQNameString ('[');
    
            if (nSize == 0)
                skipNode();
                
            logExitWithInteger(nSize)

            return nSize;
        }
    }

    logExitWithInteger(nSize)

    return nSize;
}


/*
 * In rpc/encoded style the stream is as follows,
 * <abc:ArrayOfPoints xmlns:abc="http://www.opensource.lk/Points"
 *    xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
 *    enc:arrayType="xsd:Point[2]">
 *    <abc:Point><x>5</x><y>6</y></abc:Point>
 *    <abc:Point><x>7</x><y>8</y></abc:Point>
 * </abc:ArrayOfPoints>
 * But in doc/literal style it is,
 *    <points><x>5</x><y>6</y></points>
 *    <points><x>7</x><y>8</y></points>
 *
 */

Axis_Array *SoapDeSerializer::
getCmplxArray (Axis_Array* pArray, 
               void *pDZFunct, void *pCreFunct, void *pDelFunct, 
               const AxisChar * pName, const AxisChar * pNamespace)
{
    logEntryEngine("SoapDeSerializer::getCmplxArray")

    // if anything has gone wrong earlier just do nothing 
    if (AXIS_SUCCESS == m_nStatus)
    {
        // Loop through the array adding elements.
        int arraySize = getArraySize ();    
        int count = 0;
        const char* elementName;
        
        while(RPC_ENCODED != m_nStyle || count < arraySize)
        {
            // For RPC-encoded arrays, the element name in array cannot be derived - 
            // within an array value element names are not significant - so  
            // we read until end-of-element is encountered (i.e. null string 
            // is returned from peek()). 
            elementName = m_pParser->peek();
            if ((RPC_ENCODED == m_nStyle && 0x00 != *elementName) || strcmp(elementName, pName) == 0)
                pArray->addElement(getCmplxObject(pDZFunct, pCreFunct, pDelFunct, pName, pNamespace));
            else
                break;    
                
            ++count;    
        }
        
        if (AXIS_FAIL == m_nStatus) // TODO - not sure this line is needed
            m_pNode = NULL;         // TODO - not sure this line is needed
        else if (arraySize > 0)
            skipNode();
    }
        
    logExitWithPointer(pArray)

    return pArray;
}

/*
 * In rpc/encoded style the stream is as follows,
 * <abc:ArrayOfPhoneNumbers xmlns:abc="http://example.org/2001/06/numbers"
 *    xmlns:enc="http://www.w3.org/2001/06/soap-encoding"
 *    enc:arrayType="xsd:string[2]">
 *    <item>+94-112-500500</item>
 *    <item>+94-112-500500</item>
 * </abc:ArrayOfPhoneNumbers>
 * But in doc/literal style it is,
 *    <phonenumbers>+94-112-500500</phonenumbers>
 *    <phonenumbers>+94-112-500500</phonenumbers> 
 *
 *
 */

Axis_Array*SoapDeSerializer::
getBasicArray (XSDTYPE nType, const AxisChar * pName, const AxisChar * pNamespace)
{
    logEntryEngine("SoapDeSerializer::getBasicArray")

    int size = 0;      
    Axis_Array* Array = new Axis_Array();
    Array->m_Type = nType;

    // if anything has gone wrong earlier just do nothing
    if (AXIS_SUCCESS == m_nStatus)
    {
        // Loop through the array adding elements.
        IAnySimpleType* pSimpleType = NULL;
        void * pValue = NULL;
        
        try
        {
            size = getArraySize ();
            const char* elementName;
            int count = 0;
                    
            while(RPC_ENCODED != m_nStyle || count < size)
            {
                // For RPC-encoded arrays, the element name in array cannot be derived - 
                // within an array value element names are not significant -   
                // so we read until end-of-element is encountered (i.e. null string 
                // is returned from peek()). 
                elementName = m_pParser->peek();
                if ((RPC_ENCODED == m_nStyle && 0x00 != *elementName) || strcmp(elementName, pName) == 0)
                {
                    // TODO instead of deleting the pointer use it by by-passing addElement().
                    if (XSD_ANYTYPE != nType)
                    {
                        if (0 == count)
                            pSimpleType = AxisUtils::createSimpleTypeObject(nType);
                        getElement(pName, pNamespace, pSimpleType, (bool)(RPC_ENCODED == m_nStyle));
                        pValue = pSimpleType->getValue();
                        Array->addElement(pValue);
                        Axis::AxisDelete(pValue, pSimpleType->getType());
                    }
                    else
                    {
                        pValue = getElementAsAnyType(pName, pNamespace);
                        Array->addElement(pValue);
                        Axis::AxisDelete(pValue, XSD_ANYTYPE);
                    }
                    
                    pValue = NULL;
                }
                else
                    break;
                    
                ++count;
            }             
        }
        catch ( ... )
        {
            if (pSimpleType)
            { 
                if (pValue)
                    Axis::AxisDelete(pValue, pSimpleType->getType());
                delete pSimpleType;
            }
            
            delete Array;
            
            logRethrowException()
            
            throw;
        }
        
        delete pSimpleType;
        
        if (AXIS_FAIL == m_nStatus) // TODO - not sure this line is needed
            m_pNode = NULL;         // TODO - not sure this line is needed
        else if (size > 0)
            skipNode();
    }
    
    logExitWithPointer(Array)

    return Array;    
}

/*
 * In doc/lit style pName is the name of the type instance "result"
 *  <result>
 *        <name>Widgets Inc.</name> 
 *        <symbol>WID</symbol> 
 *        <public>true</public> 
 *  </result>
 * But in rpc/encoded style pName is the name of the type "QuoteInfoType"
 *  <tns:QuoteInfoType xmlns:tns="http://www.getquote.org/test">
 *        <name xsi:type="xsd:string">Widgets Inc.</name> 
 *        <symbol xsi:type="xsd:string">WID</symbol> 
 *        <public xsi:type="xsd:boolean">true</public> 
 *  </tns:QuoteInfoType>
 *
 */
void *SoapDeSerializer::
getCmplxObject (void *pDZFunct, void *pCreFunct, void *pDelFunct, 
                const AxisChar * pName, const AxisChar * pNamespace, bool isFault)
{
    logEntryEngine("SoapDeSerializer::getCmplxObject")

    if (!isFault)
    {
    	if (AXIS_SUCCESS == m_nStatus && (RPC_ENCODED != m_nStyle) && (m_pNode == NULL))
    	{
    		const char*name = peekNextElementName();
    		if (0 != strcmp (pName, name))
    		{
                logExitWithPointer(NULL)

                return NULL; 
    		}
    	}
    	
        if (AXIS_SUCCESS != m_nStatus || (AXIS_FAIL == getNextNode(RPC_ENCODED != m_nStyle)))
        {
            logExitWithPointer(NULL)

            return NULL;  
        }
    }
    
    if (RPC_ENCODED != m_nStyle) // TODO - why do we selectively do this check and not for all?
        if (0 != strcmp (pName, m_pNode->m_pchNameOrValue))
        {
            /*
             * TODO: Need to verify what WS-I 1.0 says
             * about the mandatory of all the elements in the response in case of
             * null value or none filled value. Some Web services servers work
             * like this. This apply for all the rest of the deserializer.
             */
            logExitWithPointer(NULL)

            return NULL;            
        }
    
    // TODO - even if node is nil, there may be attributes associated with the element that 
    // TODO - need to be deserialized - thus in the generated code we need to get the nil 
    // TODO - attribute if element is nillable and check if it is true or false, in which case
    // TODO - we would short-circuit the deserialization after any other attributes have been 
    // TODO - obtained. Thus changes will need to be made here and in the code generator.             
    // if node contain attributes let them be used by the complex type's deserializer
    if (isNilValue())
    {
        skipNode();
        
        logExitWithPointer(NULL)

        return NULL;
    }
    
    // Make attributes available to code that deserializes the attributes
    m_pCurrNode = NULL;
    if (0 != m_pNode->m_pchAttributes[0])
        m_pCurrNode = m_pNode;    
    
    // indicate node consumed
    m_pNode = NULL; 
    
    if (!isFault && AXIS_FAIL == m_nStatus)  
    {
        logExitWithPointer(NULL)

        return NULL;  
    }

    // Call the Axis-generated routine that will deserialize complex object,
    // including any attributes.
    
    logDebugArg1("Calling object create function for %s", pName)
    
    void *pObject = ((AXIS_OBJECT_CREATE_FUNCT) pCreFunct) (0);
    
    logDebugArg2("Returned from object create function for %s, returned object %p", pName, pObject)

    if (pObject && pDZFunct)
    {
        try 
        {
            m_doNotSkip = false;

            logDebugArg1("Calling object deserializer function for %s", pName)
            
            m_nStatus =    ((AXIS_DESERIALIZE_FUNCT) pDZFunct) (pObject, this);
            
            logDebugArg2("Returned from object deserializer function for %s, status=%d", pName, m_nStatus)

        
            if (AXIS_SUCCESS == m_nStatus)
            {
                if (!m_doNotSkip)
                  skipNode();
            }
            else
            {
                logDebugArg2("Calling object delete function for %s for object %p", pName, pObject)
                
                ((AXIS_OBJECT_DELETE_FUNCT) pDelFunct) (pObject, 0);
                
                logDebugArg1("Returned from object delete function for %s", pName)
            
                pObject = NULL;
            }
        }
        catch ( ... )
        {
            logDebugArg2("Calling object delete function for %s for object %p", pName, pObject)
            
            ((AXIS_OBJECT_DELETE_FUNCT) pDelFunct) (pObject, 0);
            
            logDebugArg1("Returned from object delete function for %s", pName)

            logRethrowException()

            throw;
        }
    }

    logExitWithPointer(pObject)

    return pObject;
}

void * SoapDeSerializer::
getAttribute(const AxisChar* pName, const AxisChar * pNamespace, IAnySimpleType * pSimpleType)
{
    logEntryEngine("SoapDeSerializer::getAttribute")

    void *returnValue = NULL;
    
    if (m_pCurrNode)
    {
        for (int i=0; m_pCurrNode->m_pchAttributes[i]; i += 3)
        {
            if (0 == strcmp(m_pCurrNode->m_pchAttributes[i], pName))
            {
                pSimpleType->deserialize(m_pCurrNode->m_pchAttributes[i+2]);
                returnValue = pSimpleType->getValue();
                break;
            }
        }
    }
    
    logExitWithPointer(returnValue)

    return returnValue;
}

xsd__int *SoapDeSerializer::
getAttributeAsInt (const AxisChar * pName, const AxisChar * pNamespace)
{
    Int simpleType;
    return (xsd__int *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__boolean *SoapDeSerializer::
getAttributeAsBoolean (const AxisChar * pName, const AxisChar * pNamespace)
{
    Boolean simpleType;
    return (xsd__boolean *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__unsignedInt *SoapDeSerializer::
getAttributeAsUnsignedInt (const AxisChar * pName, const AxisChar * pNamespace)
{
    UnsignedInt simpleType;
    return (xsd__unsignedInt *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__short *SoapDeSerializer::
getAttributeAsShort (const AxisChar * pName, const AxisChar * pNamespace)
{
    Short simpleType;
    return (xsd__short *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__unsignedShort *SoapDeSerializer::
getAttributeAsUnsignedShort (const AxisChar * pName, const AxisChar * pNamespace)
{
    UnsignedShort simpleType;
    return (xsd__unsignedShort *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__byte *SoapDeSerializer::
getAttributeAsByte (const AxisChar * pName, const AxisChar * pNamespace)
{
    Byte simpleType;
    return (xsd__byte *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__unsignedByte *SoapDeSerializer::
getAttributeAsUnsignedByte (const AxisChar * pName, const AxisChar * pNamespace)
{
    UnsignedByte simpleType;
    return (xsd__unsignedByte *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__long *SoapDeSerializer::
getAttributeAsLong (const AxisChar * pName, const AxisChar * pNamespace)
{
    Long simpleType;
    return (xsd__long *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__integer *SoapDeSerializer::
getAttributeAsInteger (const AxisChar * pName, const AxisChar * pNamespace)
{
    Integer simpleType;
    return (xsd__integer *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__nonNegativeInteger *SoapDeSerializer::
getAttributeAsNonNegativeInteger (const AxisChar * pName, const AxisChar * pNamespace)
{
    NonNegativeInteger simpleType;
    return (xsd__nonNegativeInteger *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__positiveInteger *SoapDeSerializer::
getAttributeAsPositiveInteger (const AxisChar * pName, const AxisChar * pNamespace)
{
    PositiveInteger simpleType;
    return (xsd__positiveInteger *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__nonPositiveInteger *SoapDeSerializer::
getAttributeAsNonPositiveInteger (const AxisChar * pName, const AxisChar * pNamespace)
{
    NonPositiveInteger simpleType;
    return (xsd__nonPositiveInteger *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__negativeInteger *SoapDeSerializer::
getAttributeAsNegativeInteger (const AxisChar * pName, const AxisChar * pNamespace)
{
    NegativeInteger simpleType;
    return (xsd__negativeInteger *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__unsignedLong *SoapDeSerializer::
getAttributeAsUnsignedLong (const AxisChar *pName, const AxisChar * pNamespace)
{
    UnsignedLong simpleType;
    return (xsd__unsignedLong *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__float *SoapDeSerializer::
getAttributeAsFloat (const AxisChar * pName, const AxisChar * pNamespace)
{
    Float simpleType;
    return (xsd__float *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__double *SoapDeSerializer::
getAttributeAsDouble (const AxisChar * pName, const AxisChar * pNamespace)
{
    Double simpleType;
    return (xsd__double *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__decimal *SoapDeSerializer::
getAttributeAsDecimal (const AxisChar * pName, const AxisChar * pNamespace)
{
    Decimal simpleType;
    return (xsd__decimal *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__NOTATION SoapDeSerializer::
getAttributeAsNOTATION (const AxisChar * pName, const AxisChar * pNamespace)
{
    NOTATION simpleType;
    return (xsd__NOTATION)getAttribute(pName, pNamespace, &simpleType);
}

xsd__string SoapDeSerializer::
getAttributeAsString (const AxisChar * pName, const AxisChar * pNamespace)
{
    String simpleType;
    return (xsd__string)getAttribute(pName, pNamespace, &simpleType);
}

xsd__normalizedString SoapDeSerializer::
getAttributeAsNormalizedString (const AxisChar * pName, const AxisChar * pNamespace)
{
    NormalizedString simpleType;
    return (xsd__normalizedString)getAttribute(pName, pNamespace, &simpleType);
}

xsd__token SoapDeSerializer::
getAttributeAsToken (const AxisChar * pName, const AxisChar * pNamespace)
{
    Token simpleType;
    return (xsd__token)getAttribute(pName, pNamespace, &simpleType);
}

xsd__language SoapDeSerializer::
getAttributeAsLanguage (const AxisChar * pName, const AxisChar * pNamespace)
{
    Language simpleType;
    return (xsd__language)getAttribute(pName, pNamespace, &simpleType);
}

xsd__NMTOKEN SoapDeSerializer::
getAttributeAsNMTOKEN (const AxisChar * pName, const AxisChar * pNamespace)
{
    NMTOKEN simpleType;
    return (xsd__NMTOKEN)getAttribute(pName, pNamespace, &simpleType);
}

xsd__NMTOKENS SoapDeSerializer::
getAttributeAsNMTOKENS (const AxisChar * pName, const AxisChar * pNamespace)
{
    NMTOKENS simpleType;
    return (xsd__NMTOKENS)getAttribute(pName, pNamespace, &simpleType);
}

xsd__Name SoapDeSerializer::
getAttributeAsName (const AxisChar * pName, const AxisChar * pNamespace)
{
    Name simpleType;
    return (xsd__Name)getAttribute(pName, pNamespace, &simpleType);
}

xsd__NCName SoapDeSerializer::
getAttributeAsNCName (const AxisChar * pName, const AxisChar * pNamespace)
{
    NCName simpleType;
    return (xsd__NCName)getAttribute(pName, pNamespace, &simpleType);
}

xsd__ID SoapDeSerializer::
getAttributeAsID (const AxisChar * pName, const AxisChar * pNamespace)
{
    ID simpleType;
    return (xsd__ID)getAttribute(pName, pNamespace, &simpleType);
}

xsd__IDREF SoapDeSerializer::
getAttributeAsIDREF (const AxisChar * pName, const AxisChar * pNamespace)
{
    IDREF simpleType;
    return (xsd__IDREF)getAttribute(pName, pNamespace, &simpleType);
}

xsd__IDREFS SoapDeSerializer::
getAttributeAsIDREFS (const AxisChar * pName, const AxisChar * pNamespace)
{
    IDREFS simpleType;
    return (xsd__IDREFS)getAttribute(pName, pNamespace, &simpleType);
}

xsd__ENTITY SoapDeSerializer::
getAttributeAsENTITY (const AxisChar * pName, const AxisChar * pNamespace)
{
    ENTITY simpleType;
    return (xsd__ENTITY)getAttribute(pName, pNamespace, &simpleType);
}

xsd__ENTITIES SoapDeSerializer::
getAttributeAsENTITIES (const AxisChar * pName, const AxisChar * pNamespace)
{
    ENTITIES simpleType;
    return (xsd__ENTITIES)getAttribute(pName, pNamespace, &simpleType);
}

xsd__anyURI SoapDeSerializer::
getAttributeAsAnyURI (const AxisChar * pName, const AxisChar * pNamespace)
{
    AnyURI simpleType;
    return (xsd__anyURI)getAttribute(pName, pNamespace, &simpleType);
}

xsd__QName SoapDeSerializer::
getAttributeAsQName (const AxisChar * pName, const AxisChar * pNamespace)
{
    XSD_QName simpleType;
    return (xsd__QName)getAttribute(pName, pNamespace, &simpleType);
}

xsd__hexBinary *SoapDeSerializer::
getAttributeAsHexBinary (const AxisChar * pName, const AxisChar * pNamespace)
{
    HexBinary simpleType;
    return (xsd__hexBinary *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__base64Binary *SoapDeSerializer::
getAttributeAsBase64Binary (const AxisChar * pName, const AxisChar * pNamespace)
{
    Base64Binary simpleType;
    return (xsd__base64Binary *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__dateTime *SoapDeSerializer::
getAttributeAsDateTime (const AxisChar * pName, const AxisChar * pNamespace)
{
    DateTime simpleType;
    return (xsd__dateTime *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__date *SoapDeSerializer::
getAttributeAsDate (const AxisChar * pName, const AxisChar * pNamespace)
{
    Date simpleType;
    return (xsd__date *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__time *SoapDeSerializer::
getAttributeAsTime (const AxisChar * pName, const AxisChar * pNamespace)
{
    Time simpleType;
    return (xsd__time *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__gDay*SoapDeSerializer::
getAttributeAsGDay (const AxisChar * pName, const AxisChar * pNamespace)
{
    GDay simpleType;
    return (xsd__gDay *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__gMonth*SoapDeSerializer::
getAttributeAsGMonth (const AxisChar * pName, const AxisChar * pNamespace)
{
    GMonth simpleType;
    return (xsd__gMonth *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__gMonthDay*SoapDeSerializer::
getAttributeAsGMonthDay (const AxisChar * pName, const AxisChar * pNamespace)
{
    GMonthDay simpleType;
    return (xsd__gMonthDay *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__gYear*SoapDeSerializer::
getAttributeAsGYear (const AxisChar * pName, const AxisChar * pNamespace)
{
    GYear simpleType;
    return (xsd__gYear *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__gYearMonth*SoapDeSerializer::
getAttributeAsGYearMonth (const AxisChar * pName, const AxisChar * pNamespace)
{
    GYearMonth simpleType;
    return (xsd__gYearMonth *)getAttribute(pName, pNamespace, &simpleType);
}

xsd__duration *SoapDeSerializer::
getAttributeAsDuration (const AxisChar * pName, const AxisChar * pNamespace)
{
    Duration simpleType;
    return (xsd__duration *)getAttribute(pName, pNamespace, &simpleType);
}

bool SoapDeSerializer::
isNilValue()
{
    logEntryEngine("SoapDeSerializer::isNilValue")

    bool isNillResult = false;    

    // Go through the attributes looking for nil.  We consider
    // "true" or "1" to be equivalent.
    for (int i = 0; m_pNode->m_pchAttributes[i]; i += 3)
    {
        string sLocalName = m_pNode->m_pchAttributes[i];
        string sValue = m_pNode->m_pchAttributes[i + 2];

        if (strcmp("nil", sLocalName.c_str()) == 0 &&
            (strcmp("true", sValue.c_str()) == 0 || strcmp( "1", sValue.c_str()) == 0))
        {
            isNillResult = true;
            break;
        }
    }

    logExitWithBoolean(isNillResult)
    
    return isNillResult;
}

void SoapDeSerializer::
processFaultDetail(IAnySimpleType * pSimpleType, const AxisChar* elementValue)
{
    logEntryEngine("SoapDeSerializer::processFaultDetail")

    bool isWhiteSpace = true;
    
    int len = elementValue ? strlen(elementValue) : 0;
    
    // See if detail element character data is whitespace
    for (int i=0; i<len; ++i)
        if (!(*elementValue == '\r' || *elementValue == '\n' 
                || *elementValue == '\t' || *elementValue == ' '))
        {
            isWhiteSpace = false;
            break;
        }
    
    // If it is whitespace, peek to see if next element is the start of
    // a new element, in which case the fault detail is complex.  Peek()
    // return null string if end-element tag is encountered.
    char *workingString = (char *)elementValue;
    if (isWhiteSpace)
    {
        // Since we will be doing a peek, elementValue will no longer
        // be valid, so if we will deserialize null string if we need to.
        workingString = "";
        
        // if end tag not found, must be complex detail - fault handling code
        // will know what to do when we return with no deserialization
        const char* nextName = m_pParser->peek();
        if (nextName[0] != 0x00)
        {
            m_pNode = NULL; // node consumed
            
            logExit()
            
            return;
        }
    }
    
    // If here, detail is simple character data, deserialize simple string
    pSimpleType->deserialize(workingString);
    skipNode();        
    
    logExit()
    
    return;
}

void SoapDeSerializer::
getElement (const AxisChar * pName, const AxisChar * pNamespace,
            IAnySimpleType * pSimpleType,
            bool isArrayElement)
{  
    logEntryEngine("SoapDeSerializer::getElement")

    if (AXIS_SUCCESS != m_nStatus)
    {
        logExit()
        
        return;
    }
        
	if ((RPC_ENCODED != m_nStyle) && (m_pNode == NULL))
	{
		const char*name = peekNextElementName();
		if (0 != strcmp (pName, name))
		{
            logExit()

            return; 
		}
	}
    
    if (AXIS_FAIL == getNextNode(RPC_ENCODED != m_nStyle))
    {
        logExit()
        
        return;
    }

    bool    bNillFound = false;
    if (0 == strcmp (pName, m_pNode->m_pchNameOrValue))
        bNillFound = isNilValue();

    if (RPC_ENCODED == m_nStyle)
    {
        // it is an error if type is different if the type exists
        bool foundType;
        if (!bNillFound && !isArrayElement 
                && (pSimpleType->getType() != getXSDType(m_pNode, foundType)) && foundType)
            m_nStatus = AXIS_FAIL;
    }
    else if (0 != strcmp (pName, m_pNode->m_pchNameOrValue))
    {
        logExit()
        
        return;
    }
    
    if (AXIS_FAIL == m_nStatus)
    {
        logExit()
        
        return;
    }
    
    // get next element, character mode 
    if (AXIS_FAIL == getNextNode(false, true))
    {
        logExit()
        
        return;
    }
      
    if (CHARACTER_ELEMENT == m_pNode->m_type)
    {
        const AxisChar* elementValue = m_pNode->m_pchNameOrValue;
                            
        // Code for fault finding.  As added protection against false findings, 
        // the namespace has been set to an invalid value of a single space character.
        if (pNamespace != NULL && *pNamespace == ' ')
            processFaultDetail(pSimpleType, elementValue);
        else
        {
            pSimpleType->deserialize(elementValue);
            skipNode();
        }
    }
    else if (END_ELEMENT == m_pNode->m_type)
    {
        // xsi:nil="true" OR empty tag case <tag/>
        pSimpleType->deserialize(bNillFound ? NULL : "");
        m_pNode = NULL;
    }

    logExit()
    
    return;
}

/*
 * Deserializing Elements as values directly. 
 */
xsd__boolean *SoapDeSerializer::
getElementAsBoolean (const AxisChar * pName, const AxisChar * pNamespace)
{
    Boolean simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getBoolean();
}

xsd__int *SoapDeSerializer::
getElementAsInt (const AxisChar * pName, const AxisChar * pNamespace)
{
    Int simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getInt();
}


xsd__unsignedInt *SoapDeSerializer::
getElementAsUnsignedInt (const AxisChar * pName, const AxisChar * pNamespace)
{
    UnsignedInt simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getUnsignedInt();
}

xsd__short *SoapDeSerializer::
getElementAsShort (const AxisChar * pName, const AxisChar * pNamespace)
{
    Short simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getShort();
}

xsd__unsignedShort *SoapDeSerializer::
getElementAsUnsignedShort (const AxisChar * pName, const AxisChar * pNamespace)
{
    UnsignedShort simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getUnsignedShort();
}

xsd__byte *SoapDeSerializer::
getElementAsByte (const AxisChar * pName, const AxisChar * pNamespace)
{
    Byte simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getByte();
}

xsd__unsignedByte *SoapDeSerializer::
getElementAsUnsignedByte (const AxisChar * pName, const AxisChar * pNamespace)
{
    UnsignedByte simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getUnsignedByte();
}

xsd__long *SoapDeSerializer::
getElementAsLong (const AxisChar * pName, const AxisChar * pNamespace)
{
    Long simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getLong();
}

xsd__integer *SoapDeSerializer::
getElementAsInteger (const AxisChar * pName, const AxisChar * pNamespace)
{
    Integer simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getInteger();
}

xsd__unsignedLong *SoapDeSerializer::
getElementAsUnsignedLong (const AxisChar * pName, const AxisChar * pNamespace)
{
    UnsignedLong simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getUnsignedLong();
}

xsd__float *SoapDeSerializer::
getElementAsFloat (const AxisChar * pName, const AxisChar * pNamespace)
{
    Float simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getFloat();
}

xsd__double *SoapDeSerializer::
getElementAsDouble (const AxisChar * pName, const AxisChar * pNamespace)
{
    Double simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getDouble();
}

xsd__decimal *SoapDeSerializer::
getElementAsDecimal (const AxisChar * pName, const AxisChar * pNamespace)
{
    Decimal simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getDecimal();
}

xsd__string SoapDeSerializer::
getElementAsString (const AxisChar * pName, const AxisChar * pNamespace)
{
    String simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getString();
}

xsd__anyURI SoapDeSerializer::
getElementAsAnyURI (const AxisChar * pName, const AxisChar * pNamespace)
{
    AnyURI simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getAnyURI();
}

xsd__QName SoapDeSerializer::
getElementAsQName (const AxisChar * pName, const AxisChar * pNamespace)
{
    XSD_QName simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getQName();
}

xsd__hexBinary *SoapDeSerializer::
getElementAsHexBinary (const AxisChar * pName, const AxisChar * pNamespace)
{
    HexBinary simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getHexBinary();
}

xsd__base64Binary *SoapDeSerializer::
getElementAsBase64Binary (const AxisChar * pName, const AxisChar * pNamespace)
{
    Base64Binary simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getBase64Binary();
}

xsd__dateTime *SoapDeSerializer::
getElementAsDateTime (const AxisChar * pName, const AxisChar * pNamespace)
{
    DateTime simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getDateTime();
}

xsd__date *SoapDeSerializer::
getElementAsDate (const AxisChar * pName, const AxisChar * pNamespace)
{
    Date simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getDate();
}

xsd__time *SoapDeSerializer::
getElementAsTime (const AxisChar * pName, const AxisChar * pNamespace)
{
    Time simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getTime();
}

xsd__duration *SoapDeSerializer::
getElementAsDuration (const AxisChar * pName, const AxisChar * pNamespace)
{
    Duration simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getDuration();
}

xsd__gYearMonth *SoapDeSerializer::
getElementAsGYearMonth (const AxisChar * pName, const AxisChar * pNamespace)
{
    GYearMonth simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getGYearMonth();
}

xsd__gYear *SoapDeSerializer::
getElementAsGYear (const AxisChar * pName, const AxisChar * pNamespace)
{
    GYear simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getGYear();
}

xsd__gMonthDay *SoapDeSerializer::
getElementAsGMonthDay (const AxisChar * pName, const AxisChar * pNamespace)
{
    GMonthDay simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getGMonthDay();
}

xsd__gDay *SoapDeSerializer::
getElementAsGDay (const AxisChar * pName, const AxisChar * pNamespace)
{
    GDay simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getGDay();
}

xsd__gMonth *SoapDeSerializer::
getElementAsGMonth (const AxisChar * pName, const AxisChar * pNamespace)
{
    GMonth simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getGMonth();
}

xsd__nonPositiveInteger *SoapDeSerializer::
getElementAsNonPositiveInteger (const AxisChar * pName, const AxisChar * pNamespace)
{
    NonPositiveInteger simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getNonPositiveInteger();
}

xsd__negativeInteger *SoapDeSerializer::
getElementAsNegativeInteger (const AxisChar * pName, const AxisChar * pNamespace)
{
    NegativeInteger simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getNegativeInteger();
}

xsd__nonNegativeInteger *SoapDeSerializer::
getElementAsNonNegativeInteger (const AxisChar * pName, const AxisChar * pNamespace)
{
    NonNegativeInteger simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getNonNegativeInteger();
}

xsd__positiveInteger *SoapDeSerializer::
getElementAsPositiveInteger (const AxisChar * pName, const AxisChar * pNamespace)
{
    PositiveInteger simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getPositiveInteger();
}

xsd__normalizedString SoapDeSerializer::
getElementAsNormalizedString (const AxisChar * pName, const AxisChar * pNamespace)
{
    NormalizedString simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getNormalizedString();
}

xsd__token SoapDeSerializer::
getElementAsToken (const AxisChar * pName, const AxisChar * pNamespace)
{
    Token simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getToken();
}

xsd__language SoapDeSerializer::
getElementAsLanguage (const AxisChar * pName, const AxisChar * pNamespace)
{
    Language simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getLanguage();
}

xsd__Name SoapDeSerializer::
getElementAsName (const AxisChar * pName, const AxisChar * pNamespace)
{
    Name simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getName();
}

xsd__NCName SoapDeSerializer::
getElementAsNCName (const AxisChar * pName, const AxisChar * pNamespace)
{
    NCName simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getNCName();
}

xsd__ID SoapDeSerializer::
getElementAsID (const AxisChar * pName, const AxisChar * pNamespace)
{
    ID simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getID();
}

xsd__IDREF SoapDeSerializer::
getElementAsIDREF (const AxisChar * pName, const AxisChar * pNamespace)
{
    IDREF simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getIDREF();
}

xsd__IDREFS SoapDeSerializer::
getElementAsIDREFS (const AxisChar * pName, const AxisChar * pNamespace)
{
    IDREFS simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getIDREFS();
}

xsd__ENTITY SoapDeSerializer::
getElementAsENTITY (const AxisChar * pName, const AxisChar * pNamespace)
{
    ENTITY simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getENTITY();
}

xsd__ENTITIES SoapDeSerializer::
getElementAsENTITIES (const AxisChar * pName, const AxisChar * pNamespace)
{
    ENTITIES simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getENTITIES();
}

xsd__NMTOKEN SoapDeSerializer::
getElementAsNMTOKEN (const AxisChar * pName, const AxisChar * pNamespace)
{
    NMTOKEN simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getNMTOKEN();
}

xsd__NMTOKENS SoapDeSerializer::
getElementAsNMTOKENS (const AxisChar * pName, const AxisChar * pNamespace)
{
    NMTOKENS simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getNMTOKENS();
}

xsd__NOTATION SoapDeSerializer::
getElementAsNOTATION (const AxisChar * pName, const AxisChar * pNamespace)
{
    NOTATION simpleType;
    getElement(pName, pNamespace, &simpleType);
    return simpleType.getNOTATION();
}

xsd__anyType SoapDeSerializer::
getElementAsAnyType(const AxisChar* pName, const AxisChar* pNamespace)
{
    xsd__anyType ret = NULL;
    
    if (AXIS_SUCCESS != m_nStatus)
        return ret;
        
    AnyType *any = getAnyObject(pName, pNamespace);
    if (NULL != any)
    {
        if (any->_size != 0)
        {
            ret = any->_array[0];
            any->_array[0] = NULL;
            delete [] any->_array;
        }
        delete any;
    }
    
    return ret;
}

xsd__string SoapDeSerializer::
getFaultAsXMLString()
{
    if (AXIS_SUCCESS != m_nStatus || RPC_ENCODED == m_nStyle)
        return NULL;
        
    AnyType *any = getAnyObject();
    if (any == NULL)
        return (xsd__string)NULL;

    int len = 1, i; // Add 1 for the null terminator
    for (i=0; i<any->_size; i++)
        if (any->_array[i])
            len += strlen(any->_array[i]);

    xsd__string ret = new char[len];
    memset(ret,0,len);
    for (i=0; i<any->_size; i++) 
        if (any->_array[i]) 
        {
            strcat(ret,any->_array[i]);
            delete [] any->_array[i];
        }
    delete [] any->_array;
    delete any;
    return ret;
}

/*
 * This method checks the attribute list of pElement node for the xsi:type 
 * attribute. If it is found then finds what the type is. Otherwise returns 
 * XSD_UNKNOWN.
 */
XSDTYPE SoapDeSerializer::
getXSDType (const AnyElement * pElement, bool & foundType)
{
    foundType = false;
    
    XSDTYPE type = XSD_UNKNOWN;
    
    /* first check whether this is a start element node */
    if (START_ELEMENT == pElement->m_type)
    {
        for (int i = 0; pElement->m_pchAttributes[i]; i += 3)
        {
            if (URI_XSI == URIMapping::getURI (pElement->m_pchAttributes[i + 1]))
            {
                ::QName qn;
                
                qn.splitQNameString (pElement->m_pchAttributes[i + 2], ':');
                const char * pNS = m_pParser->getNS4Prefix (qn.uri);
                if (pNS)
                {
                    if (URI_XSD == URIMapping::getURI (pNS) || URI_ENC == URIMapping::getURI (pNS))
                        type = TypeMapping::map (qn.localname);
                }
                qn.mergeQNameString (':');
                foundType = true;
                break;
            }
        }
    }

    return type;
}

/*
 * Used by the Axis Engine to get any left header blocks in the deserializer 
 * even after the completion of message path. Then those headers will be added
 * to the serializer because they are probably headers targetted to nex soap 
 * processors.
 */
HeaderBlock * SoapDeSerializer::
getHeaderBlock ()
{
    logEntryEngine("SoapDeSerializer::getHeaderBlock")

    HeaderBlock *returnValue = NULL;
    
    if (m_pHeader)
        returnValue = (HeaderBlock *) m_pHeader->getHeaderBlock (true);
    
    logExitWithPointer(returnValue)
    
    return returnValue;
}

/*
 * Used probably by a handler to add a header block to the Deserializer.
 * Probably to be used by a subsequent handler in the request message path
 */
int AXISCALL SoapDeSerializer::
addHeaderBlock (IHeaderBlock * pBlk)
{
    logEntryEngine("SoapDeSerializer::addHeaderBlock")

    if (!m_pHeader)
        m_pHeader = new SoapHeader ();
    m_pHeader->addHeaderBlock ((HeaderBlock *) pBlk);
    
    logExitWithReturnCode(AXIS_SUCCESS)

    return AXIS_SUCCESS;
}

xsd__hexBinary SoapDeSerializer::
getBodyAsHexBinary ()
{
    /* TODO */
    getNextNode();
    
    // skip the BODY element declaration
    if ((START_ELEMENT == m_pNode->m_type)
            && (0 == strcmp (m_pNode->m_pchNameOrValue, 
                             SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY])))
        getNextNode();

    string bodyContent = "";
    
    if (m_pNode)
    {
        while (!((END_ELEMENT == m_pNode->m_type) &&
               (0 == strcmp (m_pNode->m_pchNameOrValue,
                             SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY]))))
            bodyContent += AnyElemntUtils::toString(m_pNode);
    }
        
    xsd__hexBinary value;
    xsd__int size = bodyContent.length() / 2;
    xsd__unsignedByte * pTemp = new xsd__unsignedByte[size + 1];
    Hex_Decode (pTemp, bodyContent.c_str());
    pTemp[size] = 0; // Null terminate so it could be used as a string
    value.set(pTemp, size);
    delete [] pTemp;

    return value;     
}

xsd__base64Binary SoapDeSerializer::
getBodyAsBase64Binary ()
{
    /* TODO */
    getNextNode();
    
    // skip the BODY element declaration
    if ((START_ELEMENT == m_pNode->m_type)
            && (0 == strcmp (m_pNode->m_pchNameOrValue, 
                             SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY])))
        getNextNode();

    string bodyContent = "";
    
    if (m_pNode)
    {
        while (!((END_ELEMENT == m_pNode->m_type) &&
               (0 == strcmp (m_pNode->m_pchNameOrValue,
                             SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY]))))
            bodyContent += AnyElemntUtils::toString(m_pNode);
    }

    xsd__base64Binary value;
    xsd__int size = apr_base64_decode_len (bodyContent.c_str());
    xsd__unsignedByte * pTemp = new xsd__unsignedByte[size + 1];
    size = apr_base64_decode_binary (pTemp, bodyContent.c_str());
    pTemp[size] = 0; // Null terminate so it could used as a string
    value.set(pTemp, size);
    delete [] pTemp;
    return value;
}

AxisChar *SoapDeSerializer::
getBodyAsChar ()
{
    if (AXIS_FAIL == getNextNode())
        return NULL;

    // skip the BODY element declaration 
    if ((START_ELEMENT == m_pNode->m_type)
            && (0 == strcmp (m_pNode->m_pchNameOrValue,
                             SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY])))
    {
        if (AXIS_FAIL == getNextNode())
            return NULL;
    }
    
    pBodyContent = new AxisChar[1000];
    pBodyContent[0] = '\0';

    while (!((END_ELEMENT == m_pNode->m_type) &&
           (0 == strcmp (m_pNode->m_pchNameOrValue,
                         SoapKeywordMapping::map (m_nSoapVersion).pchWords[SKW_BODY]))))
        strcat (pBodyContent, (AnyElemntUtils::toString (m_pNode)).c_str ());

    return pBodyContent;
}

int SoapDeSerializer::
setNewSoapBody (AxisChar * pNewSoapBody)
{
    DeSerializerMemBufInputStream stream (pNewSoapBody);
    return m_pParser->setInputStream (&stream);
}

bool SoapDeSerializer::
isAnyMustUnderstandHeadersLeft ()
{
    /* TODO */
    return false;
}

int SoapDeSerializer::
flushInputStream ()
{
    logEntryEngine("SoapDeSerializer::flushInputStream")

    int iStatus = AXIS_FAIL;
    
    if (m_pInputStream)
    {
        int nChars = 100;
        char pBuffer[100];
        
        while (TRANSPORT_IN_PROGRESS == m_pInputStream->getBytes (pBuffer, &nChars));
        iStatus = AXIS_SUCCESS;
    }
    
    logExitWithReturnCode(iStatus)

    return iStatus;
}

AnyType * SoapDeSerializer::
getAnyObject ()
{
    return getAnyObject(NULL, NULL);
}


AnyType * SoapDeSerializer::
getAnyObject (const AxisChar* pName, const AxisChar* pNamespace)
{
    logEntryEngine("SoapDeSerializer::getAnyObject")

    // If pname is passed, then we need to move the parser pointer for RPC.
    if ((pName != NULL && RPC_ENCODED == m_nStyle) || (m_pNode == NULL))
    {
        getNextNode(false, false);
        if (m_pNode == NULL)
        {
            logExitWithPointer(NULL)

            return (AnyType *)NULL;
        }
    }

    int tagCount = 0;
    int lstSize = 0;
    bool bContinue = true;
    bool bElementFound = false;
    AxisString xmlStr = "";
    AxisString nsDecls = "";

    if (m_pNode)
    {
        // If this is an end-element node, simply return, there is no element to parse. Note
        // we do not consume the node.
        if (END_ELEMENT == m_pNode->m_type)
        {
            logExitWithPointer(NULL)

            return (AnyType *)NULL;
        }

        // There may have been namespace declarations that were previously processed....get it from
        // the node and reset the node variable.
        nsDecls = ((AnyElement*)m_pNode)->m_strXMLNSDeclsForAnyObject.c_str();
        ((AnyElement*)m_pNode)->m_strXMLNSDeclsForAnyObject.clear();
    }

    stack <AxisString> nsPrefixStack;

    AxisString inValue = "";
    AxisString outValue = "";

    // Loop and get an XML element node and its sub-elements.
    // Note the a schema element will not be counted as an element but will be included as part
    // of the data returned.
    while (m_pNode && ((END_ELEMENT != m_pNode->m_type) || (tagCount > 0) || bContinue))
    {
        // Root element needs to be what is expected for doc/literal.
        if (pName != NULL
                && RPC_ENCODED != m_nStyle
                && START_ELEMENT == m_pNode->m_type)
        {
            if (0 != strcmp (pName, m_pNode->m_pchNameOrValue))
            {
                // Need to save namespace string just in case it is needed later.
                ((AnyElement*)m_pNode)->m_strXMLNSDeclsForAnyObject = nsDecls.c_str();

                logExitWithPointer(NULL)

                return (AnyType *)NULL;
            }

            // We do not need to do the check anymore
            pName = NULL;
        }

        // Continue if processing start prefix as we haven't yet found the true start of the tag
        bContinue = false;
        if (START_PREFIX == m_pNode->m_type)
            bContinue = true;

        // if empty element we need to do a parser get to consume the end-element node.
        // Note that start/end elements are not included in tagCount processing since the node
        // is processed completely on first pass since it contains no sub-elements.
        if (START_END_ELEMENT == m_pNode->m_type2)
        {
            if (END_ELEMENT == m_pNode->m_type)
            {
                m_pNode = m_pParser->anyNext ();
                continue;
            }
        }
        else
        {
            // Increment counter if entering new tag, Decrement counter if exiting tag
            if (START_ELEMENT == m_pNode->m_type)
                tagCount++;
            else if (END_ELEMENT == m_pNode->m_type)
                tagCount--;
        }

        if (START_PREFIX == m_pNode->m_type)
        {
            nsDecls += " xmlns";
            if (m_pNode->m_pchNameOrValue && (*(m_pNode->m_pchNameOrValue) != 0x00))
            {
                nsDecls += ":";
                nsDecls += m_pNode->m_pchNameOrValue;
            }
            nsDecls += "=";
            nsDecls += PLATFORM_DOUBLE_QUOTE_S;
            nsDecls += m_pNode->m_pchNamespace;
            nsDecls += PLATFORM_DOUBLE_QUOTE_S;
        }
        else if (CHARACTER_ELEMENT != m_pNode->m_type)
        {
            bElementFound = true;
            serializeTag (xmlStr, m_pNode, nsDecls, nsPrefixStack);
            nsDecls = "";
        }
        else
        {
            inValue = m_pNode->m_pchNameOrValue;
            IAnySimpleType::replaceReservedCharacters(inValue, outValue);
            xmlStr += outValue;
        }

        // If element obtained...break out. Otherwise, get next node.
        if (bElementFound && !bContinue && tagCount == 0 && (!xmlStr.empty ()))
        {
            // If the anyType element is empty element, we need to consume END_ELEMENT.
            if (START_END_ELEMENT == m_pNode->m_type2 && START_ELEMENT == m_pNode->m_type)
                m_pNode = m_pParser->anyNext ();

            m_pNode = NULL;
        }
        else
            m_pNode = m_pParser->anyNext ();
    }

    // Generate the axis type where we store anyType XML objects.
    AnyType *pAny = new AnyType ();
    pAny->_array = 0;
    pAny->_size = 0;

    if (!xmlStr.empty ())
    {
        pAny->_array = new char *[1];

        const char *s = xmlStr.c_str ();
        logDebugArg1("\nAnyType array element\n%s\n", s)

        pAny->_array[0] = new char[xmlStr.size() + 1];
        strcpy (pAny->_array[0], s);

        pAny->_size  = 1;
    }

    logExitWithPointer(pAny)

    return pAny;
}

void SoapDeSerializer::
serializeTag (AxisString & xmlStr, 
              const AnyElement * node,
              AxisString & nsDecls,
              std::stack<AxisString> & nsPrefixStack)
{
    const XML_Ch *pchPrefix = 0;

    AxisString nsPrefix = "";

    if (START_ELEMENT == node->m_type)
    {
        xmlStr += "<";

        if (node->m_pchNamespace && (*(node->m_pchNamespace) != 0x00))
        {
            pchPrefix = m_pParser->getPrefix4NS (node->m_pchNamespace);

            if (pchPrefix && *pchPrefix != 0x00)
            {
                nsPrefix = pchPrefix;

                xmlStr += pchPrefix;
                xmlStr += ":";
            }
        }

        // We do not need to save namespace prefix if start/end element.
        if (START_END_ELEMENT != node->m_type2)
            nsPrefixStack.push(nsPrefix);
    
        xmlStr += node->m_pchNameOrValue;

        if (!nsDecls.empty ())
            xmlStr += nsDecls.c_str ();

        if (node->m_pchAttributes)
        {
            int j;
    
            /* structure of the m_pchAttributes[] array is,
             * sequence of (local_name, namespace_uri, value)
             */
    
            for (j = 0; j < 300; j += 3)    /* MAX_NO_OF_ATTRIBUTES = 100 */
            {
                if (node->m_pchAttributes[j])
                {
                    if (node->m_pchAttributes[j + 1])
                        pchPrefix = m_pParser->getPrefix4NS (node->m_pchAttributes[j + 1]);
                    else
                        pchPrefix = NULL;
                       
                    xmlStr += " ";

                    if (pchPrefix && (*pchPrefix != 0x00))
                    {
                        xmlStr += pchPrefix;
                        xmlStr += ":";
                    }
                    
                    xmlStr += node->m_pchAttributes[j];
                    xmlStr += "=";
                    xmlStr += PLATFORM_DOUBLE_QUOTE_S;
                    xmlStr += node->m_pchAttributes[j + 2];
                    xmlStr += PLATFORM_DOUBLE_QUOTE_S;
                }
                else
                    break;
            }
        }

        if (START_END_ELEMENT == node->m_type2)
            xmlStr += " />";
        else
            xmlStr += ">";
    }
    else if (END_ELEMENT == node->m_type)
    {
        AxisString prefixTag = "";

        if (!nsPrefixStack.empty())
        {
            nsPrefix = nsPrefixStack.top();
            nsPrefixStack.pop();

            if (!nsPrefix.empty())
            {
                prefixTag += nsPrefix;
                prefixTag += ":";
            }
        }

        xmlStr += "</";
        xmlStr += prefixTag;
        xmlStr += node->m_pchNameOrValue;
        if (START_END_ELEMENT == node->m_type2)
            xmlStr += " />";
        else
            xmlStr += ">";
    }
}

void SoapDeSerializer::
getChardataAs (void **pValue, XSDTYPE type)
{  
    logEntryEngine("SoapDeSerializer::getChardataAs")

    if (pValue && AXIS_FAIL != getNextNode(true, true))
    {
        *pValue = NULL;
        if (CHARACTER_ELEMENT == m_pNode->m_type)
        {
            IAnySimpleType* pSimpleType = AxisUtils::createSimpleTypeObject(type);
            pSimpleType->deserialize(m_pNode->m_pchNameOrValue);
            *pValue = pSimpleType->getValue();
            delete pSimpleType;
        }
        else if (END_ELEMENT == m_pNode->m_type)
        {
            m_doNotSkip = true;
            m_pNode = NULL;
        }
    }
    
    logExit()
}

/* This function is never called. */
AXIS_TRANSPORT_STATUS SoapDeSerializer::
DeSerializerMemBufInputStream::
sendBytes (const char *pcSendBuffer, const void *pBufferid)
{
    return TRANSPORT_FINISHED;
}

AXIS_TRANSPORT_STATUS SoapDeSerializer::
DeSerializerMemBufInputStream::
getBytes (char *pcBuffer, int *piRetSize)
{
    logEntryEngine("SoapDeSerializer::DeSerializerMemBufInputStream::getBytes")

    if (!m_pcDeSeriaMemBuffer)
    {
        logExitWithMessage("Returned return code of TRANSPORT_FAILED")
        
        return TRANSPORT_FAILED;
    }
        
    int nBufLen = strlen (m_pcDeSeriaMemBuffer);
    if (0 == nBufLen)
    {
        logExitWithMessage("Returned return code of TRANSPORT_FINISHED")

        return TRANSPORT_FINISHED;
    }
        
    nBufLen = ((*piRetSize - 1) < nBufLen) ? (*piRetSize - 1) : nBufLen;
    strncpy (pcBuffer, m_pcDeSeriaMemBuffer, nBufLen);
    pcBuffer[nBufLen] = 0;
    m_pcDeSeriaMemBuffer += nBufLen;
    
    logExitWithMessage("Returned return code of TRANSPORT_IN_PROGRESS")

    return TRANSPORT_IN_PROGRESS;
}

ISoapAttachment* SoapDeSerializer::
getAttachment(const char* pcAttachmentid)    
{            
    return m_pInputStream->getAttachment(pcAttachmentid);         
}

ISoapAttachment** SoapDeSerializer::
getAllAttachments(int *pAttchArraySize)
{
    return m_pInputStream->getAllAttachments(pAttchArraySize);
}

const char* SoapDeSerializer::
getMethodNameToInvoke()
{
    return m_strMethodNameToInvoke.c_str();
}

void SoapDeSerializer::
setMethodNameToInvoke(const char* methodName)
{
    logEntryEngine("SoapDeSerializer::setMethodNameToInvoke")

    m_strMethodNameToInvoke = methodName;
    
    logExit()
}

AXIS_CPP_NAMESPACE_END
