/*
 * 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.
 */

/**
*  This file contains code to build the DOM tree. It registers a document
*  handler with the scanner. In these handler methods, appropriate DOM nodes
*  are created and added to the DOM tree.
*
* $Id: AbstractDOMParser.cpp 568078 2007-08-21 11:43:25Z amassari $
*
*/



// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/parsers/AbstractDOMParser.hpp>
#include <xercesc/internal/XMLScannerResolver.hpp>
#include <xercesc/internal/ElemStack.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/framework/XMLNotationDecl.hpp>
#include <xercesc/framework/XMLValidator.hpp>
#include <xercesc/framework/psvi/PSVIElement.hpp>
#include <xercesc/framework/psvi/PSVIAttribute.hpp>
#include <xercesc/framework/psvi/PSVIAttributeList.hpp>
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
#include <xercesc/util/IOException.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationRegistry.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include <xercesc/dom/impl/DOMAttrImpl.hpp>
#include <xercesc/dom/impl/DOMTypeInfoImpl.hpp>
#include <xercesc/dom/DOMCDATASection.hpp>
#include <xercesc/dom/DOMComment.hpp>
#include <xercesc/dom/impl/DOMTextImpl.hpp>
#include <xercesc/dom/impl/DOMDocumentImpl.hpp>
#include <xercesc/dom/impl/DOMDocumentTypeImpl.hpp>
#include <xercesc/dom/DOMDocumentType.hpp>
#include <xercesc/dom/impl/DOMElementNSImpl.hpp>
#include <xercesc/dom/impl/DOMEntityImpl.hpp>
#include <xercesc/dom/impl/DOMEntityReferenceImpl.hpp>
#include <xercesc/dom/impl/DOMNotationImpl.hpp>
#include <xercesc/dom/DOMNamedNodeMap.hpp>
#include <xercesc/dom/DOMProcessingInstruction.hpp>
#include <xercesc/dom/impl/DOMProcessingInstructionImpl.hpp>
#include <xercesc/dom/impl/DOMNodeIDMap.hpp>
#include <xercesc/dom/impl/DOMCasts.hpp>
#include <xercesc/validators/common/ContentSpecNode.hpp>
#include <xercesc/validators/common/GrammarResolver.hpp>
#include <xercesc/validators/schema/SchemaSymbols.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>

XERCES_CPP_NAMESPACE_BEGIN


// ---------------------------------------------------------------------------
//  AbstractDOMParser: Constructors and Destructor
// ---------------------------------------------------------------------------


typedef JanitorMemFunCall<AbstractDOMParser>    CleanupType;
typedef JanitorMemFunCall<AbstractDOMParser>    ResetInProgressType;


AbstractDOMParser::AbstractDOMParser( XMLValidator* const   valToAdopt
                                    , MemoryManager* const  manager
                                    , XMLGrammarPool* const gramPool) :

  fCreateEntityReferenceNodes(true)
, fIncludeIgnorableWhitespace(true)
, fWithinElement(false)
, fParseInProgress(false)
, fCreateCommentNodes(true)
, fDocumentAdoptedByUser(false)
, fCreateSchemaInfo(false)
, fScanner(0)
, fImplementationFeatures(0)
, fCurrentParent(0)
, fCurrentNode(0)
, fCurrentEntity(0)
, fDocument(0)
, fNodeStack(0)
, fDocumentType(0)
, fDocumentVector(0)
, fGrammarResolver(0)
, fURIStringPool(0)
, fValidator(valToAdopt)
, fMemoryManager(manager)
, fGrammarPool(gramPool)
, fBufMgr(manager)
, fInternalSubset(fBufMgr.bidOnBuffer())
, fPSVIHandler(0)
{
    CleanupType cleanup(this, &AbstractDOMParser::cleanUp);

    try
    {
        initialize();
    }
    catch(const OutOfMemoryException&)
    {
        // Don't cleanup when out of memory, since executing the
        // code can cause problems.
        cleanup.release();

        throw;
    }

    cleanup.release();
}


AbstractDOMParser::~AbstractDOMParser()
{
    cleanUp();
}

// ---------------------------------------------------------------------------
//  AbstractDOMParser: Initialize/CleanUp methods
// ---------------------------------------------------------------------------
void AbstractDOMParser::initialize()
{
    //  Create grammar resolver and string pool to pass to the scanner
    fGrammarResolver = new (fMemoryManager) GrammarResolver(fGrammarPool, fMemoryManager);
    fURIStringPool = fGrammarResolver->getStringPool();

    //  Create a scanner and tell it what validator to use. Then set us
    //  as the document event handler so we can fill the DOM document.
    fScanner = XMLScannerResolver::getDefaultScanner(fValidator, fGrammarResolver, fMemoryManager);
    fScanner->setDocHandler(this);
    fScanner->setDocTypeHandler(this);
    fScanner->setURIStringPool(fURIStringPool);

    fNodeStack = new (fMemoryManager) ValueStackOf<DOMNode*>(64, fMemoryManager);
    this->reset();
}

void AbstractDOMParser::cleanUp()
{
    if (fDocumentVector)
        delete fDocumentVector;

    if (!fDocumentAdoptedByUser && fDocument)
        fDocument->release();

    delete fNodeStack;
    delete fScanner;
    delete fGrammarResolver;
    // grammar pool *always* owns this
    //delete fURIStringPool;
    fMemoryManager->deallocate(fImplementationFeatures);

    if (fValidator)
        delete fValidator;
}

// ---------------------------------------------------------------------------
//  AbstractDOMParser: Utilities
// ---------------------------------------------------------------------------
void AbstractDOMParser::reset()
{
    // if fDocument exists already, store the old pointer in the vector for deletion later
    if (fDocument && !fDocumentAdoptedByUser) {
        if (!fDocumentVector) {
            // allocate the vector if not exists yet
            fDocumentVector  = new (fMemoryManager) RefVectorOf<DOMDocumentImpl>(10, true, fMemoryManager) ;
        }
        fDocumentVector->addElement(fDocument);
    }

    fDocument = 0;
    resetDocType();
    fCurrentParent   = 0;
    fCurrentNode     = 0;
    fCurrentEntity   = 0;
    fParseInProgress = false;
    fWithinElement   = false;
    fDocumentAdoptedByUser = false;
    fNodeStack->removeAllElements();
    fInternalSubset.reset();
}


void AbstractDOMParser::resetInProgress()
{
    fParseInProgress = false;
}


void AbstractDOMParser::resetPool()
{
    //  We cannot enter here while a regular parse is in progress.
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    if (fDocumentVector)
        fDocumentVector->removeAllElements();

    if (!fDocumentAdoptedByUser && fDocument)
        fDocument->release();

    fDocument = 0;
}

bool AbstractDOMParser::isDocumentAdopted() const
{
    return fDocumentAdoptedByUser;
}

DOMDocument* AbstractDOMParser::adoptDocument()
{
    fDocumentAdoptedByUser = true;
    return fDocument;
}


// ---------------------------------------------------------------------------
//  AbstractDOMParser: Getter methods
// ---------------------------------------------------------------------------
DOMDocument* AbstractDOMParser::getDocument()
{
    return fDocument;
}

const XMLValidator& AbstractDOMParser::getValidator() const
{
    return *fScanner->getValidator();
}

bool AbstractDOMParser::getDoNamespaces() const
{
    return fScanner->getDoNamespaces();
}

bool AbstractDOMParser::getGenerateSyntheticAnnotations() const
{
    return fScanner->getGenerateSyntheticAnnotations();
}

bool AbstractDOMParser::getValidateAnnotations() const
{
    return fScanner->getValidateAnnotations();
}

bool AbstractDOMParser::getExitOnFirstFatalError() const
{
    return fScanner->getExitOnFirstFatal();
}

bool AbstractDOMParser::getValidationConstraintFatal() const
{
    return fScanner->getValidationConstraintFatal();
}

AbstractDOMParser::ValSchemes AbstractDOMParser::getValidationScheme() const
{
    const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();

    if (scheme == XMLScanner::Val_Always)
        return Val_Always;
    else if (scheme == XMLScanner::Val_Never)
        return Val_Never;

    return Val_Auto;
}

bool AbstractDOMParser::getDoSchema() const
{
    return fScanner->getDoSchema();
}

bool AbstractDOMParser::getValidationSchemaFullChecking() const
{
    return fScanner->getValidationSchemaFullChecking();
}

bool AbstractDOMParser::getIdentityConstraintChecking() const
{
    return fScanner->getIdentityConstraintChecking();
}

int AbstractDOMParser::getErrorCount() const
{
    return fScanner->getErrorCount();
}

XMLCh* AbstractDOMParser::getExternalSchemaLocation() const
{
    return fScanner->getExternalSchemaLocation();
}

XMLCh* AbstractDOMParser::getExternalNoNamespaceSchemaLocation() const
{
    return fScanner->getExternalNoNamespaceSchemaLocation();
}

SecurityManager* AbstractDOMParser::getSecurityManager() const
{
    return fScanner->getSecurityManager();
}

bool AbstractDOMParser::getLoadExternalDTD() const
{
    return fScanner->getLoadExternalDTD();
}

bool AbstractDOMParser::getCalculateSrcOfs() const
{
    return fScanner->getCalculateSrcOfs();
}

bool AbstractDOMParser::getStandardUriConformant() const
{
    return fScanner->getStandardUriConformant();
}

bool AbstractDOMParser::getIgnoreAnnotations() const
{
    return fScanner->getIgnoreAnnotations();
}

bool AbstractDOMParser::getDisableDefaultEntityResolution() const
{
    return fScanner->getDisableDefaultEntityResolution();
}

bool AbstractDOMParser::getSkipDTDValidation() const
{
    return fScanner->getSkipDTDValidation();
}

// ---------------------------------------------------------------------------
//  AbstractDOMParser: Setter methods
// ---------------------------------------------------------------------------
void AbstractDOMParser::setPSVIHandler(PSVIHandler* const handler)
{
    fPSVIHandler = handler;
    if (fPSVIHandler) {
        fScanner->setPSVIHandler(this);
    }
    else if(!fCreateSchemaInfo) {
        fScanner->setPSVIHandler(0);        
    }
}


void AbstractDOMParser::setDoNamespaces(const bool newState)
{
    fScanner->setDoNamespaces(newState);
}

void AbstractDOMParser::setGenerateSyntheticAnnotations(const bool newState)
{
    fScanner->setGenerateSyntheticAnnotations(newState);
}

void AbstractDOMParser::setValidateAnnotations(const bool newState)
{
    fScanner->setValidateAnnotations(newState);
}

void AbstractDOMParser::setExitOnFirstFatalError(const bool newState)
{
    fScanner->setExitOnFirstFatal(newState);
}

void AbstractDOMParser::setValidationConstraintFatal(const bool newState)
{
    fScanner->setValidationConstraintFatal(newState);
}

void AbstractDOMParser::setValidationScheme(const ValSchemes newScheme)
{
    if (newScheme == Val_Never)
        fScanner->setValidationScheme(XMLScanner::Val_Never);
    else if (newScheme == Val_Always)
        fScanner->setValidationScheme(XMLScanner::Val_Always);
    else
        fScanner->setValidationScheme(XMLScanner::Val_Auto);
}

void AbstractDOMParser::setDoSchema(const bool newState)
{
    fScanner->setDoSchema(newState);
}

void AbstractDOMParser::setValidationSchemaFullChecking(const bool schemaFullChecking)
{
    fScanner->setValidationSchemaFullChecking(schemaFullChecking);
}

void AbstractDOMParser::setIdentityConstraintChecking(const bool identityConstraintChecking)
{
    fScanner->setIdentityConstraintChecking(identityConstraintChecking);
}

void AbstractDOMParser::setExternalSchemaLocation(const XMLCh* const schemaLocation)
{
    fScanner->setExternalSchemaLocation(schemaLocation);
}
void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const XMLCh* const noNamespaceSchemaLocation)
{
    fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
}

void AbstractDOMParser::setExternalSchemaLocation(const char* const schemaLocation)
{
    fScanner->setExternalSchemaLocation(schemaLocation);
}
void AbstractDOMParser::setExternalNoNamespaceSchemaLocation(const char* const noNamespaceSchemaLocation)
{
    fScanner->setExternalNoNamespaceSchemaLocation(noNamespaceSchemaLocation);
}

void AbstractDOMParser::setSecurityManager(SecurityManager* const securityManager)
{
    // since this could impact various components, don't permit it to change
    // during a parse
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    fScanner->setSecurityManager(securityManager);
}

void AbstractDOMParser::setLoadExternalDTD(const bool newState)
{
    fScanner->setLoadExternalDTD(newState);
}

void AbstractDOMParser::setCalculateSrcOfs(const bool newState)
{
    fScanner->setCalculateSrcOfs(newState);
}

void AbstractDOMParser::setStandardUriConformant(const bool newState)
{
    fScanner->setStandardUriConformant(newState);
}

void AbstractDOMParser::useScanner(const XMLCh* const scannerName)
{
    XMLScanner* tempScanner = XMLScannerResolver::resolveScanner
    (
        scannerName
        , fValidator
        , fGrammarResolver
        , fMemoryManager
    );

    if (tempScanner) {

        tempScanner->setParseSettings(fScanner);
        tempScanner->setURIStringPool(fURIStringPool);
        delete fScanner;
        fScanner = tempScanner;
    }
}

void AbstractDOMParser::setCreateSchemaInfo(const bool create)
{
    fCreateSchemaInfo = create;
    if(fCreateSchemaInfo)
        fScanner->setPSVIHandler(this);
    else if(!fPSVIHandler)
        fScanner->setPSVIHandler(0);
}

void AbstractDOMParser::setIgnoreAnnotations(const bool newValue)
{
    fScanner->setIgnoreAnnotations(newValue);
}

void AbstractDOMParser::setDisableDefaultEntityResolution(const bool newValue)
{
    fScanner->setDisableDefaultEntityResolution(newValue);
}

void AbstractDOMParser::setSkipDTDValidation(const bool newValue)
{
    fScanner->setSkipDTDValidation(newValue);
}

void AbstractDOMParser::setDocument(DOMDocument* toSet)
{
    fDocument = (DOMDocumentImpl *)toSet;
}

// ---------------------------------------------------------------------------
//  AbstractDOMParser: Parsing methods
// ---------------------------------------------------------------------------
void AbstractDOMParser::parse(const InputSource& source)
{
    // Avoid multiple entrance
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    ResetInProgressType     resetInProgress(this, &AbstractDOMParser::resetInProgress);

    try
    {
        fParseInProgress = true;
        fScanner->scanDocument(source);
    }
    catch(const OutOfMemoryException&)
    {
        resetInProgress.release();

        throw;
    }    
}

void AbstractDOMParser::parse(const XMLCh* const systemId)
{
    // Avoid multiple entrance
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    ResetInProgressType     resetInProgress(this, &AbstractDOMParser::resetInProgress);

    try
    {
        fParseInProgress = true;
        fScanner->scanDocument(systemId);
    }
    catch(const OutOfMemoryException&)
    {
        resetInProgress.release();

        throw;
    }    
}

void AbstractDOMParser::parse(const char* const systemId)
{
    // Avoid multiple entrance
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    ResetInProgressType     resetInProgress(this, &AbstractDOMParser::resetInProgress);

    try
    {
        fParseInProgress = true;
        fScanner->scanDocument(systemId);
    }
    catch(const OutOfMemoryException&)
    {
        resetInProgress.release();

        throw;
    }    
}



// ---------------------------------------------------------------------------
//  AbstractDOMParser: Progressive parse methods
// ---------------------------------------------------------------------------
bool AbstractDOMParser::parseFirst( const XMLCh* const    systemId
                                   ,       XMLPScanToken&  toFill)
{
    //
    //  Avoid multiple entrance. We cannot enter here while a regular parse
    //  is in progress.
    //
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    return fScanner->scanFirst(systemId, toFill);
}

bool AbstractDOMParser::parseFirst( const char* const         systemId
                                   ,       XMLPScanToken&      toFill)
{
    //
    //  Avoid multiple entrance. We cannot enter here while a regular parse
    //  is in progress.
    //
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    return fScanner->scanFirst(systemId, toFill);
}

bool AbstractDOMParser::parseFirst( const InputSource& source
                                   ,       XMLPScanToken&  toFill)
{
    //
    //  Avoid multiple entrance. We cannot enter here while a regular parse
    //  is in progress.
    //
    if (fParseInProgress)
        ThrowXMLwithMemMgr(IOException, XMLExcepts::Gen_ParseInProgress, fMemoryManager);

    return fScanner->scanFirst(source, toFill);
}

bool AbstractDOMParser::parseNext(XMLPScanToken& token)
{
    return fScanner->scanNext(token);
}

void AbstractDOMParser::parseReset(XMLPScanToken& token)
{
    // Reset the scanner, and then reset the parser
    fScanner->scanReset(token);
    reset();
}


// ---------------------------------------------------------------------------
//  AbstractDOMParser: Implementation of PSVIHandler interface
// ---------------------------------------------------------------------------
void AbstractDOMParser::handleElementPSVI(const XMLCh* const            localName 
                                        , const XMLCh* const            uri
                                        ,       PSVIElement *           elementInfo)
{
    // associate the info now; if the user wants, she can override what we did
    if(fCreateSchemaInfo)
    {
        DOMTypeInfoImpl* typeInfo=new (getDocument()) DOMTypeInfoImpl();
        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validity, elementInfo->getValidity());
        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validitation_Attempted, elementInfo->getValidationAttempted());
        if(elementInfo->getTypeDefinition())
        {
            typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, elementInfo->getTypeDefinition()->getTypeCategory());
            typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, elementInfo->getTypeDefinition()->getAnonymous());
            typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, 
                fDocument->getPooledString(elementInfo->getTypeDefinition()->getNamespace()));
            typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, 
                fDocument->getPooledString(elementInfo->getTypeDefinition()->getName()));
        }
        else if(elementInfo->getValidity()==PSVIItem::VALIDITY_VALID)
        {
            // if we are valid but we don't have a type validator, we are xs:anyType
            typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::COMPLEX_TYPE);
            typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, false);
            typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
            typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, SchemaSymbols::fgATTVAL_ANYTYPE);
        }
        if(elementInfo->getMemberTypeDefinition())
        {
            typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Anonymous, elementInfo->getMemberTypeDefinition()->getAnonymous());
            typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Namespace, 
                fDocument->getPooledString(elementInfo->getMemberTypeDefinition()->getNamespace()));
            typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Name, 
                fDocument->getPooledString(elementInfo->getMemberTypeDefinition()->getName()));
        }
        if(elementInfo->getElementDeclaration())
            typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Nil, elementInfo->getElementDeclaration()->getNillable());
        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Default, fDocument->getPooledString(elementInfo->getSchemaDefault()));
        typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Normalized_Value, fDocument->getPooledString(elementInfo->getSchemaNormalizedValue()));
        typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Schema_Specified, true);
        ((DOMElementNSImpl*)fCurrentParent)->setTypeInfo(typeInfo);
    }
    if(fPSVIHandler)
        fPSVIHandler->handleElementPSVI(localName, uri, elementInfo);
}

void AbstractDOMParser::handlePartialElementPSVI(const XMLCh* const            localName 
                                               , const XMLCh* const            uri
                                               ,       PSVIElement *           elementInfo)
{
    if(fPSVIHandler)
        fPSVIHandler->handlePartialElementPSVI(localName, uri, elementInfo);
}

void AbstractDOMParser::handleAttributesPSVI( const XMLCh* const            localName 
                                            , const XMLCh* const            uri
                                            ,       PSVIAttributeList *     psviAttributes)
{
    if(fCreateSchemaInfo)
    {
        for (unsigned int index=0; index < psviAttributes->getLength(); index++) {
            XERCES_CPP_NAMESPACE_QUALIFIER PSVIAttribute *attrInfo=psviAttributes->getAttributePSVIAtIndex(index);
            XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* pAttrNode=fCurrentNode->getAttributes()->getNamedItemNS(psviAttributes->getAttributeNamespaceAtIndex(index),
                                                                                                            psviAttributes->getAttributeNameAtIndex(index));
            if(pAttrNode!=NULL)
            {
                DOMTypeInfoImpl* typeInfo=new (getDocument()) DOMTypeInfoImpl();
                typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validity, attrInfo->getValidity());
                typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Validitation_Attempted, attrInfo->getValidationAttempted());
                if(attrInfo->getTypeDefinition())
                {
                    typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::SIMPLE_TYPE);
                    typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, attrInfo->getTypeDefinition()->getAnonymous());
                    typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, 
                        fDocument->getPooledString(attrInfo->getTypeDefinition()->getNamespace()));
                    typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, 
                        fDocument->getPooledString(attrInfo->getTypeDefinition()->getName()));
                }
                else if(attrInfo->getValidity()==PSVIItem::VALIDITY_VALID)
                {
                    // if we are valid but we don't have a type validator, we are xs:anySimpleType
                    typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Type, XSTypeDefinition::SIMPLE_TYPE);
                    typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Anonymous, false);
                    typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Namespace, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
                    typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Type_Definition_Name, SchemaSymbols::fgDT_ANYSIMPLETYPE);
                }
                if(attrInfo->getMemberTypeDefinition())
                {
                    typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Anonymous, attrInfo->getMemberTypeDefinition()->getAnonymous());
                    typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Namespace, 
                        fDocument->getPooledString(attrInfo->getMemberTypeDefinition()->getNamespace()));
                    typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Member_Type_Definition_Name, 
                        fDocument->getPooledString(attrInfo->getMemberTypeDefinition()->getName()));
                }
                typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Default, fDocument->getPooledString(attrInfo->getSchemaDefault()));
                typeInfo->setStringProperty(DOMPSVITypeInfo::PSVI_Schema_Normalized_Value, fDocument->getPooledString(attrInfo->getSchemaNormalizedValue()));
                typeInfo->setNumericProperty(DOMPSVITypeInfo::PSVI_Schema_Specified, true);
                ((DOMAttrImpl*)pAttrNode)->setTypeInfo(typeInfo);
            }
        }
    }
    // associate the info now; if the user wants, she can override what we did
    if(fPSVIHandler)
        fPSVIHandler->handleAttributesPSVI(localName, uri, psviAttributes);
}

// ---------------------------------------------------------------------------
//  AbstractDOMParser: Implementation of XMLDocumentHandler interface
// ---------------------------------------------------------------------------
void AbstractDOMParser::docCharacters(  const   XMLCh* const    chars
                              , const unsigned int    length
                              , const bool cdataSection)
{
    // Ignore chars outside of content
    if (!fWithinElement)
        return;

    // revisit.  Is it really safe to null-terminate here?
    //                Does the scanner do it already?
    //                If scanner goes up to the very end of an unterminated
    //                buffer, we may be stepping on something bad here.
    //           Probably best to modify the scanner to null terminate.
    XMLCh savedChar = chars[length];
    XMLCh *ncChars  = (XMLCh *)chars;   // cast off const
    ncChars[length] = 0;
    if (cdataSection == true)
    {
        DOMCDATASection *node = fDocument->createCDATASection(chars);
        castToParentImpl (fCurrentParent)->appendChildFast (node);
        fCurrentNode = node;
    }
    else
    {
        if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE)
        {
            DOMText *node = (DOMText *)fCurrentNode;
            node->appendData(chars);
        }
        else
        {
            DOMText *node = fDocument->createTextNode(chars);
            castToParentImpl (fCurrentParent)->appendChildFast (node);
            fCurrentNode = node;
        }
    }
    ncChars[length] = savedChar;
    return;
}


void AbstractDOMParser::docComment(const XMLCh* const comment)
{
    if (fCreateCommentNodes) {
        DOMComment *dcom = fDocument->createComment(comment);
        castToParentImpl (fCurrentParent)->appendChildFast (dcom);
        fCurrentNode = dcom;
    }
}


void AbstractDOMParser::docPI(  const   XMLCh* const    target
                      , const XMLCh* const    data)
{
    DOMProcessingInstruction *pi = fDocument->createProcessingInstruction
        (
        target
        , data
        );
    castToParentImpl (fCurrentParent)->appendChildFast (pi);
    fCurrentNode = pi;
}


void AbstractDOMParser::endEntityReference(const XMLEntityDecl&)
{
    if (!fCreateEntityReferenceNodes) return;

    DOMEntityReferenceImpl *erImpl = 0;

    if (fCurrentParent->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE)
        erImpl = (DOMEntityReferenceImpl *) fCurrentParent;

    fCurrentParent = fNodeStack->pop();

    fCurrentNode   = fCurrentParent;

    if (erImpl)
        erImpl->setReadOnly(true, true);
}


void AbstractDOMParser::endElement( const   XMLElementDecl&
                           , const unsigned int
                           , const bool
                           , const XMLCh* const)
{
    fCurrentNode   = fCurrentParent;
    fCurrentParent = fNodeStack->pop();

    // If we've hit the end of content, clear the flag
    if (fNodeStack->empty())
        fWithinElement = false;
}

void AbstractDOMParser::elementTypeInfo( const XMLCh * const  /*typeName*/
                                       , const XMLCh * const  /*typeURI*/)
{
}


void AbstractDOMParser::ignorableWhitespace(  const XMLCh* const    chars
                                            , const unsigned int    length
                                            , const bool)
{
    // Ignore chars before the root element
    if (!fWithinElement || !fIncludeIgnorableWhitespace)
        return;

    // revisit.  Not safe to slam in a null like this.
    XMLCh savedChar = chars[length];
    XMLCh *ncChars  = (XMLCh *)chars;   // cast off const
    ncChars[length] = chNull;

    if (fCurrentNode->getNodeType() == DOMNode::TEXT_NODE)
    {
        DOMText *node = (DOMText *)fCurrentNode;
        node->appendData(chars);
    }
    else
    {
        DOMTextImpl *node = (DOMTextImpl *)fDocument->createTextNode(chars);
        node->setIgnorableWhitespace(true);
        castToParentImpl (fCurrentParent)->appendChildFast (node);

        fCurrentNode = node;
    }
    ncChars[length] = savedChar;
}


void AbstractDOMParser::resetDocument()
{
    //
    //  The reset methods are called before a new parse event occurs.
    //  Reset this parsers state to clear out anything that may be left
    //  from a previous use, in particular the DOM document itself.
    //
    this->reset();
}


void AbstractDOMParser::startDocument()
{
    if(fImplementationFeatures == 0)
        fDocument = (DOMDocumentImpl *)DOMImplementation::getImplementation()->createDocument(fMemoryManager);
    else 
        fDocument = (DOMDocumentImpl *)DOMImplementationRegistry::getDOMImplementation(fImplementationFeatures)->createDocument(fMemoryManager);

    // Just set the document as the current parent and current node
    fCurrentParent = fDocument;
    fCurrentNode   = fDocument;
    // set DOM error checking off
    fDocument->setErrorChecking(false);
    fDocument->setDocumentURI(fScanner->getLocator()->getSystemId());
    fDocument->setActualEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
}


void AbstractDOMParser::endDocument()
{
    // set DOM error checking back on
    fDocument->setErrorChecking(true);

    // DOM L2 does not support editing DocumentType nodes
    if (fDocumentType && fScanner -> getDoNamespaces())
        fDocumentType->setReadOnly(true, true);
}


void AbstractDOMParser::startElement(const  XMLElementDecl&         elemDecl
                             , const unsigned int            urlId
                             , const XMLCh* const            elemPrefix
                             , const RefVectorOf<XMLAttr>&   attrList
                             , const unsigned int            attrCount
                             , const bool                    isEmpty
                             , const bool                    isRoot)
{
    DOMElement     *elem;
    DOMElementImpl *elemImpl;
    const XMLCh* namespaceURI = 0;

    //get the list for use in the loop
    XMLAttDefList* defAttrs = 0;
    if(elemDecl.hasAttDefs()) {
        defAttrs = &elemDecl.getAttDefList();
    }

    if (fScanner -> getDoNamespaces()) {    //DOM Level 2, doNamespaces on

        if (urlId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix

            namespaceURI = fScanner->getURIText(urlId); //get namespaceURI

            if (elemPrefix && *elemPrefix) {

                XMLBufBid elemQName(&fBufMgr);

                elemQName.set(elemPrefix);
                elemQName.append(chColon);
                elemQName.append(elemDecl.getBaseName());
                elem = createElementNSNode(namespaceURI, elemQName.getRawBuffer());
            }
            else { 
                elem = createElementNSNode(namespaceURI, elemDecl.getBaseName());
            }
        } 
        else {
            elem = createElementNSNode(namespaceURI, elemDecl.getBaseName());
        }

        elemImpl = (DOMElementImpl *) elem;
    }
    else {    //DOM Level 1
        elem = fDocument->createElement(elemDecl.getFullName());
        elemImpl = (DOMElementImpl *) elem;
    }
    for (unsigned int index = 0; index < attrCount; ++index) {
        const XMLAttr* oneAttrib = attrList.elementAt(index);
        DOMAttrImpl *attr = 0;
        DOMNode* remAttr = 0;

        //  revisit.  Optimize to init the named node map to the
        //            right size up front.
        if (fScanner -> getDoNamespaces()) {    //DOM Level 2, doNamespaces on
            unsigned int attrURIId = oneAttrib -> getURIId();
            namespaceURI = 0;            
            if (XMLString::equals(oneAttrib -> getName(), XMLUni::fgXMLNSString)) {   //for xmlns=...
                attrURIId = fScanner->getXMLNSNamespaceId();                
            }
            if (attrURIId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
                namespaceURI = fScanner->getURIText(attrURIId);   //get namespaceURI
            }
            attr = (DOMAttrImpl *)fDocument->createAttributeNS(namespaceURI, oneAttrib->getQName());
            remAttr = elemImpl->setAttributeNodeNS(attr);
        }
        else {
            attr = (DOMAttrImpl *)fDocument->createAttribute(oneAttrib->getName());
            remAttr = elemImpl->setAttributeNode(attr);
        }
        attr->setValue(oneAttrib -> getValue());
        if (remAttr)
            remAttr->release();

        // Attributes of type ID.  If this is one, add it to the hashtable of IDs
        //   that is constructed for use by GetElementByID().
        //
        if (oneAttrib->getType()==XMLAttDef::ID)
        {
            if (fDocument->fNodeIDMap == 0)
                fDocument->fNodeIDMap = new (fDocument) DOMNodeIDMap(500, fDocument);
            fDocument->fNodeIDMap->add(attr);
            attr->fNode.isIdAttr(true);
        }

        attr->setSpecified(oneAttrib->getSpecified());

        // store DTD validation information
        if(fCreateSchemaInfo)
        {
            switch(oneAttrib->getType())
            {
            case XMLAttDef::CData:          attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break;
            case XMLAttDef::ID:             attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break;
            case XMLAttDef::IDRef:          attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break;
            case XMLAttDef::IDRefs:         attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break;
            case XMLAttDef::Entity:         attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break;
            case XMLAttDef::Entities:       attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break;
            case XMLAttDef::NmToken:        attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break;
            case XMLAttDef::NmTokens:       attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break;
            case XMLAttDef::Notation:       attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break;
            case XMLAttDef::Enumeration:    attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break;
            default:                        attr->setTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break;
            }
        }
    }

    // set up the default attributes
	if (defAttrs != 0)
	{		
        XMLAttDef* attr = 0;

        DOMAttrImpl * insertAttr = 0;

        for(unsigned int i=0; i<defAttrs->getAttDefCount(); i++)
        {
            attr = &defAttrs->getAttDef(i);

            const XMLAttDef::DefAttTypes defType = attr->getDefaultType();
            if ((defType == XMLAttDef::Default)
            ||  (defType == XMLAttDef::Fixed))
            {

                if (fScanner->getDoNamespaces())
                {
                    // DOM Level 2 wants all namespace declaration attributes
                    // to be bound to "http://www.w3.org/2000/xmlns/"
                    // So as long as the XML parser doesn't do it, it needs to
                    // done here.
                    const XMLCh* qualifiedName = attr->getFullName();
                    XMLBufBid bbPrefixQName(&fBufMgr);
                    XMLBuffer& prefixBuf = bbPrefixQName.getBuffer();
                    int colonPos = -1;
                    unsigned int uriId = fScanner->resolveQName(qualifiedName, prefixBuf, ElemStack::Mode_Attribute, colonPos);

                    const XMLCh* namespaceURI = 0;
                    if (XMLString::equals(qualifiedName, XMLUni::fgXMLNSString))    //for xmlns=...
                        uriId = fScanner->getXMLNSNamespaceId();
                    if (uriId != fScanner->getEmptyNamespaceId()) {  //TagName has a prefix
                        namespaceURI = fScanner->getURIText(uriId);
                    }

                    insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(namespaceURI,     // NameSpaceURI
                                                                              qualifiedName);   // qualified name

                    DOMAttr* remAttr = elemImpl->setDefaultAttributeNodeNS(insertAttr);
                    if (remAttr)
                        remAttr->release();
                }
                else
                {
                    // Namespaces is turned off...
                    insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());

                    DOMNode* remAttr = elemImpl->setDefaultAttributeNode(insertAttr);
                    if (remAttr)
                        remAttr->release();
                }
                //need to do this before the get as otherwise we overwrite any value in the attr
                if (attr->getValue() != 0)
                {
                    insertAttr->setValue(attr->getValue());
                    insertAttr->setSpecified(false);
                }

                // store DTD validation information
                if(fCreateSchemaInfo)
                {
                    switch(attr->getType())
                    {
                    case XMLAttDef::CData:          insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break;
                    case XMLAttDef::ID:             insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break;
                    case XMLAttDef::IDRef:          insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break;
                    case XMLAttDef::IDRefs:         insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break;
                    case XMLAttDef::Entity:         insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break;
                    case XMLAttDef::Entities:       insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break;
                    case XMLAttDef::NmToken:        insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break;
                    case XMLAttDef::NmTokens:       insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break;
                    case XMLAttDef::Notation:       insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break;
                    case XMLAttDef::Enumeration:    insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break;
                    default:                        insertAttr->setTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break;
                    }
                }
            }

            insertAttr = 0;
            attr->reset();
        }
    }

    if (fCurrentParent != fDocument)
      castToParentImpl (fCurrentParent)->appendChildFast (elem);
    else
      fCurrentParent->appendChild (elem);

    fNodeStack->push(fCurrentParent);
    fCurrentParent = elem;
    fCurrentNode = elem;
    fWithinElement = true;

    // If an empty element, do end right now (no endElement() will be called)
    if (isEmpty)
        endElement(elemDecl, urlId, isRoot, elemPrefix);
}


void AbstractDOMParser::startEntityReference(const XMLEntityDecl& entDecl)
{
    const XMLCh * entName = entDecl.getName();
    DOMNamedNodeMap *entities = fDocumentType->getEntities();
    DOMEntityImpl* entity = (DOMEntityImpl*)entities->getNamedItem(entName);
    if (entity)
        entity->setActualEncoding(fScanner->getReaderMgr()->getCurrentEncodingStr());
    fCurrentEntity = entity;


    // Following line has been moved up so that erImpl is only declared
    // and used if create entity ref flag is true
    if (fCreateEntityReferenceNodes == true)    {
        DOMEntityReference *er = fDocument->createEntityReferenceByParser(entName);

        //set the readOnly flag to false before appending node, will be reset 
        // in endEntityReference
        DOMEntityReferenceImpl *erImpl = (DOMEntityReferenceImpl *) er;
        erImpl->setReadOnly(false, true);

        castToParentImpl (fCurrentParent)->appendChildFast (er);

        fNodeStack->push(fCurrentParent);
        fCurrentParent = er;
        fCurrentNode = er;

    // this entityRef needs to be stored in Entity map too.
    // We'd decide later whether the entity nodes should be created by a
    // separated method in parser or not. For now just stick it in if
    // the ref nodes are created
        if (entity)
            entity->setEntityRef(er);
    }
}


void AbstractDOMParser::XMLDecl(const   XMLCh* const version
                                , const XMLCh* const encoding
                                , const XMLCh* const standalone
                                , const XMLCh* const actualEncStr)
{
    fDocument->setStandalone(XMLString::equals(XMLUni::fgYesString, standalone));

    fDocument->setVersion(version);
    fDocument->setEncoding(encoding);
    fDocument->setActualEncoding(actualEncStr);
}

// ---------------------------------------------------------------------------
//  AbstractDOMParser: Helper methods
// ---------------------------------------------------------------------------
DOMElement* AbstractDOMParser::createElementNSNode(const XMLCh *namespaceURI,
                                                   const XMLCh *qualifiedName)
{
    return fDocument->createElementNS(namespaceURI, qualifiedName);
}
// ---------------------------------------------------------------------------
//  AbstractDOMParser: Deprecated methods
// ---------------------------------------------------------------------------
bool AbstractDOMParser::getDoValidation() const
{
    //
    //  We don't want to tie the public parser classes to the enum used
    //  by the scanner, so we use a separate one and map.
    //
    //  DON'T mix the new and old methods!!
    //
    const XMLScanner::ValSchemes scheme = fScanner->getValidationScheme();
    if (scheme == XMLScanner::Val_Always)
        return true;
    return false;
}

void AbstractDOMParser::setDoValidation(const bool newState)
{
    fScanner->setDoValidation
    (
        newState ? XMLScanner::Val_Always : XMLScanner::Val_Never
    );
}

//doctypehandler interfaces
void AbstractDOMParser::attDef
(
    const   DTDElementDecl&     elemDecl
    , const DTDAttDef&          attDef
    , const bool
)
{	
    if (fDocumentType->isIntSubsetReading())
    {
        if (elemDecl.hasAttDefs())
        {
            fInternalSubset.append(attDef.getFullName());

            // Get the type and display it
            const XMLAttDef::AttTypes type = attDef.getType();
            switch(type)
            {
            case XMLAttDef::CData :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgCDATAString);
                break;
            case XMLAttDef::ID :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgIDString);
                break;
            case XMLAttDef::IDRef :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgIDRefString);
                break;
            case XMLAttDef::IDRefs :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgIDRefsString);
                break;
            case XMLAttDef::Entity :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgEntityString);
                break;
            case XMLAttDef::Entities :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgEntitiesString);
                break;
            case XMLAttDef::NmToken :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgNmTokenString);
                break;
            case XMLAttDef::NmTokens :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgNmTokensString);
                break;

            case XMLAttDef::Notation :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgNotationString);
                break;

            case XMLAttDef::Enumeration :
                {
                    fInternalSubset.append(chSpace);
                    const XMLCh* enumString = attDef.getEnumeration();
                    int length = XMLString::stringLen(enumString);
                    if (length > 0) {

                        fInternalSubset.append(chOpenParen );
                        for(int i=0; i<length; i++) {
                            if (enumString[i] == chSpace)
                                fInternalSubset.append(chPipe);
                            else
                                fInternalSubset.append(enumString[i]);
                        }
                        fInternalSubset.append(chCloseParen);
                    }
                }
                break;
            default:
                // remaining types don't belong to a DTD
                break;
            }
            //get te default types of the attlist
            const XMLAttDef::DefAttTypes def = attDef.getDefaultType();
            switch(def)
            {
            case XMLAttDef::Required :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgRequiredString);
                break;
            case XMLAttDef::Implied :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgImpliedString);
                break;
            case XMLAttDef::Fixed :
                fInternalSubset.append(chSpace);
                fInternalSubset.append(XMLUni::fgFixedString);
                break;
            default:
                // remaining types don't belong to a DTD
                break;
            }

            const XMLCh* defaultValue = attDef.getValue();
            if (defaultValue != 0) {
                fInternalSubset.append(chSpace);
                fInternalSubset.append(chDoubleQuote);
                fInternalSubset.append(defaultValue);
                fInternalSubset.append(chDoubleQuote);
            }
        }
    }
}

void AbstractDOMParser::doctypeComment
(
    const   XMLCh* const    comment
)
{
    if (fDocumentType->isIntSubsetReading())
    {
        if (comment != 0)
        {
            fInternalSubset.append(XMLUni::fgCommentString);
            fInternalSubset.append(chSpace);
            fInternalSubset.append(comment);
            fInternalSubset.append(chSpace);
            fInternalSubset.append(chDash);
            fInternalSubset.append(chDash);
            fInternalSubset.append(chCloseAngle);
        }
    }
}

void AbstractDOMParser::doctypeDecl
(
    const   DTDElementDecl& elemDecl
    , const XMLCh* const    publicId
    , const XMLCh* const    systemId
    , const bool
    , const bool
)
{
    fDocumentType = (DOMDocumentTypeImpl *) fDocument->createDocumentType(elemDecl.getFullName(), publicId, systemId);
    fDocument->setDocumentType(fDocumentType);

}

void AbstractDOMParser::doctypePI
(
    const   XMLCh* const    target
    , const XMLCh* const    data
)
{
    if (fDocumentType->isIntSubsetReading())
    {
        //add these chars to internalSubset variable
        fInternalSubset.append(chOpenAngle);
        fInternalSubset.append(chQuestion);
        fInternalSubset.append(target);
        fInternalSubset.append(chSpace);
        fInternalSubset.append(data);
        fInternalSubset.append(chQuestion);
        fInternalSubset.append(chCloseAngle);
    }	
}


void AbstractDOMParser::doctypeWhitespace
(
    const   XMLCh* const    chars
    , const unsigned int
)
{
    if (fDocumentType->isIntSubsetReading())
        fInternalSubset.append(chars);
}

void AbstractDOMParser::elementDecl
(
    const   DTDElementDecl& decl
    , const bool
)
{
    if (fDocumentType->isIntSubsetReading())
    {
        fInternalSubset.append(chOpenAngle);
        fInternalSubset.append(chBang);
        fInternalSubset.append(XMLUni::fgElemString);
        fInternalSubset.append(chSpace);
        fInternalSubset.append(decl.getFullName());

        //get the ContentSpec information
        const XMLCh* contentModel = decl.getFormattedContentModel();
        if (contentModel != 0) {
            fInternalSubset.append(chSpace);
            fInternalSubset.append(contentModel);
        }

        fInternalSubset.append(chCloseAngle);
    }
}

void AbstractDOMParser::endAttList
(
    const   DTDElementDecl& elemDecl
)
{
    if (fDocumentType->isIntSubsetReading())
    {
        //print the closing angle
        fInternalSubset.append(chCloseAngle);
    }

	// this section sets up default attributes.
	// default attribute nodes are stored in a NamedNodeMap DocumentTypeImpl::elements
	// default attribute data attached to the document is used to conform to the
	// DOM spec regarding creating element nodes & removing attributes with default values
	// see DocumentTypeImpl
	if (elemDecl.hasAttDefs())
	{		
        XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
        XMLAttDef* attr = 0;

        DOMAttrImpl * insertAttr = 0;
        DOMElement     *elem  = fDocument->createElement(elemDecl.getFullName());
        DOMElementImpl *elemImpl = (DOMElementImpl *) elem;

        for(unsigned int i=0; i<defAttrs->getAttDefCount(); i++)
        {
            attr = &defAttrs->getAttDef(i);
            if (attr->getValue() != 0)
            {
                if (fScanner->getDoNamespaces())
                {
                    // DOM Level 2 wants all namespace declaration attributes
                    // to be bound to "http://www.w3.org/2000/xmlns/"
                    // So as long as the XML parser doesn't do it, it needs to
                    // done here.
                    const XMLCh* qualifiedName = attr->getFullName();
                    int index = DOMDocumentImpl::indexofQualifiedName(qualifiedName);

                    XMLBufBid bbQName(&fBufMgr);
                    XMLBuffer& buf = bbQName.getBuffer();
                    static const XMLCh XMLNS[] = {
                        chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chNull};

                    if (index > 0) {
                        // there is prefix
                        // map to XML URI for all cases except when prefix == "xmlns"
                        XMLCh* prefix;
                        XMLCh temp[1000];

                        if (index > 999)
                            prefix = (XMLCh*) fMemoryManager->allocate
                            (
                                (index + 1) * sizeof(XMLCh)
                            );//new XMLCh[index+1];
                        else
                            prefix = temp;

                        XMLString::subString(prefix ,qualifiedName, 0, index, fMemoryManager);

                        if (XMLString::equals(prefix,XMLNS))
                            buf.append(XMLUni::fgXMLNSURIName);
                        else
                            buf.append(XMLUni::fgXMLURIName);

                        if (index > 999)
                            fMemoryManager->deallocate(prefix);//delete [] prefix;
                    }
                    else {
                        //   No prefix
                        if (XMLString::equals(qualifiedName,XMLNS))
                            buf.append(XMLUni::fgXMLNSURIName);
                    }

                    insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(
                       buf.getRawBuffer(),     // NameSpaceURI
                       qualifiedName);   // qualified name

                    DOMNode* remAttr = elemImpl->setAttributeNodeNS(insertAttr);
                    if (remAttr)
                        remAttr->release();
                }
                else
                {
                    // Namespaces is turned off...
                    insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
                    DOMNode* remAttr = elemImpl->setAttributeNode(insertAttr);
                    if (remAttr)
                        remAttr->release();
                }

                insertAttr->setValue(attr->getValue());
                insertAttr->setSpecified(false);
            }
        }
        DOMNode* rem = fDocumentType->getElements()->setNamedItem(elemImpl);
        if (rem)
            rem->release();
    }
}

void AbstractDOMParser::endIntSubset()
{
    fDocumentType->setInternalSubset(fInternalSubset.getRawBuffer());
    // the buffer shouldn't be released as it is reused in the next parse
    // fBufMgr.releaseBuffer(fInternalSubset);
    fDocumentType->fIntSubsetReading = false;
}

void AbstractDOMParser::endExtSubset()
{
}

void AbstractDOMParser::entityDecl
(
    const   DTDEntityDecl&  entityDecl
    , const bool
    , const bool
)
{
    DOMEntityImpl* entity = (DOMEntityImpl *) fDocument->createEntity(entityDecl.getName());

    entity->setPublicId(entityDecl.getPublicId());
    entity->setSystemId(entityDecl.getSystemId());
    entity->setNotationName(entityDecl.getNotationName());
    entity->setBaseURI(entityDecl.getBaseURI());

    DOMEntityImpl *previousDef = (DOMEntityImpl *)
	    fDocumentType->getEntities()->setNamedItem( entity );

    if (previousDef)
        previousDef->release();

    if (fDocumentType->isIntSubsetReading())
    {
        //add thes chars to internalSubset variable
        fInternalSubset.append(chOpenAngle);
        fInternalSubset.append(chBang);
        fInternalSubset.append(XMLUni::fgEntityString);
        fInternalSubset.append(chSpace);

        fInternalSubset.append(entityDecl.getName());

        const XMLCh* id = entity->getPublicId();
        if (id != 0) {
            fInternalSubset.append(chSpace);
            fInternalSubset.append(XMLUni::fgPubIDString);
            fInternalSubset.append(chSpace);
            fInternalSubset.append(chDoubleQuote);
            fInternalSubset.append(id);
            fInternalSubset.append(chDoubleQuote);
        }
        id = entity->getSystemId();
        if (id != 0) {
            fInternalSubset.append(chSpace);
            fInternalSubset.append(XMLUni::fgSysIDString);
            fInternalSubset.append(chSpace);
            fInternalSubset.append(chDoubleQuote);
            fInternalSubset.append(id);
            fInternalSubset.append(chDoubleQuote);

        }
        id = entity->getNotationName();
        if (id != 0) {
            fInternalSubset.append(chSpace);
            fInternalSubset.append(XMLUni::fgNDATAString);
            fInternalSubset.append(chSpace);
            fInternalSubset.append(id);
        }
        id = entityDecl.getValue();
        if (id !=0) {
            fInternalSubset.append(chSpace);
            fInternalSubset.append(chDoubleQuote);
            fInternalSubset.append(id);
            fInternalSubset.append(chDoubleQuote);
        }

        fInternalSubset.append(chCloseAngle);
    }

}

void AbstractDOMParser::resetDocType()
{
	fDocumentType = 0;
}

void AbstractDOMParser::notationDecl
(
    const   XMLNotationDecl&    notDecl
    , const bool
)
{
    DOMNotationImpl* notation = (DOMNotationImpl *)fDocument->createNotation(notDecl.getName());
    notation->setPublicId(notDecl.getPublicId());
    notation->setSystemId(notDecl.getSystemId());
    notation->setBaseURI(notDecl.getBaseURI());

    DOMNode* rem = fDocumentType->getNotations()->setNamedItem( notation );
    if (rem)
        rem->release();

    if (fDocumentType->isIntSubsetReading())
    {
        //add thes chars to internalSubset variable
        fInternalSubset.append(chOpenAngle);
        fInternalSubset.append(chBang);
        fInternalSubset.append(XMLUni::fgNotationString);
        fInternalSubset.append(chSpace);

        fInternalSubset.append(notDecl.getName());

        const XMLCh* id = notation->getPublicId();
        if (id != 0) {
            fInternalSubset.append(chSpace);
            fInternalSubset.append(XMLUni::fgPubIDString);
            fInternalSubset.append(chSpace);
            fInternalSubset.append(chDoubleQuote);
            fInternalSubset.append(id);
            fInternalSubset.append(chDoubleQuote);
        }
        id = notation->getSystemId();
        if (id != 0) {
            fInternalSubset.append(chSpace);
            fInternalSubset.append(XMLUni::fgSysIDString);
            fInternalSubset.append(chSpace);
            fInternalSubset.append(chDoubleQuote);
            fInternalSubset.append(id);
            fInternalSubset.append(chDoubleQuote);

        }
        fInternalSubset.append(chCloseAngle);
    }
}

void AbstractDOMParser::startAttList
(
    const   DTDElementDecl& elemDecl
)
{
    if (fDocumentType->isIntSubsetReading())
    {
        fInternalSubset.append(chOpenAngle);
        fInternalSubset.append(chBang);
        fInternalSubset.append(XMLUni::fgAttListString);
        fInternalSubset.append(chSpace);
        fInternalSubset.append(elemDecl.getFullName());
    }
}

void AbstractDOMParser::startIntSubset()
{
	fDocumentType->fIntSubsetReading = true;
}

void AbstractDOMParser::startExtSubset()
{
}

void AbstractDOMParser::TextDecl
(
    const   XMLCh* const    versionStr
    , const XMLCh* const    encodingStr
)
{
    if (fCurrentEntity) {
        fCurrentEntity->setVersion(versionStr);
        fCurrentEntity->setEncoding(encodingStr);
    }
}

XERCES_CPP_NAMESPACE_END

