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

#include "XalanFileUtility.hpp"



#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <climits>
#include <cstring>

#if defined(XALAN_HAVE_WIN32_DIRECT_H)
#include <direct.h>
#define PATH_MAX _MAX_PATH
#define chdir _chdir
#define getcwd _getcwd
#define mkdir _mkdir
#elif XALAN_HAVE_UNISTD_H
#if !defined(PATH_MAX)
#define PATH_MAX 2000
#endif
#define DIR_MODE_BITS 509
#include <dirent.h>
#include <unistd.h>

#include <sys/stat.h>
#endif


#include <iostream>
#include <strstream>



using std::fclose;
using std::feof;
using std::ferror;
using std::fgets;
using std::fopen;
using std::localtime;
using std::sprintf;
using std::strftime;
using std::tm;
using std::time;



#include "xercesc/sax/ErrorHandler.hpp"
#include "xercesc/sax/SAXException.hpp"
#include "xercesc/sax/SAXParseException.hpp"



#include "xalanc/PlatformSupport/DirectoryEnumerator.hpp"
#include "xalanc/PlatformSupport/DOMStringHelper.hpp"
#include "xalanc/PlatformSupport/XalanOutputStreamPrintWriter.hpp"
#include "xalanc/PlatformSupport/XalanFileOutputStream.hpp"
#include "xalanc/PlatformSupport/XalanUnicode.hpp"



#include "xalanc/XMLSupport/FormatterToXML.hpp"
#include "xalanc/XMLSupport/FormatterTreeWalker.hpp"



#include "xalanc/XalanSourceTree/XalanSourceTreeDOMSupport.hpp"
#include "xalanc/XalanSourceTree/XalanSourceTreeParserLiaison.hpp"
#include "xalanc/XalanSourceTree/XalanSourceTreeDocument.hpp"



#include "xalanc/XSLT/StylesheetRoot.hpp"



#include "xalanc/XalanTransformer/XalanCompiledStylesheet.hpp"
#include "xalanc/XalanTransformer/XalanTransformer.hpp"



#include "XalanXMLFileReporter.hpp"



namespace XALAN_CPP_NAMESPACE {




const char* const   xalanNodeTypes[] =
{
    "UNKNOWN_NODE",
    "ELEMENT_NODE",
    "ATTRIBUTE_NODE",
    "TEXT_NODE",
    "CDATA_SECTION_NODE",
    "ENTITY_REFERENCE_NODE",
    "ENTITY_NODE",
    "PROCESSING_INSTRUCTION_NODE",
    "COMMENT_NODE",
    "DOCUMENT_NODE",
    "DOCUMENT_TYPE_NODE",
    "DOCUMENT_FRAGMENT_NODE",
    "NOTATION_NODE"
};



using std::cerr;
using std::cout;
using std::endl;


const XalanDOMString    XalanFileUtility::s_emptyString(XalanMemMgrs::getDummyMemMgr());



XalanFileUtility::reportStruct::reportStruct(MemoryManager&     theManager) :
    theDrive(theManager),
    testOrFile(theManager),
    xmlFileURL(theManager),
    xslFileURL(theManager),
    xmlFormat(theManager),
    msg(0),
    currentNode(theManager),
    actual(theManager),
    expected(theManager),
    pass(0),
    fail(0),
    nogold(0)
{
}



void
XalanFileUtility::reportStruct::reset()
{
    testOrFile.clear();
    msg = "";
    currentNode.clear();
    actual.clear();
    expected.clear();
}



XalanFileUtility::cmdParams::cmdParams(MemoryManager&   theManager) :
    help(),
    base(theManager),
    output(theManager),
    gold(theManager),
    sub(theManager),
    source(0),
    skip(false),
    iters(0)
{
}



const char*
XalanFileUtility::cmdParams::getHelpMessage()
{
    help << '\0';

    const char* const   data = help.str();

#if defined(HPUX)
   help.rdbuf() -> freeze(false);
#else
    help.freeze(false);
#endif

    return data;
}



XalanFileUtility::XalanFileUtility(MemoryManager&   theManager) :
    data(theManager),
    args(theManager),
    m_buffer(theManager),
    m_verbose(false)
{
    cout << endl
         << "Using Xalan version "
         << XALAN_FULLVERSIONDOT
         << endl
         << "Using Xerces version "
         << XERCES_FULLVERSIONDOT
         << endl
         << endl;
}



XalanFileUtility::~XalanFileUtility()
{
}



#if !defined(XALAN_WINDOWS)
XalanDOMString&
XalanFileUtility::getDrive(XalanDOMString&  theResult)
{
    theResult.erase();

    return theResult;
}
#else
XalanDOMString&
XalanFileUtility::getDrive(XalanDOMString&  theResult)
{
    const char temp[] =
    {
        char(_getdrive() + 'A' - 1),
        ':',
        '\0'
    };
    theResult.assign(temp, sizeof(temp) - 1);

    return theResult;
}
#endif


bool
XalanFileUtility::getParams(
            int             argc,
            char*           argv[],
            const char*     outDir,
            bool            fsetGold)
{
    bool fSuccess = true;   // Used to continue argument loop
    bool fsetOut = true;    // Set default output directory, set to false if data is provided

    args.skip = true;       // Default values for performance testing parameters.
    args.iters = 3;         

    // Insure that required "-base" argument is there.
    //
    if (argc == 1 || argv[1][0] == '-')
    {
        cout << args.getHelpMessage();  
        return false;
    }
    else
    {
        if (checkDir(XalanDOMString(argv[1], getMemoryManager())))
        {
            args.base.assign(XalanDOMString(argv[1], getMemoryManager()));
        }
        else
        {
            cout << endl << "Given base directory \"" << argv[1] << "\" does not exist" << endl;
            cout << args.getHelpMessage();
            return false;
        }
    }

    // Get the rest of the arguments.
    //
    for (int i = 2; i < argc && fSuccess == true; ++i)
    {
        if(!strcmp("-out", argv[i]))
        {
            ++i;
            if(i < argc && argv[i][0] != '-')
            {
                args.output.assign(XalanDOMString(argv[i], getMemoryManager()));
                args.output.append(s_pathSep);
                checkAndCreateDir(args.output);
                fsetOut = false;
            }
            else
            {
                cout << args.getHelpMessage();
                fSuccess = false;
            }
        }
        else if(!strcmp("-gold", argv[i]))
        {
            ++i;
            if(i < argc && argv[i][0] != '-')
            {
                args.gold.assign(XalanDOMString(argv[i], getMemoryManager()));

                if ( !checkDir(args.gold) )
                {   
                    TranscodeToLocalCodePage(args.gold, m_buffer, true);

                    cout << "Given Gold dir - " << &*m_buffer.begin() << " - does not exist" << endl;
                    fSuccess = false;
                }

                args.gold.append(s_pathSep);
                fsetGold = false;
            }
            else
            {
                cout << args.getHelpMessage();
                fSuccess = false;
            }
        }
        else if(!strcmp("-source", argv[i]))
        {
            ++i;
            if(i < argc && argv[i][0] != '-')
            {
                if (strcmp(argv[i],"XPL") == 0)
                {
                    args.source = 1;
                    outDir = "DOM-XALAN";
                }
                else if (strcmp(argv[i], "DOM") == 0)
                {
                    args.source = 2;
                    outDir = "DOM-XERCES";
                }
                else
                {
                    cout << args.getHelpMessage();
                    fSuccess = false;
                }
            }
            else
            {
                cout << args.getHelpMessage();
                fSuccess = false;
            }
        }
        else if(!strcmp("-sub", argv[i]))
        {
            ++i;
            if(i < argc && argv[i][0] != '-')
            {
                args.sub.assign(XalanDOMString(argv[i], getMemoryManager()));
            }
            else
            {
                cout << args.getHelpMessage();
                fSuccess = false;
            }
        }
        else if(!strcmp("-i", argv[i]))
        {
            args.skip = false;
        }
        else if(!strcmp("-iter", argv[i]))
        {
            ++i;
            
            // Make sure number is there and is greater then zero
            if(i < argc && atol(argv[i]) > 0)
            {
                args.iters = atol(argv[i]);
            }
            else
            {
                cout << args.getHelpMessage();
                fSuccess = false;
            }
        }
        else
        {
            cout << args.getHelpMessage();
            fSuccess = false;
        }

    } // End of for-loop

    // Do we need to set the default output directory??
    //
    if (fsetOut)
    { 
        const XalanDOMString::size_type     ii =
            lastIndexOf(args.base, s_pathSep[0]);

        if (ii < args.base.length())
        {
            args.output.assign(args.base, 0, ii + 1);
        }

        args.output.append(XalanDOMString(outDir, getMemoryManager()));
        checkAndCreateDir(args.output);
        args.output.append(s_pathSep); 

    }
    // Do we need to set the default gold directory??
    //
    if (fsetGold)
    {
        args.gold = args.base;
        args.gold.append(XalanDOMString("-gold", getMemoryManager()));
        if ( !checkDir(args.gold) )
        {   
            TranscodeToLocalCodePage(args.gold, m_buffer, true);
            cout << "Assumed Gold dir - " << &*m_buffer.begin() << " - does not exist" << endl;
            fSuccess = false;
        }
        args.gold.append(s_pathSep);
    }
    
    // Add the path seperator to the end of the base directory 
    // here after we've finished using it for all directory creation.
    //
    args.base.append(s_pathSep);
    
    return fSuccess;
}



//  This routine retrieves test file names from specified directories.
//  Inputs: baseDir:    typically "conf" or "perf"
//          relDir:     sub-directory to search.
//
//  Notes:  It builds the searchSpecification by concatenating all the 
//          necessary components.
//
XalanFileUtility::FileNameVectorType&
XalanFileUtility::getTestFileNames(
            const XalanDOMString&   baseDir,
            const XalanDOMString&   relDir,
            bool                    useDirPrefix,
            FileNameVectorType&     theFiles)
{
    char buffer3[PATH_MAX];
    getcwd(buffer3, PATH_MAX);

    const XalanDOMString    searchSuffix("*.xsl", getMemoryManager());
    XalanDOMString  searchSpecification(getMemoryManager());

    // Allow directory search w/o mandating files start with directory name. Required for files
    // garnered from XSLTMARK performance directory exm.
    if (useDirPrefix)
    {
        searchSpecification.assign(baseDir);
        searchSpecification += relDir;
        searchSpecification += s_pathSep;
        searchSpecification += relDir;
        searchSpecification += searchSuffix;
    }
    else
    {
        searchSpecification.assign(baseDir);
        searchSpecification += relDir;
        searchSpecification += s_pathSep;
        searchSpecification += searchSuffix;
    }


    DirectoryEnumeratorFunctor<
        FileNameVectorType,
        XalanDOMString>     theEnumerator(getMemoryManager());

    theEnumerator(searchSpecification, theFiles);

    chdir(buffer3);

    return theFiles;
}

/*  This routine retrieves all sub-directories from the specified directories.
//  Inputs: rootDirectory:  typically "conf" or "perf"
//
//  Notes:  The searchSpecification in this case is just "*". 
//                                                                          */  
XalanFileUtility::FileNameVectorType&
XalanFileUtility::getDirectoryNames(
            const XalanDOMString&                   rootDirectory,
            XalanFileUtility::FileNameVectorType&   theFiles)
{
    char buffer2[PATH_MAX];
    getcwd(buffer2, PATH_MAX);

    const XalanDOMString    dirSpec("*", getMemoryManager());

    DirectoryEnumeratorFunctor<
        FileNameVectorType,
        XalanDOMString,
        DirectoryFilterPredicate>   theEnumerator(getMemoryManager());

    theEnumerator(
        XalanDOMString(
            rootDirectory,
            getMemoryManager()),
        XalanDOMString(
            dirSpec,
            getMemoryManager()), 
        theFiles);
    
    chdir(buffer2);

    return theFiles;
}


bool XalanFileUtility::checkDir(const XalanDOMString&    directory )
{
    char buffer[PATH_MAX];

    getcwd(buffer, PATH_MAX);

    bool    fResult = false;

    TranscodeToLocalCodePage(directory, m_buffer, true);

    if ( !chdir(&*m_buffer.begin()) )
    {
        fResult = true;
    }

    chdir(buffer);

    return fResult;
}


void XalanFileUtility::checkAndCreateDir(const XalanDOMString&   directory)
{
    char buffer[PATH_MAX];

    getcwd(buffer, PATH_MAX);

    TranscodeToLocalCodePage(directory, m_buffer, true);

    const char* const   theDir = &*m_buffer.begin();
    assert(theDir != 0);

    if (chdir(theDir))
    {
        //cout << "Couldn't change to " << directory << ", will create it." << endl;
#if defined(XALAN_WINDOWS_DIR_FUNCTIONS)
        if (!mkdir(theDir))
#else
        if (!mkdir(theDir, DIR_MODE_BITS))
#endif
        {
            if (m_verbose == true)
            {
                cout << theDir << " created." << endl;
            }
        }
        else
        {
            cout << theDir << " NOT created." << endl;
        }
    }

    chdir(buffer);
}

/*  This routine generates file names based on the provide suffix
//  Inputs: theXMLFileName: typically "conf" or "perf"
//          suffix:         typically "xsl" or "out".
//
//  Notes:  
*/  

XalanDOMString&
XalanFileUtility::generateFileName(
            const XalanDOMString&   theXMLFileName,
            const char*             suffix,
            XalanDOMString&         targetFile,
            bool*                   status)
{
    const XalanDOMString::size_type     thePeriodIndex =
        lastIndexOf(theXMLFileName, XalanUnicode::charFullStop);

    if (thePeriodIndex != XalanDOMString::npos)
    {
        targetFile.assign(theXMLFileName, 0, thePeriodIndex + 1);

        targetFile += XalanDOMString(suffix, getMemoryManager());
    }

    // Check the .xml file exists.
    if (!strcmp(suffix, "xml"))
    {
        TranscodeToLocalCodePage(targetFile, m_buffer, true);
        const char* const   theFileName = &*m_buffer.begin();
        assert(theFileName != 0);

        FILE* fileHandle = fopen(theFileName, "r");
        if (fileHandle == 0)
        {
            cout << "TEST ERROR: File Missing: " << theFileName << endl;

            if (status != 0)
            {
                *status = false;
            }
        }
        else
        {
            fclose(fileHandle);
        }
    }

    return targetFile;
}


/*  This routine generates a Unique Runid. 
//  Inputs: None
//          
//  Notes: The format is mmddhhmm. For example
//         03151046 is "Mar 15 10:46"   
*/

XalanDOMString&
XalanFileUtility::generateUniqRunid(XalanDOMString& theResult)
{
    struct tm *newtime;
    time_t long_time;
    char tmpbuf[10];

    time( &long_time );                /* Get time as long integer. */
    newtime = localtime( &long_time ); /* Convert to local time. */

    strftime( tmpbuf, 10,"%m%d%H%M",newtime );

    theResult.assign(tmpbuf);

    return theResult;
}


//  This routine gets Xerces Version number. It's used to put the Xerces Version
//  into the output xml results file as an attribute of 'PerfData' element.
//  Inputs: None
//              

XalanDOMString&
XalanFileUtility::getXercesVersion(XalanDOMString& theResult)
{
    theResult.assign(gXercesFullVersionStr);

    return theResult;
}

/*  This routine creates a FormatterToXML FormatterListener. This is used to format
//  the output DOM so a comparision can be done with the expected GOLD file. 
//  Inputs: None
//              
*/


FormatterListener* 
XalanFileUtility::getXMLFormatter(
            PrintWriter&            resultWriter,
            int                     indentAmount,
            const XalanDOMString&   mimeEncoding,
            const StylesheetRoot*   stylesheet)
{
    XalanDOMString  version(getMemoryManager());
    bool            outputIndent= 0;
    XalanDOMString  mediatype(getMemoryManager());
    XalanDOMString  doctypeSystem(getMemoryManager());
    XalanDOMString  doctypePublic(getMemoryManager());
    XalanDOMString  standalone(getMemoryManager());

    if (stylesheet != 0)
    {
        XalanDOMString  theBuffer(getMemoryManager());

        version = stylesheet->getOutputVersion(theBuffer);

        mediatype = stylesheet->getOutputMediaType(theBuffer);
        doctypeSystem = stylesheet->getOutputDoctypeSystem(theBuffer);
        doctypePublic = stylesheet->getOutputDoctypePublic(theBuffer);
        standalone = stylesheet->getOutputStandalone(theBuffer);
        outputIndent = stylesheet->getOutputIndent();
    }

    return FormatterToXML::create(
                    resultWriter.getMemoryManager(),
                    resultWriter,
                    version,
                    outputIndent,
                    indentAmount,
                    mimeEncoding,
                    mediatype,
                    doctypeSystem,
                    doctypePublic,
                    true,   // xmlDecl
                    standalone);
}


/*  This routine is used to compares the results of a transform and report the results.
//  When a failure is detected the 'data' structure used to report detailed info about 
//  a failure is filled in.
//  Inputs: 
//      goldFile    - Name of gold file
//      outputFile  - Name of result file.
//      logfile     - Name of log file reporter.
//      
//  Returns: 
//      Void
*/
void
XalanFileUtility::checkResults(
            const XalanDOMString&   outputFile, 
            const XalanDOMString&   goldFile, 
            XalanXMLFileReporter&   logfile)
{
    int ambgFlag = data.nogold; // get the current number of tests w/o gold files.

    // Compare the results, report success if compareSerializedResults returns true.
    if(compareSerializedResults(outputFile, goldFile))
    {
        cout << "Passed: " << data.testOrFile << endl;
        logfile.logCheckPass(data.testOrFile);
        data.pass += 1;
    }
    else
    {
        typedef XalanXMLFileReporter::Hashtable  Hashtable;

        // if the compairson fails gather up the failure data and determine if it failed 
        // due to bad output or missing Gold file. Lastly, log the failure.
        Hashtable   attrs(getMemoryManager());
        Hashtable   actexp(getMemoryManager());

        reportError();

        attrs.insert(XalanDOMString("reason", getMemoryManager()), XalanDOMString(data.msg, getMemoryManager()));
        attrs.insert(XalanDOMString("atNode", getMemoryManager()), data.currentNode);
        actexp.insert(XalanDOMString("exp", getMemoryManager()),data.expected);
        actexp.insert(XalanDOMString("act", getMemoryManager()), data.actual);

        actexp.insert(XalanDOMString("xsl", getMemoryManager()), data.xslFileURL);
        actexp.insert( XalanDOMString("xml", getMemoryManager()),  data.xmlFileURL);
        actexp.insert( XalanDOMString("result", getMemoryManager()),  outputFile );
        actexp.insert( XalanDOMString("gold", getMemoryManager()),  goldFile);

        if (ambgFlag < data.nogold)
        {
            logfile.logCheckAmbiguous(data.testOrFile);
        }
        else
        {
            logfile.logCheckFail(data.testOrFile, attrs, actexp);
        }

    }
}

void
XalanFileUtility::checkAPIResults(
            const XalanDOMString&   actual, 
            const XalanDOMString&   expected, 
            const char*             msg,
            XalanXMLFileReporter&        logfile,
            const XalanDOMString&   outputFile, 
            const XalanDOMString&   goldFile,
            bool                    containsOnly)
{
    if(actual == expected ||
       (containsOnly == true && indexOf(actual, expected) != XalanDOMString::npos))
    {
        data.pass += 1;
        cout << "Passed: " << data.testOrFile << endl;
        logfile.logCheckPass(data.testOrFile);
    }
    else
    {   data.actual = actual;
        data.expected = expected;
        data.currentNode = "API Test";
        data.msg = msg;
        data.fail += 1;

        reportError();

        typedef XalanXMLFileReporter::Hashtable  Hashtable;

        Hashtable   actexp(getMemoryManager());

        actexp.insert( XalanDOMString("exp", getMemoryManager()), expected);
        actexp.insert( XalanDOMString("act", getMemoryManager()), actual);
        actexp.insert( XalanDOMString("xsl", getMemoryManager()), data.xslFileURL);
        actexp.insert( XalanDOMString("xml", getMemoryManager()), data.xmlFileURL);
        actexp.insert( XalanDOMString("result", getMemoryManager()), outputFile);
        actexp.insert( XalanDOMString("gold", getMemoryManager()), goldFile);

        // Todo: Need to determine if I should check for missing gold in these cases.
        logfile.logCheckFail(data.testOrFile, actexp);
    }
}



/*  This routine compares the results of a transform with the gold file.
//  It in turn call the domCompare routine to do the actual comparision. 
//  Inputs: 
//      gold - Dom tree for the expected results
//      doc  - Dom tree created during transformation
//      filename - Current filename
//      
//  Returns: 
//      Void
//      
*/
void
XalanFileUtility::checkDOMResults(
            const XalanDOMString&           theOutputFile, 
            const XalanCompiledStylesheet*  compiledSS, 
            const XalanSourceTreeDocument*  dom,
            const XSLTInputSource&          goldInputSource,
            XalanXMLFileReporter&           logfile)
{
    const int   ambgFlag = data.nogold;

    const XalanDOMString    mimeEncoding("", getMemoryManager());

    XalanFileOutputStream           myOutput(theOutputFile, getMemoryManager());
    XalanOutputStreamPrintWriter    myResultWriter(myOutput);

    FormatterListener* const    theFormatter =
        getXMLFormatter(
            myResultWriter,
            0,
            mimeEncoding,
            compiledSS->getStylesheetRoot());

    FormatterTreeWalker     theTreeWalker(*theFormatter, getMemoryManager());

    theTreeWalker.traverse(dom);

    XalanDestroy(
        getMemoryManager(),
        *theFormatter);

    XalanSourceTreeDOMSupport       domSupport;
    XalanSourceTreeParserLiaison    parserLiaison(domSupport, getMemoryManager());
    
    domSupport.setParserLiaison(&parserLiaison);

    const XalanDocument* const  goldDom =
        parserLiaison.parseXMLStream(goldInputSource);

    if (domCompare(*goldDom, *dom))
    {
        cout << "Passed: " << data.testOrFile << endl;
        logfile.logCheckPass(data.testOrFile);
        data.pass += 1;
    }
    else
    {
        typedef XalanXMLFileReporter::Hashtable  Hashtable;

        // if the compairson fails gather up the failure data and determine if it failed 
        // due to bad output or missing Gold file. Lastly, log the failure.
        Hashtable attrs(getMemoryManager());
        Hashtable actexp(getMemoryManager());

        reportError();

        attrs.insert(
            XalanDOMString("reason", getMemoryManager()), 
            XalanDOMString(data.msg, getMemoryManager()));

        attrs.insert(
            XalanDOMString("atNode", getMemoryManager()),
            data.currentNode);

        actexp.insert(
            XalanDOMString("exp", getMemoryManager()),
            data.expected);

        actexp.insert(
            XalanDOMString("act", getMemoryManager()),
            data.actual);

        if (ambgFlag < data.nogold)
        {
            logfile.logCheckAmbiguous(data.testOrFile);
        }
        else
        {
            logfile.logCheckFail(data.testOrFile, attrs, actexp);
        }

    }
}



class DummyErrorHandler : public xercesc::ErrorHandler
{
    virtual void
    warning(const xercesc::SAXParseException& exc)
    {
        throw exc;
    }

    virtual void
    error(const xercesc::SAXParseException& exc)
    {
        throw exc;
    }

    virtual void
    fatalError(const xercesc::SAXParseException& exc)
    {
        throw exc;
    }

    virtual void
    resetErrors()
    {
    }
};



/*  This routine takes the result file and gold file and parses them.
//  If either of the files fails to parse and a SAXException is throw,
//  then the files are compared using a char by char file compare,
//  otherwise the domCompare routine is used.
//  Inputs: 
//      outputFile:  Name of result file
//      goldFile:    Name of gold file
//      
//  Returns: 
//      True or False
//      
*/
bool
XalanFileUtility::compareSerializedResults(
            const XalanDOMString&   outputFile,
            const XalanDOMString&   goldFile)
{
    const XSLTInputSource   resultInputSource(outputFile, getMemoryManager());
    const XSLTInputSource   goldInputSource(goldFile, getMemoryManager());

    XalanSourceTreeDOMSupport       domSupport;
    XalanSourceTreeParserLiaison    parserLiaison(domSupport, getMemoryManager());

    domSupport.setParserLiaison(&parserLiaison);

    DummyErrorHandler   theErrorHandler;

    parserLiaison.setErrorHandler(&theErrorHandler);

    try
    {
        const XalanDocument* const  transformDom =
            parserLiaison.parseXMLStream(resultInputSource);
        assert(transformDom != 0);

        const XalanDocument* const  goldDom =
            parserLiaison.parseXMLStream(goldInputSource);
        assert(goldDom != 0);

        return domCompare(*goldDom, *transformDom);
    }
    // This exception is being reported prior to this Catch, however, however, I clarify that it's a SAX exception.
    // It's a good indication that the Gold file is not a valid XML.  When this happens the transform result needs
    // to be compared with the Gold,  with a character by character basis,  not via the DOM compair. 
    catch (const xercesc::SAXException&)
    {
        if (m_verbose == true)
        {
            cout << "SAXException: Using fileCompare to check output.\n";
        }

        CharVectorType     goldFileVec(getMemoryManager());
        TranscodeToLocalCodePage(goldFile, goldFileVec, true);

        CharVectorType     outputFileVec(getMemoryManager());
        TranscodeToLocalCodePage(outputFile, outputFileVec, true);
        return fileCompare(c_str(goldFileVec), c_str(outputFileVec));
    }
}



/*  This routine is used to compare the results against the gold when one or both of 
//  fails to parse without throwing a SAXException. When a failure is detected the 'data' 
//  structure used to report detailed info about a failure is filled in.
//  Inputs: 
//      outputFile:  Name of result file
//      goldFile:    Name of gold file
//      
//  Returns: 
//      True or False
//      
*/
bool
XalanFileUtility::fileCompare(
            const char*     goldFile,
            const char*     outputFile)
{
    bool    retValue = true;

    const unsigned long     maxBuffer = 132;

    char rline[maxBuffer];  // declare buffers to hold single line from file
    char gline[maxBuffer];
    char temp[20];              // buffer to hold line number
    char lineNum = 1;

    // Set fail data incase there are i/o problems with the files to compare.
    data.expected = XalanDOMString(" ", getMemoryManager());
    data.actual = XalanDOMString(" ", getMemoryManager());
    data.currentNode = XalanDOMString("Line: 0", getMemoryManager());

    // Attempt to open the files. 
    FILE* const     result = fopen(outputFile, "r");
    FILE* const     gold = fopen(goldFile, "r");

    if (!result)
    {
        // If the result file fails to open report this as a failure.
        data.msg = "No Result (Transform failed)";
        data.fail += 1;
        retValue = false;
    }
    else if (!gold)
    {
        // If the gold file fails to open report this as ambiguous.
        data.msg = "No Gold file";
        data.nogold += 1;
        retValue = false;
    }
    else
    {
        // Start file comparison,  line by line..
        while(!feof(result) && !feof(gold) && retValue == true)
        {
		    gline[0] = '\0';
		    rline[0] = '\0';

		    fgets(gline, sizeof(gline), gold );
            fgets(rline, sizeof(rline), result );
            sprintf(temp,"%d",lineNum);

            if (ferror(gold) || ferror(result))
            {
                data.msg = "Read Error - Gold/Result file";
                data.currentNode = XalanDOMString("Line: ", getMemoryManager());
                data.currentNode += XalanDOMString(temp, getMemoryManager());
                retValue = false;
            }
            else
            {
                // Compare the lines character by charcter ....
                XalanSize_t     i = 0;
                while(i < strlen(gline) && retValue == true) 
                {
                    if (gline[i] == rline[i]) 
                    {
                        ++i;
                    }
                    else
                    {   // If there is a mismatch collect up the fail data and return false.  To ensure that 
                        // the results can be seen in the browser enclose the actual/expected in CDATA Sections.

                        data.msg = "Text based comparison failure";

                        try
                        {
                            data.expected += XalanDOMString(gline, getMemoryManager());
                        }
                        catch(const XalanDOMString::TranscodingError&)
                        {
                            data.expected +=
                                XalanDOMString(
                                    "Unable to transcode expected data.",
                                    getMemoryManager());
                        }

                        try
                        {
                            data.actual += XalanDOMString(rline, getMemoryManager());
                        }
                        catch(const XalanDOMString::TranscodingError&)
                        {
                            data.actual +=
                                XalanDOMString(
                                    "Unable to transcode actual data.",
                                    getMemoryManager());
                        }

                        data.currentNode = XalanDOMString("Line: ", getMemoryManager());
                        data.currentNode += XalanDOMString(temp, getMemoryManager());
                        data.fail += 1;

                        retValue = false;
                    }
                }

                ++lineNum;
            }
        }
    }

    fclose(result);
    fclose(gold);

    return retValue;
}



/*  This routine performs a DOM Comparision. 
//  Inputs: 
//      gold - Dom tree for the expected results
//      doc  - Dom tree created during transformation
//      filename - Current filename
//      
//  Returns: 
//      True or False
//      
*/
bool 
XalanFileUtility::domCompare(
            const XalanNode&    gold,
            const XalanNode&    doc)
{
    const XalanNode::NodeType   docNodeType  = doc.getNodeType();
    const XalanNode::NodeType   goldNodeType = gold.getNodeType();

    const XalanDOMString&  docNodeName  = doc.getNodeName();    

    if (goldNodeType != docNodeType)
    {
        collectData(
            "NodeType mismatch.",
            docNodeName,
            XalanDOMString(xalanNodeTypes[docNodeType], getMemoryManager()),
            XalanDOMString(xalanNodeTypes[goldNodeType], getMemoryManager()));

        return false;
    }

    switch (goldNodeType)
    {
    case XalanNode::ELEMENT_NODE:   // ATTRIBUTE_NODEs are processed with diffElement().
        { 
            if (diffElement(gold, doc) == false) 
            {
                return false;
            }
        }
        break;

    case XalanNode::CDATA_SECTION_NODE:
    case XalanNode::TEXT_NODE:  
        {
            const XalanDOMString&   docNodeValue  = doc.getNodeValue();
            const XalanDOMString&   goldNodeValue = gold.getNodeValue();
            
            //debugNodeData(docNodeName, docNodeValue);
            
            if(goldNodeValue != docNodeValue)
            {
                collectData(
                    "Text node mismatch. ", 
                    docNodeName,
                    goldNodeValue,
                    docNodeValue);

                return false;
            }
        }
        break;

    case XalanNode::PROCESSING_INSTRUCTION_NODE:
        {
            const XalanDOMString&  goldNodeName = gold.getNodeName();

            if (goldNodeName != docNodeName)
            {
                collectData(
                    "processing-instruction target mismatch. ", 
                    docNodeName,
                    goldNodeName,
                    docNodeName);

                return false;
            }
            else
            {
                const XalanDOMString&   docNodeValue = doc.getNodeValue();
                const XalanDOMString&   goldNodeValue = gold.getNodeValue();

                if (goldNodeValue != docNodeValue)
                {
                    collectData(
                        "processing-instruction data mismatch. ", 
                        docNodeName,
                        goldNodeValue,
                        docNodeValue);

                    return false;
                }
            }
        }
        break;

    case XalanNode::COMMENT_NODE:
        {
            const XalanDOMString&   docNodeValue = doc.getNodeValue();
            const XalanDOMString&   goldNodeValue = gold.getNodeValue();

            if (goldNodeValue != docNodeValue)
            {
                collectData(
                    "comment data mismatch. ", 
                    docNodeName,
                    goldNodeValue,
                    docNodeValue);

                return false;
            }
        }
        break;

    case XalanNode::DOCUMENT_NODE:
        {
            //debugNodeData(docNodeName);

            const XalanNode *goldNextNode;
            const XalanNode *domNextNode;

            goldNextNode = gold.getFirstChild();
            domNextNode = doc.getFirstChild();

            if (0 != goldNextNode)
            {
                if(domCompare(*goldNextNode,*domNextNode) == false)
                {
                    return false;
                }
            }
        }
        break;

    case XalanNode::ENTITY_REFERENCE_NODE:
    case XalanNode::ENTITY_NODE:
    case XalanNode::DOCUMENT_TYPE_NODE:
    case XalanNode::DOCUMENT_FRAGMENT_NODE:
    case XalanNode::NOTATION_NODE:
    default:
        cerr << "Unexpected node type: " << goldNodeType << endl;

        return false;
    }

    // Need to process siblings.  Children are processed in diffElement, since
    // only they can have children in the XPath data model.
    const XalanNode* const  goldNextNode = gold.getNextSibling();
    const XalanNode* const  domNextNode = doc.getNextSibling();

    if (0 != goldNextNode)
    {
        if (0 != domNextNode)
        {
            if (domCompare(*goldNextNode, *domNextNode) == false)
            {
                return false;
            }
        }
        else
        {
            collectData(
                "Missing sibling node. ", 
                docNodeName,
                goldNextNode->getNodeName(),
                goldNextNode->getNodeName());

            return false;
        }
    }
    else if (0 != domNextNode)
    {
        collectData(
            "Extra sibling node. ", 
            docNodeName,
            domNextNode->getNodeName(),
            domNextNode->getNodeName());

        return false;
    }

    return true;
}



bool 
XalanFileUtility::domCompare(
            const XalanDocument&    gold,
            const XalanDocument&    doc)
{
    const XalanNode*    theGoldPos = &gold;
    const XalanNode*    theDocPos = &doc;

    bool    fEqual = true;

    do
    {
        fEqual = diffNode(theGoldPos, theDocPos);

        if (fEqual == true)
        {
            assert(theGoldPos != 0 && theDocPos != 0);

            const XalanNode*    nextGoldNode = theGoldPos->getFirstChild();
            const XalanNode*    nextDocNode = theDocPos->getFirstChild();

            bool    fBreak = false;

            while(
                nextGoldNode == 0 &&
                nextDocNode == 0 &&
                fBreak == false)
            {
                // Move to the next sibling of each node,
                // since we would get here only if both have
                // no children.
                nextGoldNode = theGoldPos->getNextSibling();
                nextDocNode = theDocPos->getNextSibling();

                // If there is no next sibling, move up to the
                // parent.  If one, but not both, has a sibling,
                // we'll end up back at the top of the do/while
                // loop and the difference will be reported.
                if(0 == nextGoldNode && 0 == nextDocNode)
                {
                    theGoldPos = theGoldPos->getParentNode();
                    theDocPos = theDocPos->getParentNode();

                    // If the parent is null, then we've reached
                    // the end of the document.  Note that if we
                    // got here, then there must also be a parent
                    // node in the document we're verifying, so we
                    // could simply assert that theDocPos is either
                    // null if theGoldPos is null, or it is not-null
                    // if theGoldPos is not-null.
                    if(0 == theGoldPos)
                    {
                        nextGoldNode = theGoldPos;

                        fBreak = true;
                    }

                    if(0 == theDocPos)
                    {
                        nextDocNode = theDocPos;

                        fBreak = true;
                    }
                }
            }

            theGoldPos = nextGoldNode;
            theDocPos = nextDocNode;
        }
    } while((theGoldPos != 0 || theDocPos != 0) && fEqual == true);


    return fEqual;
}



bool
XalanFileUtility::diffNode(
            const XalanNode&    gold,
            const XalanNode&    doc)
{
    const XalanNode::NodeType   docNodeType  = doc.getNodeType();
    const XalanNode::NodeType   goldNodeType = gold.getNodeType();

    const XalanDOMString&  docNodeName  = doc.getNodeName();    

    if (goldNodeType != docNodeType)
    {
        collectData(
            "NodeType mismatch.",
            docNodeName,
            XalanDOMString(xalanNodeTypes[docNodeType], getMemoryManager()),
            XalanDOMString(xalanNodeTypes[goldNodeType], getMemoryManager()));

        return false;
    }

    switch (goldNodeType)
    {
    case XalanNode::ELEMENT_NODE:   // ATTRIBUTE_NODEs are processed with diffElement().
        return diffElement2(gold, doc);
        break;

    case XalanNode::CDATA_SECTION_NODE:
    case XalanNode::TEXT_NODE:  
        {
            const XalanDOMString&   docNodeValue  = doc.getNodeValue();
            const XalanDOMString&   goldNodeValue = gold.getNodeValue();
            
            //debugNodeData(docNodeName, docNodeValue);
            
            if(goldNodeValue != docNodeValue)
            {
                collectData(
                    "Text node mismatch. ",
                    docNodeName,
                    goldNodeValue,
                    docNodeValue);

                return false;
            }
        }
        break;

    case XalanNode::PROCESSING_INSTRUCTION_NODE:
        {
            const XalanDOMString&  goldNodeName  = gold.getNodeName();

            if (goldNodeName != docNodeName)
            {
                collectData(
                    "processing-instruction target mismatch. ", 
                    docNodeName,
                    goldNodeName,
                    docNodeName);

                return false;
            }
            else
            {
                const XalanDOMString&   docNodeValue  = doc.getNodeValue();
                const XalanDOMString&   goldNodeValue = gold.getNodeValue();

                if (goldNodeValue != docNodeValue)
                {
                    collectData(
                        "processing-instruction data mismatch. ", 
                        docNodeName,
                        goldNodeValue,
                        docNodeValue);

                    return false;
                }
            }
        }
        break;

    case XalanNode::COMMENT_NODE:
        {
            const XalanDOMString&   docNodeValue  = doc.getNodeValue();
            const XalanDOMString&   goldNodeValue = gold.getNodeValue();

            if (goldNodeValue != docNodeValue)
            {
                collectData(
                    "comment data mismatch. ", 
                    docNodeName,
                    goldNodeValue,
                    docNodeValue);

                return false;
            }
        }
        break;

    case XalanNode::DOCUMENT_NODE:
        break;

    case XalanNode::ENTITY_REFERENCE_NODE:
    case XalanNode::ENTITY_NODE:
    case XalanNode::DOCUMENT_TYPE_NODE:
    case XalanNode::DOCUMENT_FRAGMENT_NODE:
    case XalanNode::NOTATION_NODE:
    default:
        cerr << "Unexpected node type: " << goldNodeType << endl;

        return false;
    }

    return true;
}



bool
XalanFileUtility::diffNode(
            const XalanNode*    gold,
            const XalanNode*    doc)
{
    if (gold != 0 && doc != 0)
    {
        return diffNode(*gold, *doc);
    }
    else if (gold != 0)
    {
        const XalanNode* const  parent =
            gold->getParentNode();

        collectData(
            "Missing sibling node. ",
            parent == 0 ? s_emptyString : parent->getNodeName(),
            s_emptyString,
            gold->getNodeName());

        return false;
    }
    else
    {
        assert(doc != 0 && gold == 0);

        const XalanNode* const  parent =
            doc->getParentNode();

        collectData(
            "Extra sibling node. ", 
            parent == 0 ? s_emptyString : parent->getNodeName(),
            doc->getNodeName(),
            s_emptyString);

        return false;
    }
}



/*  This routine compares two element nodes. 
//  Inputs: 
//      gold - Dom tree for the expected results
//      doc  - Dom tree created during transformation
//      filename - Current filenam
//      
//  Returns: 
//      True or False
//                      
*/

bool
XalanFileUtility::diffElement(
            const XalanNode&    gold,
            const XalanNode&    doc)
{
    assert(gold.getNodeType() == XalanNode::ELEMENT_NODE);
    assert(gold.getNodeType() == XalanNode::ELEMENT_NODE);

    const XalanDOMString&  docNodeName  = doc.getNodeName();    
    const XalanDOMString&  goldNodeName = gold.getNodeName();

    const XalanDOMString&  docNsUri  = doc.getNamespaceURI();
    const XalanDOMString&  goldNsUri = gold.getNamespaceURI();

    //debugNodeData(docNodeName);

    // This essentially checks 2 things, that the prefix and localname are the
    // same.  So specific checks of these items are not necessary.
    if (goldNodeName != docNodeName)
    {
        collectData(
            "Element mismatch. ", 
            docNodeName,
            goldNodeName,
            docNodeName);

        return false;
    }

    if ( goldNsUri != docNsUri)
    {
        collectData(
            "Element NamespaceURI mismatch. ",
            docNodeName,
            goldNsUri,
            docNsUri);

        return false;
    }

    // Get Attributes for each Element Node. 
    const XalanNamedNodeMap* const  goldAttrs = gold.getAttributes();
    const XalanNamedNodeMap* const  docAttrs  = doc.getAttributes();

    // Get number of Attributes
    const XalanSize_t  numGoldAttr = goldAttrs->getLength();
    const XalanSize_t  numDomAttr  = docAttrs ->getLength();

    /*
    // This needs to be uncommented if 'compare.exe' is to work. 
    // If this is the 'root' element strip off the xmlns:xml namespace attribute,
    // that is lurking around on the gold file, but not the dom.  This is necessary
    // only for the 'compare' test, that uses a pure DOM, that has not been serialized.
    //if (goldNodeName == XalanDOMString("root"))
    {
        numGoldAttr -= 1;
        XalanNode *gXMLAttr = goldAttrs->item(1);
    }
    */
    // Check that each Element has same number of Attributes. If they don't report error  
    if ( numGoldAttr == numDomAttr )
    {
        // Compare Attributes one at a time.
        for (XalanSize_t i = 0; i < numGoldAttr; ++i)
        {
            // Attribute order is irrelvant, so comparision is base on Attribute name.
            const XalanNode* const  gAttr = goldAttrs->item(i);
            const XalanDOMString&   goldAttrName = gAttr->getNodeName();

            const XalanNode* const  dAttr = docAttrs->getNamedItem(goldAttrName);

            if (dAttr != 0)
            {
                if( ! (diffAttr(gAttr, dAttr)) )
                    return false;
            }
            else
            {
                collectData(
                    "Element missing named Attribute. ",
                    docNodeName,
                    goldAttrName,
                    XalanDOMString("NOTHING", getMemoryManager()));

                return false;
            }
        }
    }
    else
    {
        XalanDOMString  numGoldStr(getMemoryManager());
        XalanDOMString  numDOMStr(getMemoryManager());

        collectData(
            "Wrong number of attributes. ",
            docNodeName,
            NumberToDOMString(static_cast<XMLUInt64>(numGoldAttr), numGoldStr),
            NumberToDOMString(static_cast<XMLUInt64>(numDomAttr), numDOMStr));

        return false;
    }

    const XalanNode*    goldNextNode = gold.getFirstChild();
    const XalanNode*    domNextNode = doc.getFirstChild();

    if (0 != goldNextNode)
    {
        if (0 != domNextNode)
        {
            if ( ! domCompare(*goldNextNode, *domNextNode) )
                return false;
        }
        else
        {
            collectData(
                "Element missing ChildNode. ", 
                docNodeName,
                XalanDOMString(goldNextNode->getNodeName(), getMemoryManager()),
                XalanDOMString("NOTHING", getMemoryManager()));

            return false;
        }
    }
    else if (domNextNode != 0)
    {
        // The result doc has additional Children. If the additional node is a text node
        // then gather up the text and print it out.
        if ( domNextNode->getNodeType() == XalanNode::TEXT_NODE)
        {
            collectData(
                "Result has additional Child node: ", 
                docNodeName,
                XalanDOMString("NOTHING", getMemoryManager()),       
                XalanDOMString(domNextNode->getNodeName(), getMemoryManager()).append(XalanDOMString("  \"", getMemoryManager()).append(
                XalanDOMString(domNextNode->getNodeValue(), getMemoryManager()).append(XalanDOMString("\"", getMemoryManager())))));
        }
        // Additional node is NOT text, so just print it's Name.
        else
        {
            collectData(
                "Result has additional Child node: ",
                docNodeName,
                XalanDOMString("NOTHING", getMemoryManager()),
                XalanDOMString(domNextNode->getNodeName(), getMemoryManager()));

        }

        return false;
    }

    return true;
}


bool
XalanFileUtility::diffElement2(
            const XalanNode&    gold,
            const XalanNode&    doc)
{
    assert(gold.getNodeType() == XalanNode::ELEMENT_NODE);
    assert(gold.getNodeType() == XalanNode::ELEMENT_NODE);

    const XalanDOMString&  docNodeName  = doc.getNodeName();    
    const XalanDOMString&  goldNodeName = gold.getNodeName();

    const XalanDOMString&  docNsUri  = doc.getNamespaceURI();
    const XalanDOMString&  goldNsUri = gold.getNamespaceURI();

    //debugNodeData(docNodeName);

    // This essentially checks 2 things, that the prefix and localname are the
    // same.  So specific checks of these items are not necessary.
    if (goldNodeName != docNodeName)
    {
        collectData(
            "Element mismatch. ", 
            docNodeName,
            goldNodeName,
            docNodeName);

        return false;
    }

    if ( goldNsUri != docNsUri)
    {
        collectData(
            "Element NamespaceURI mismatch. ",
            docNodeName,
            goldNsUri,
            docNsUri);

        return false;
    }

    // Get Attributes for each Element Node. 
    const XalanNamedNodeMap* const  goldAttrs = gold.getAttributes();
    assert(goldAttrs != 0);

    const XalanNamedNodeMap* const  docAttrs  = doc.getAttributes();
    assert(docAttrs != 0);

    // Get number of Attributes
    const XalanSize_t  numGoldAttr = goldAttrs->getLength();
    const XalanSize_t  numDomAttr  = docAttrs ->getLength();

    // Check that each Element has same number of Attributes. If they don't report error  
    if ( numGoldAttr == numDomAttr )
    {
        // Compare Attributes one at a time.
        for (XalanSize_t i = 0; i < numGoldAttr; ++i)
        {
            // Attribute order is irrelevant, so comparision is base on Attribute name.
            const XalanNode* const  gAttr = goldAttrs->item(i);
            const XalanDOMString&   goldAttrName = gAttr->getNodeName();

            const XalanNode* const  dAttr = docAttrs->getNamedItem(goldAttrName);

            if (dAttr != 0)
            {
                if( ! (diffAttr(gAttr, dAttr)) )
                    return false;
            }
            else
            {
                collectData(
                    "Element missing named Attribute. ",
                    docNodeName,
                    goldAttrName,
                    XalanDOMString("NOTHING", getMemoryManager()));

                return false;
            }
        }
    }
    else
    {
        XalanDOMString  numGoldStr(getMemoryManager());
        XalanDOMString  numDOMStr(getMemoryManager());

        collectData(
            "Wrong number of attributes. ",
            docNodeName,
            NumberToDOMString(static_cast<XMLUInt64>(numGoldAttr), numGoldStr),
            NumberToDOMString(static_cast<XMLUInt64>(numDomAttr), numDOMStr));

        return false;
    }

    return true;
}


/*  This routine compares two attribute nodes. 
//  Inputs: 
//      gAttr - attribute from Gold dom tree 
//      dAttr - attribute from Dom tree created during transformation
//      fileName - Current filenam
//      
//  Returns: 
//      True or False
//              
*/

bool XalanFileUtility::diffAttr(const XalanNode* gAttr, const XalanNode* dAttr)
{

    const XalanDOMString&   docAttrName  = dAttr->getNodeName();

    //debugAttributeData(goldAttrName);

    const XalanDOMString&   goldAttrValue = gAttr->getNodeValue();
    const XalanDOMString&   docAttrValue    = dAttr->getNodeValue();

    if (goldAttrValue != docAttrValue)
    {
        collectData(
            "Attribute Value mismatch. ",
            docAttrName,
            goldAttrValue,
            docAttrValue);

        return false;
    }

    const XalanDOMString&   goldAttrNsUri = gAttr->getNamespaceURI();
    const XalanDOMString&   docAttrNsUri    = dAttr->getNamespaceURI();

    if (goldAttrNsUri != docAttrNsUri)
    {
        collectData(
            "Attribute NamespaceURI mismatch. ", 
            docAttrName,
            goldAttrNsUri,
            docAttrNsUri);

        return false;
    }

    return true;
}

/*  This routine reports DOM comparison errors. 
//  Inputs: 
//      file    -   Name of current file
//      node    -   Current node that fails
//      msg     -   Failure message
//
*/
void
XalanFileUtility::reportError()
{

    cout << endl
         << "* Failed "
         << data.testOrFile
         << "  Error: "
         << data.msg
         << endl
         << "   "
         << "Processing Node: "
         << data.currentNode
         << endl
         << "   Expected:   "
         << data.expected
         << endl
         << "   Actual:     "
         << data.actual
         << endl
         << endl;
}


void
XalanFileUtility::debugNodeData(const XalanDOMString&    value)
{
    CharVectorType     valueVec(getMemoryManager());

    TranscodeToLocalCodePage(value, valueVec, true);

    cout << "Node is: " << c_str(valueVec) << endl;
}



void
XalanFileUtility::debugNodeData(
            const XalanDOMString&   node,
            const XalanDOMString&   value)
{
    CharVectorType     valueVec(getMemoryManager());
    TranscodeToLocalCodePage(value, valueVec, true);

    CharVectorType     nodeVec(getMemoryManager());
    TranscodeToLocalCodePage(node, nodeVec, true);

    cout << "Node is: " << c_str(nodeVec) << "   "
         << "Value is: \"" << c_str(valueVec) << "\"\n";
}



void
XalanFileUtility::debugAttributeData(const XalanDOMString&   value)
{
    CharVectorType      theTargetVector(getMemoryManager());

    TranscodeToLocalCodePage(value, theTargetVector, true);

    cout << "Attribute is: " << c_str(theTargetVector) << endl;
}


/*  This routine collects up data pertinent to a dom comparison failure. 
//  Inputs: 
//      errmsg:         Reason for the failure.
//      currentnode:    Node in the dom tree where the mismatch occured
//      expdata:        Expected data based on the Gold file.
//      actdata:        Actual data returned in the result file.
//  Returns: Void                       
*/
void 
XalanFileUtility::collectData(
            const char*             errmsg,
            const XalanDOMString&   currentnode,
            const XalanDOMString&   expdata,
            const XalanDOMString&   actdata)
{
    data.msg = errmsg;
    data.currentNode = currentnode;
    data.expected = expdata;
    data.actual = actdata;
    data.fail += 1;
}


/*  Routine prints the result to the console, as well as adds summary info into the logfile. 
//  Inputs: 
//      logfile:    Current log file
//      runid:      Unique runid
//  Returns: Void                       
*/
void
XalanFileUtility::reportPassFail(
            XalanXMLFileReporter&   logfile,
            const XalanDOMString&   runid)
{
    typedef XalanXMLFileReporter::Hashtable  Hashtable;

    Hashtable   runResults(getMemoryManager());

    char temp[10];

    // Create entrys that contain runid, xerces version, and numbers for Pass, Fail and No Gold.

    XalanDOMString theBuffer(getMemoryManager());

    runResults.insert(
        XalanDOMString("UniqRunid", getMemoryManager()),
        runid);

    runResults.insert(
        XalanDOMString("Xerces-Version ", getMemoryManager()),
        getXercesVersion(theBuffer));

    runResults.insert(
        XalanDOMString("BaseDrive ", getMemoryManager()), 
        XalanDOMString(getDrive(theBuffer), getMemoryManager()));

    runResults.insert(
        XalanDOMString("TestBase ", getMemoryManager()),
        XalanDOMString(args.base, getMemoryManager()));

    runResults.insert(
        XalanDOMString("xmlFormat ", getMemoryManager()),
        data.xmlFormat);

    sprintf(temp, "%ld", args.iters);

    runResults.insert(
        XalanDOMString("Iters ", getMemoryManager()),
        XalanDOMString(temp, getMemoryManager()));

    sprintf(temp, "%d", data.pass);

    runResults.insert(
        XalanDOMString("Passed", getMemoryManager()),
        XalanDOMString(temp, getMemoryManager()));
    
    sprintf(temp, "%d", data.fail);

    runResults.insert(
        XalanDOMString("Failed", getMemoryManager()),
        XalanDOMString(temp, getMemoryManager()));

    sprintf(temp, "%d", data.nogold);

    runResults.insert(
        XalanDOMString("No_Gold_Files", getMemoryManager()),
        XalanDOMString(temp, getMemoryManager()));

    logfile.logElementWAttrs(10, "RunResults", runResults, "xxx");  

    cout << "\nPassed " << data.pass;
    cout << "\nFailed " << data.fail;
    cout << "\nMissing Gold " << data.nogold << endl;

}

/*  Routine runs a stylesheet on the log file and displays the results in HTML. 
//  Inputs: 
//      xalan:          An instance of the transformer
//      resultsFile:    logfile 
//  Returns: Void                       
*/
void
XalanFileUtility::analyzeResults(XalanTransformer& xalan, const XalanDOMString& resultsFile)
{
    XalanDOMString paramValue(getMemoryManager());

    bool    fileStatus;

#if defined(AIX) || defined(SOLARIS) || defined(LINUX) || defined(HPUX)

    bool    pathStatus;
    CharVectorType     withPath(getMemoryManager());
    TranscodeToLocalCodePage(resultsFile, withPath, false);
    if (withPath[0] == '/')
        pathStatus=true;
    else
        pathStatus=false;
    
    char buffer5[PATH_MAX];
    XalanDOMString resultPath(getcwd(buffer5, PATH_MAX), getMemoryManager());
    append(resultPath, s_pathSep);
#endif
    

    // Pass the results .xml file as a parameter to the stylesheet.  It must be wrapped in single
    // quotes so that it is not considered an expression.
    //
  #if defined (AIX) || defined(SOLARIS) || defined(LINUX) || defined(HPUX)
    paramValue.assign(XalanDOMString("\'", getMemoryManager()));
    if ( !pathStatus )
        paramValue.append(resultPath);
    paramValue.append(resultsFile);
    paramValue.append(XalanDOMString("\'", getMemoryManager()));
  #else 
    paramValue.assign(XalanDOMString("'", getMemoryManager()));
    paramValue.append(resultsFile);
    paramValue.append(XalanDOMString("'", getMemoryManager()));
  #endif

    // Set the parameter
    //
    xalan.setStylesheetParam(
        XalanDOMString("testfile", getMemoryManager()),
        paramValue);

    // Generate the input and output file names.
    //
    XalanDOMString  theHTMLFile(getMemoryManager());
    generateFileName(resultsFile,"html", theHTMLFile, &fileStatus);
    
    XalanDOMString  theStylesheet(getMemoryManager());
    theStylesheet += args.base;
    theStylesheet += XalanDOMString("cconf.xsl", getMemoryManager());

    XalanDOMString  theXMLSource(getMemoryManager());
    theXMLSource += args.base;
    theXMLSource += XalanDOMString("cconf.xml", getMemoryManager());

    // Check that we can find the stylesheet to analyze the results.
    //
    CharVectorType theBuffer(getMemoryManager());
    TranscodeToLocalCodePage(theStylesheet, theBuffer, true);
    FILE* fileHandle = fopen(c_str(theBuffer), "r");
    if (fileHandle == 0)
    {
        cout << "ANALYSIS ERROR: File Missing: " << c_str(theBuffer) << endl;
        return;
    }
    else
    {
        fclose(fileHandle);
    }

    // Create the InputSources and ResultTarget.
    const XSLTInputSource   xslInputSource(theStylesheet, getMemoryManager());
    const XSLTInputSource   xmlInputSource(theXMLSource, getMemoryManager());
    const XSLTResultTarget  resultFile(theHTMLFile, getMemoryManager());

    // Do the transform, display the output HTML, or report any failure.
    const int   result = xalan.transform(xmlInputSource, xslInputSource, resultFile);

    if (result == 0)
    {
#if defined(XALAN_WINDOWS)
        CharVectorType theBuffer(getMemoryManager());
        TranscodeToLocalCodePage(theHTMLFile, theBuffer, true);

        // system(c_str(theBuffer));
#else
        cout << "The HTML output: " << theHTMLFile << " was created" << endl;
#endif
    }
    else 
    {
        cout << "Analysis failed due to following error: "
             << xalan.getLastError()
             << endl;
    }   
}



const XalanDOMChar  XalanFileUtility::s_xmlSuffix[] =
{
    XalanUnicode::charFullStop,
    XalanUnicode::charLetter_x,
    XalanUnicode::charLetter_m,
    XalanUnicode::charLetter_l,
    0
};

const XalanDOMChar  XalanFileUtility::s_pathSep[] =
{
#if defined(XALAN_WINDOWS)
    XalanUnicode::charReverseSolidus,
#else
    XalanUnicode::charSolidus,
#endif
    0
};



}
