XSModel *XMLGrammarPoolImpl::getXSModel(bool& XSModelWasChanged)
{
    XSModelWasChanged = false;
    if (fLocked || fXSModelIsValid)
        return fXSModel;

    createXSModel();
    XSModelWasChanged = true;
    return fXSModel;
}
XSModel *XMLGrammarPoolImpl::getXSModel() 
{
    if (fLocked)
        return fXSModel;

    if (fXSModelIsValid)
        return fXSModel;
        
    createXSModel();    
    return fXSModel;
}
void XMLGrammarPoolImpl::lockPool()
{
    if (!fLocked)
    {
        fLocked = true;
        MemoryManager *memMgr = getMemoryManager();
        if(!fSynchronizedStringPool)
        {
            fSynchronizedStringPool = new (memMgr) XMLSynchronizedStringPool(fStringPool, 109, memMgr);
        }
        if (!fXSModelIsValid)
        {
            createXSModel();
        }
    }
}
/***
 *   .empty stringPool
 *   .empty gramamrRegistry
 ***/
void XMLGrammarPoolImpl::deserializeGrammars(BinInputStream* const binIn)
{
    MemoryManager *memMgr = getMemoryManager();
    unsigned int stringCount = fStringPool->getStringCount();
    if (stringCount)
    {
        /***
         * it contains only the four predefined one, that is ok
         * but we need to reset the string before deserialize it
         *
         ***/
        if ( stringCount <= 4 )
        {
            fStringPool->flushAll();
        }
        else
        {
            ThrowXMLwithMemMgr(XSerializationException, XMLExcepts::XSer_StringPool_NotEmpty, memMgr);
        }
    }

    RefHashTableOfEnumerator<Grammar> grammarEnum(fGrammarRegistry, false, memMgr);
    if (grammarEnum.hasMoreElements())
    {
        ThrowXMLwithMemMgr(XSerializationException, XMLExcepts::XSer_GrammarPool_NotEmpty, memMgr);
    }

    // This object will take care of cleaning up if an exception is
    // thrown during deserialization.
    JanitorMemFunCall<XMLGrammarPoolImpl>   cleanup(this, &XMLGrammarPoolImpl::cleanUp);

    try
    {
        XSerializeEngine  serEng(binIn, this);

        //version information
        unsigned int  StorerLevel;
        serEng>>StorerLevel;
        serEng.fStorerLevel = StorerLevel;

        // The storer level must match the loader level.
        //
        if (StorerLevel != (unsigned int)XERCES_GRAMMAR_SERIALIZATION_LEVEL)
        {
            XMLCh     StorerLevelChar[5];
            XMLCh     LoaderLevelChar[5];
            XMLString::binToText(StorerLevel,                          StorerLevelChar,   4, 10, memMgr);
            XMLString::binToText(XERCES_GRAMMAR_SERIALIZATION_LEVEL,   LoaderLevelChar,   4, 10, memMgr);

            ThrowXMLwithMemMgr2(XSerializationException
                    , XMLExcepts::XSer_Storer_Loader_Mismatch
                    , StorerLevelChar
                    , LoaderLevelChar
                    , memMgr);
        }

        //lock status
        serEng>>fLocked;

        //StringPool, don't use >>
        fStringPool->serialize(serEng);

        /***
         * Deserialize RefHashTableOf<Grammar>*    fGrammarRegistry;
         ***/
        XTemplateSerializer::loadObject(&fGrammarRegistry, 29, true, serEng);

    }
    catch(const OutOfMemoryException&)
    {
        // This is a special case, because we don't want
        // to execute cleanup code on out-of-memory
        // conditions.
        cleanup.release();

        throw;
    }

    // Everything is OK, so we can release the cleanup object.
    cleanup.release();

    if (fLocked)
    {
        createXSModel();
    }
}