/** @name resmgr.cpp
-----------------------------------------------------------------------------

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

-----------------------------------------------------------------------------

   Description: This file contains class {\tt ResourceManager}.
                Note: code parts which should be made thread-safe
                      are marked with "mutex" (suhre)

-----------------------------------------------------------------------------


-------------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Interface dependencies                                            */
/* ----------------------------------------------------------------------- */
//#define DEBUG_VERBOSE
#include "uima/resmgr.hpp"
#include "apr.h"

/* ----------------------------------------------------------------------- */
/*       Implementation dependencies                                       */
/* ----------------------------------------------------------------------- */
#if (__GNUC__ < 3)
#include <clocale>
#else
#include <locale>
#endif

#if defined(_MSC_VER)
int rc = _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
// Send all reports to STDOUT
int rc1 =   _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
_HFILE h1 =  _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
int rc3 =   _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_HFILE h2 = _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
int rc5 =   _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_HFILE h3 = _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
#endif

#include <jni.h>
#include "uima/envvar.hpp"
#include "uima/trace.hpp"
#include "uima/dirwalk.hpp"
#include "uima/dllfile.hpp"

#include "uima/macros.h"
#include "uima/comp_ids.h"
#include "uima/res_abase.hpp"
#include "uima/res_annotator.hpp"
#include "uima/envvars.h"
#include "uima/exceptions.hpp"
#include "uima/language.hpp"
#include "uima/msg.h"
#include "uima/msgstrtab.h"
#include "uima/casexception.hpp"

#include "xercesc/util/PlatformUtils.hpp"
#include "unicode/uclean.h"
#include "uima/stltools.hpp"

/* ----------------------------------------------------------------------- */
/*       Constants                                                         */
/* ----------------------------------------------------------------------- */

#define JAVA_PROXY "org/apache/uima/uimacpp/UimacppAnalysisComponent"

#ifndef UIMA_VERSION
#error UIMA_VERSION must be defined in the compilation environment
#endif

/* max. number of characters in a valid filename for shipment */
const size_t UIMA_MAX_VALID_FILENAME_SIZE = 8;   /* DOS 8+3 */

XERCES_CPP_NAMESPACE_USE

/* ----------------------------------------------------------------------- */
/*       Types / Classes                                                   */
/* ----------------------------------------------------------------------- */
using namespace std;
namespace uima {

  /*
   * The class ResourceManagerAutomaticInstanceDestructor is used to call method
   * ResourceManager::deleteInstance().
   * There needs to be one instance of ResourceManagerAutomaticInstanceDestructor
   * for which the destructor will be called whenever the DLL goes out of scope.
   * This destructor will then call ResourceManager::deleteInstance()
   * automatically shutting down the resource manager.
   */
  class ResourceManagerAutomaticInstanceDestructor {
  public:
    ResourceManagerAutomaticInstanceDestructor(void) {
      ; /* do nothing */
      UIMA_TPRINT(_TEXT("INIT ..."));
    }
    ~ResourceManagerAutomaticInstanceDestructor(void) {
      UIMA_TPRINT(_TEXT("deleting ResourceManagerInstance ..."));
      ResourceManager::deleteInstance();
    }
  }
  ; /* ResourceManagerAutomaticInstanceDestructor */

  /* ----------------------------------------------------------------------- */
  /*       Globals                                                           */
  /* ----------------------------------------------------------------------- */
  

  ResourceManager * ResourceManager::cv_pclSingletonInstance = 0;
  TyProcedure               iv_traceProc;

  /* see docu for class ResourceManagerAutomaticInstanceDestructor above */
  static ResourceManagerAutomaticInstanceDestructor gs_clResourceManagerAutomaticInstanceDestructor;

  /* ----------------------------------------------------------------------- */
  /*       Function declarations                                             */
  /* ----------------------------------------------------------------------- */

  /* ----------------------------------------------------------------------- */
  /*       Macro definitions                                                 */
  /* ----------------------------------------------------------------------- */

  /* ----------------------------------------------------------------------- */
  /*       Private implementation                                            */
  /* ----------------------------------------------------------------------- */

  ResourceManager::ResourceManager(const TCHAR * cpszInstance, const TCHAR * cpszProductPrefix) :
      iv_utLastErrorId(UIMA_ERR_NONE),
      iv_locationWork("."),
      iv_locationData("."),
      iv_frameworkLogger(NULL),
      iv_logLevel(LogStream::EnMessage),
      iv_fileLogger(NULL),
      iv_loggers()
      /* ----------------------------------------------------------------------- */
  {
    
    string                    str;

    assert(EXISTS(cpszInstance));
    UIMA_TPRINT(_TEXT("instance: ") << cpszInstance);

    /* set the product prefix -- dropped this code */

    /* after the trace instance has been created and enabled,
       we may instantiate a first trace object */
    util::Trace                 clTrace(util::enTraceDetailLow, UIMA_TRACE_ORIGIN, UIMA_TRACE_COMPID_RESOURCE_MGR);
    clTrace.dump(_TEXT("UIMACPP Instance"), cpszInstance);

    /* determine xsd path ... use $UIMACPP_HOME/data instead of iv_locationData
       (which defaults to $UIMACPP_DATAPATH) as the latter is for user data. */
    bDoSchemaValidation=true;
    str = UIMA_ENVVAR_HOME;
    util::EnvironmentVariableQueryOnly clEnvVarSchemaPath(str.c_str());
    UIMA_TPRINT(_TEXT("querying envvar: ") << str.c_str());
    schemaInfo[0] = '\0';                   // Play safe
    if (clEnvVarSchemaPath.hasValue()) {
      string schemaloc = clEnvVarSchemaPath.getValue();
      UIMA_TPRINT(_TEXT("value: ") << schemaloc);
      schemaloc += "/data";

      // Create full name & transform path to absolute s.t. the XML parser can handle it
      util::Filename schemaFilename(schemaloc.c_str(),UIMA_XSD_FILENAME);
      schemaFilename.normalizeAbsolute();
      bIsSchemaAvailable = schemaFilename.isExistent();

      // schema filename must not contain blanks as the parser schemaLocation
      // attribute is a blank-separated pair of strings
      if (bIsSchemaAvailable) {
        icu::UnicodeString schemaPath(schemaFilename.getAsCString());
        schemaPath.findAndReplace(" ", "%20");
        int len = strlen(UIMA_XML_NAMESPACE);
        memcpy(schemaInfo, UIMA_XML_NAMESPACE, len);
        schemaInfo[len] = ' ';
        schemaPath.extract(0, schemaPath.length(), schemaInfo+len+1, "UTF-8");
      }
    } else {
      bIsSchemaAvailable = false;
    }

    /* determine data path */
    str = UIMA_ENVVAR_SUFFIX_DATAPATH;
    util::EnvironmentVariableQueryOnly clEnvVarDataPath(str.c_str());
    UIMA_TPRINT(_TEXT("querying envvar: ") << str.c_str());
    if (clEnvVarDataPath.hasValue()) {
      iv_locationData = util::Location(clEnvVarDataPath.getValue());
    } else {
      iv_locationData = util::Location(".");
    }
    assert(EXISTS(iv_locationData));
    UIMA_TPRINT(_TEXT("value: ") << iv_locationData);

    /* determine work path */
    str = UIMA_ENVVAR_SUFFIX_WORKPATH;
    util::EnvironmentVariableQueryOnly clEnvVarWorkPath(str.c_str());
    UIMA_TPRINT(_TEXT("querying envvar: ") << str.c_str());
    if (clEnvVarWorkPath.hasValue()) {
      iv_locationWork = util::Location(clEnvVarWorkPath.getValue());
    } else {
      iv_locationWork = util::Location();                   // TMP directory
    }
    assert(EXISTS(iv_locationWork));
    UIMA_TPRINT(_TEXT("value: ") << iv_locationWork);

    /* determine iv_bIgnoreAnnotatorPathSpec flag */       // ** Dropped this

    // we must make sure real values our ini files are read with . (e.g. "0.5")
    setlocale(LC_NUMERIC, "C");

    UIMA_TPRINT(_TEXT("workpath: ") << (const char*)iv_locationWork);
    UIMA_TPRINT(_TEXT("datapath: ") << (const char*)iv_locationData);
    clTrace.dump(_TEXT("Work path"), iv_locationWork.getAsCString());
    clTrace.dump(_TEXT("Data path"), iv_locationData.getAsCString());

#ifndef NDEBUG
    /* check whether the message string table apepars correct and consistent */
    ErrorMessage                clMsgSig1(UIMA_MSG_ID_SIGNATURE_BEGIN);
    ErrorMessage                clMsgSig2(UIMA_MSG_ID_SIGNATURE_END);

    /* the signatures at the start and end must match! */
    if (strcmp(clMsgSig1.asString().c_str(), clMsgSig2.asString().c_str()) != 0) {
      cerr << "Internal build error"
      << "String table in uima/msgstrtab.h is inconsistent!" << endl
      << "Signature Id BEGIN: " << clMsgSig1.getMessageID() << endl
      << "   Found message: "   << clMsgSig1 << endl
      << "Signature Id END: "   << clMsgSig2.getMessageID() << endl
      << "   Found message:"    << clMsgSig2 << endl;
      assert(false);
    }
#endif

    //read environement setting to register Sofa Stream handlers
    //mappings are specified as:
    //         UIMACPP_STREAMHANDLERS=urischeme:dllfilename urischeme2:dllfilename2
    str = UIMA_ENVVAR_SOFA_STREAM_HANDLERS;
    util::EnvironmentVariableQueryOnly clEnvVarStreamHandlers(str.c_str());
    UIMA_TPRINT(_TEXT("querying envvar: ") << str.c_str());
    TCHAR *  cpszURIToStreamHandlerMap=0;
    if (clEnvVarStreamHandlers.hasValue()) {
      cpszURIToStreamHandlerMap = (TCHAR*) clEnvVarStreamHandlers.getValue();
      assert(EXISTS(cpszURIToStreamHandlerMap));
      UIMA_TPRINT(_TEXT("value: ") << cpszURIToStreamHandlerMap);

      TCHAR * urischeme =0;
      TCHAR * handlerdllfilename=0;

      TCHAR * curptr = cpszURIToStreamHandlerMap;
      TCHAR * chptr  = 0;

      //parse string to get each uri:dllfilename pair ... separated by one or more spaces
      while (curptr != NULL) {
        while (*curptr == ' ')
          ++curptr;
        chptr = strchr(curptr, ':');

        int len = chptr - curptr;
        if (len > 0) {
          //get the uri scheme
          urischeme = new char[len+1];
          strncpy(urischeme, curptr, len);
          urischeme[len]='\0';

          curptr = chptr+1;
          chptr = strchr(curptr, ' ');
          if (chptr == NULL)
            len =  strlen(curptr);
          else
            len = chptr - curptr;

          //get dll and register
          if (len > 0) {
            handlerdllfilename = new char[len+1];
            strncpy(handlerdllfilename,curptr, len);
            handlerdllfilename[len]='\0';
            registerStreamHandlerForURIScheme(urischeme, handlerdllfilename);
            delete [] handlerdllfilename;
          }
          delete [] urischeme;
        }

        //move ptr
        if (chptr==NULL)
          curptr=chptr;
        else
          curptr = chptr+1;
      }  //while
    } //if

    //register the Sofa Data Stream Handler for the 'file' URI scheme
    //registerStreamHandlerForURIScheme("file", "sofafilestreamhandler");
  }


  void ResourceManager::deleteResourceList( TyResourceList & rResList) {
    int i;
    for (i=rResList.size()-1; i>=0 ;--i) {
      ResourceABase * rResource = rResList[i];
      UIMA_TPRINT("   deleting resource " << i << ": " << rResource);
      assert( EXISTS(rResource) );
      UIMA_TPRINT("       key: " << rResource->getKey() );
      UIMA_TPRINT("  de-initing resource");
      rResource->deInit();
      assert( EXISTS(rResource) );
      delete rResource;
      rResList[i] = NULL;
      UIMA_TPRINT("   done");
    }
  }


  /* ----------------------------------------------------------------------- */
  /*       Protected implementation                                          */
  /* ----------------------------------------------------------------------- */

  /* ----------------------------------------------------------------------- */
  /*       Public implementation                                             */
  /* ----------------------------------------------------------------------- */

  ResourceManager::~ResourceManager(void)
  /* ----------------------------------------------------------------------- */
  {
    UIMA_TPRINT("Searching...");
    // it is important that annotators are deInited (unloaded)
    // last due to the following scenario:
    // a annotator p derives a class from ResourceABase, the class definition
    // is thus only valid during the lifetime in p. However, all resources
    // are handled by the resource manager. After the annotator is unloaded
    // the virtual function table of the resource is destroyed
    // (MS .NET and MSVC++6), thus the deInit() call fails.

    // use this factory just to get the kind string
    internal::ResourceAnnotatorFileFactory annotatorFactory;
    icu::UnicodeString const & crAnnotatorKind = annotatorFactory.getKind();

    TyResourceList * pAnnotators = NULL;

    TyResources::iterator it;
    for (it = iv_resources.begin(); it != iv_resources.end(); ++it) {
      TyResourceList & rResList = (*it).second;
      UIMA_TPRINT("Deleting all resources with kind: " << (*it).first);
      if ( (*it).first == crAnnotatorKind ) {
        assert( pAnnotators == NULL );
        pAnnotators = & rResList;
      } else {
        deleteResourceList( rResList );
      }
    }

    TyURIStreamHandlers::iterator ite;
    for (ite = iv_streamhandlers.begin(); ite != iv_streamhandlers.end(); ++ite) {
      util::Filename * pDllFile = (util::Filename *) (*ite).second;
      UIMA_TPRINT("Deleting stream handler dll file for uri scheme: " << (*ite).first);
      delete pDllFile;
    }


    // unload annotators at last, if any
    if (pAnnotators != NULL) {
      deleteResourceList( *pAnnotators );
    }
    iv_resources.clear();

    UIMA_TPRINT("  ...seek and destroy!");
  }

  const util::Location & ResourceManager::getLocationWork(void) const
  /* ----------------------------------------------------------------------- */
  {
    assert(iv_utLastErrorId != UIMA_ERR_RESMGR_OUT_OF_MEMORY );
    return iv_locationWork;
  }

  const util::Location & ResourceManager::getLocationData(void) const
  /* ----------------------------------------------------------------------- */
  {
    assert(iv_utLastErrorId != UIMA_ERR_RESMGR_OUT_OF_MEMORY );
    return iv_locationData;
  }

  void ResourceManager::setNewLocationWork(const util::Location & crclLocation)
  /* ----------------------------------------------------------------------- */
  {
    util::Trace                 clTrace(util::enTraceDetailLow, UIMA_TRACE_ORIGIN, UIMA_TRACE_COMPID_RESOURCE_MGR);

    assert(iv_utLastErrorId != UIMA_ERR_RESMGR_OUT_OF_MEMORY );
    clTrace.dump(_TEXT("New work path"), crclLocation.getAsCString());
    iv_locationWork = crclLocation;
  }

  void ResourceManager::setNewLocationData(const util::Location & crclLocation)
  /* ----------------------------------------------------------------------- */
  {
    util::Trace                 clTrace(util::enTraceDetailLow, UIMA_TRACE_ORIGIN, UIMA_TRACE_COMPID_RESOURCE_MGR);

    assert(iv_utLastErrorId != UIMA_ERR_RESMGR_OUT_OF_MEMORY );
    clTrace.dump(_TEXT("New data path"), crclLocation.getAsCString());
    iv_locationData = crclLocation;
  }

  util::DllProcLoaderFile * ResourceManager::requestAnnotatorFile(const util::Filename & crclFilename)
  /* ----------------------------------------------------------------------- */
  {
    internal::ResourceAnnotatorFileFactory factory;

    icu::UnicodeString us( crclFilename.getAsCString() );
    uima::ErrorInfo errInfo;
    internal::ResourceAnnotatorFile const * cpResAnnotatorFile = (internal::ResourceAnnotatorFile const *) getResource( us, factory, errInfo);
	if (errInfo.getErrorId()==UIMA_ERR_NONE && EXISTS(cpResAnnotatorFile)) {
      return cpResAnnotatorFile->getAnnotatorFile();
	} else {
		std::string err = "ResourceManager::requestAnnotatorFile() failed to find ";
        err += crclFilename;
        ResourceManager::getInstance().getLogger().logError(err);
        UIMA_EXC_THROW_NEW(Uima_runtime_error,
                              errInfo.getErrorId(),
                              errInfo.getMessage(),
                              errInfo.getMessage().getMessageID(),
                              ErrorInfo::unrecoverable);
	}
  }

  ResourceABase const * ResourceManager::getResource(uima::Language const & crLang,
      ResourceFactoryABase const & crFactory,
      ErrorInfo & rErrInfo) {
    icu::UnicodeString us( crLang.asString().c_str() );
    return getResource(us, crFactory, rErrInfo);
  }

  ResourceABase const * ResourceManager::getResource(icu::UnicodeString const & crKey,
      ResourceFactoryABase const & crFactory,
      uima::ErrorInfo & rErrInfo) {
//      assertWithMsg(false, "Implement caching functionality");
    icu::UnicodeString const & crKind = crFactory.getKind();
    UIMA_TPRINT("Creating resource with kind " << crKind << " and key " << crKey);
    // acquire mutex lock

    TyResourceList & rResList = iv_resources[crKind];
    ResourceABase * pResource = NULL;

    TyResourceList::const_iterator cit;
    for (cit = rResList.begin(); cit != rResList.end(); ++cit) {
      if ( (*cit)->getKey() == crKey ) {
        pResource = *cit;
        break;
      }
    }
    // if the resource was not found
    if (pResource == NULL) {
      pResource = crFactory.createResource( crKey );
      pResource->init(rErrInfo);
      if (rErrInfo.getErrorId() != UIMA_ERR_NONE) {
        delete pResource;
        return NULL;
      }
      rResList.push_back(pResource);
    }
    // release mutex lock
    UIMA_TPRINT("...resource created: " << pResource);
    assert( EXISTS( pResource ) );
    return pResource;

  }

  void ResourceManager::enableSchemaValidation(bool aEnable) {
    bDoSchemaValidation=aEnable;
  }

  bool ResourceManager::doSchemaValidation() {
    return bDoSchemaValidation;
  }

  bool  ResourceManager::isSchemaAvailable() {
    return bIsSchemaAvailable;
  }

  LogStream::EnEntryType  ResourceManager::getLoggingLevel() {
    return iv_logLevel;
  }

  void ResourceManager::setLoggingLevel(LogStream::EnEntryType level) {
    iv_logLevel=level;
  }

  TCHAR const *  ResourceManager::getSchemaInfo() {
    return schemaInfo;
  }

  void ResourceManager::registerLogger(Logger * pLogger) {
 	iv_loggers.push_back(pLogger);
  }

  vector<Logger*> & ResourceManager::getLoggers() {
 	return iv_loggers;
  }
  
  void ResourceManager::unregisterLogger(Logger * pLogger) {
      vector<Logger*>::iterator iter;
 	for (iter=iv_loggers.begin(); iter  != iv_loggers.end();iter++) {
  		if (*iter == pLogger) {
		    iv_loggers.erase(iter);
                return;
            }
      }
 	
      string str = "Logger not found. Could not unregister.";
      UIMA_EXC_THROW_NEW(Uima_runtime_error,
                  UIMA_MSG_ID_LITERAL_STRING,
                  UIMA_MSG_ID_LITERAL_STRING,
                  ErrorMessage(UIMA_MSG_ID_LITERAL_STRING, str.c_str()),
                  ErrorInfo::unrecoverable);

  }


  void ResourceManager::registerFactory(icu::UnicodeString const & crKind, ResourceFactoryABase & crFactory) {
    iv_resourceFactories.insert(TyResourceFactories::value_type(crKind, &crFactory));
  }

  void ResourceManager::deRegisterFactory(icu::UnicodeString const & crKind, ResourceFactoryABase & crFactory) {
    TyResourceFactories::iterator it = iv_resourceFactories.find(crKind);
    if (it != iv_resourceFactories.end()) {
      assert( (*it).second == &crFactory );
      iv_resourceFactories.erase(it);
    }
  }

  ResourceABase const * ResourceManager::getResource(
    icu::UnicodeString const & crKey,
    icu::UnicodeString const & crKind,
    ErrorInfo &                errorInfo) {
    TyResourceFactories::iterator  it = iv_resourceFactories.find(crKind);
    if (it == iv_resourceFactories.end()) {
      errorInfo.setErrorId(UIMA_ERR_RESMGR_NO_RESOURCE_FACTORY_FOR_KIND);
      return NULL;
    }
    assert(it->first == crKind);
    assert(EXISTS(it->second));

    return getResource(crKey, *(it->second), errorInfo);
  }


  /**
   * Register a stream handler dll filename for a given URI scheme.
   * A URI scheme may be registered only once in an application. 
   */
  util::Filename const * ResourceManager::registerStreamHandlerForURIScheme(TCHAR const * uriScheme,
      TCHAR const * dllFilename) {
    std::string uriSchemeStr(uriScheme);
    TyURIStreamHandlers::iterator  ite;
    ite = iv_streamhandlers.find(uriSchemeStr);
    if (ite != iv_streamhandlers.end() ) {
      ErrorMessage errMsg = ErrorMessage(UIMA_MSG_ID_EXC_SCHEMEHANDLER_DUPLICATE);
      errMsg.addParam(dllFilename);
      errMsg.addParam(uriScheme);
      UIMA_EXC_THROW_NEW(SofaDataStreamException,
                         UIMA_ERR_SOFADATASTREAM,
                         errMsg,
                         UIMA_MSG_ID_EXCON_SOFADATASTREAM,
                         ErrorInfo::unrecoverable);
    }
    util::Filename * pDllFile = new util::Filename(dllFilename);
    if (pDllFile == NULL) {
      ErrorMessage errMsg = ErrorMessage(UIMA_MSG_ID_EXC_SCHEMEHANDLER_LOAD);
      errMsg.addParam(dllFilename);
      errMsg.addParam(uriScheme);
      UIMA_EXC_THROW_NEW(SofaDataStreamException,
                         UIMA_ERR_SOFADATASTREAM,
                         errMsg,
                         UIMA_MSG_ID_EXCON_SOFADATASTREAM,
                         ErrorInfo::unrecoverable);
    }
    iv_streamhandlers.insert(TyURIStreamHandlers::value_type(uriSchemeStr, pDllFile));
    return(util::Filename*)pDllFile;
  }


  /**
   * Return the dll file registered for the specified uri scheme if found.
   * Otherwise, returns null.
   */
  util::Filename const * ResourceManager::getStreamHandlerForURIScheme(std::string uriScheme) {

    TyURIStreamHandlers::iterator  ite = iv_streamhandlers.find(uriScheme);
    if (ite == iv_streamhandlers.end() ) {
      return NULL;
    } else {
      return(util::Filename *) ite->second;
    }

  }




  /* ----------------------------------------------------------------------- */
  /*       Static implementation                                             */
  /* ----------------------------------------------------------------------- */

  /* static */ ResourceManager & ResourceManager::createInstance(const TCHAR * cpszInstance, const TCHAR * cpszProductPrefix)
  /* ----------------------------------------------------------------------- */
  {
    // acquire mutex
    if (NOTEXISTS(cv_pclSingletonInstance)) {

      // First must initialize apr (re-init is OK)
      apr_status_t rv = apr_initialize();
      if (rv != APR_SUCCESS) {
        char errBuf[256];
        apr_strerror(rv, errBuf, sizeof(errBuf));
        UIMA_EXC_THROW_NEW(AprFailureException,
                           UIMA_ERR_APR_FAILURE,
                           ErrorMessage(UIMA_MSG_ID_EXC_APR_ERROR,errBuf),
                           ErrorMessage(UIMA_MSG_ID_EXCON_APR_FUNCTION,"apr_initialize"),
                           ErrorInfo::unrecoverable);
      }

      cv_pclSingletonInstance = new ResourceManager(cpszInstance, cpszProductPrefix);
      assert(EXISTS(cv_pclSingletonInstance));
      // Initialize the ICU
      UErrorCode status = U_ZERO_ERROR;
      u_init(&status);
      if (status != U_ZERO_ERROR) {
        char buffer[100];
        sprintf(buffer, "ICU init failed with %d", status);
        UIMA_EXC_THROW_NEW(Uima_runtime_error,
                           UIMA_MSG_ID_LITERAL_STRING,
                           UIMA_MSG_ID_LITERAL_STRING,
                           ErrorMessage(UIMA_MSG_ID_LITERAL_STRING, buffer),
                           ErrorInfo::unrecoverable);
      }
      try {
        // initialize XML4C stuff
        XMLPlatformUtils::Initialize();
      } catch (XMLException& ) {
        cv_pclSingletonInstance->iv_utLastErrorId = UIMA_ERR_RESMGR_COULD_NOT_INITIALIZE_XML4C;
        assertWithMsg(false, "XML4C initialization failed");
      }

      //create the fileLogger if UIMACPP_LOGFILE env variable is set
      /* determine log file name */
      string str = UIMA_ENVVAR_LOG_FILE;
      util::EnvironmentVariableQueryOnly clEnvVarLogFilePath(str.c_str());
      UIMA_TPRINT(_TEXT("querying envvar: ") << str.c_str());
      if (clEnvVarLogFilePath.hasValue()) {
        const TCHAR *  cpszLogFile = clEnvVarLogFilePath.getValue();
        UIMA_TPRINT(_TEXT("value: ") << cpszLogFile);

        /* create an instance of FileLogger and register it. */
        cv_pclSingletonInstance->iv_fileLogger = new FileLogger(cpszLogFile);

        if (cv_pclSingletonInstance->iv_fileLogger == NULL) {   //Need to handle this better
          //cerr << "Could not open the log file " << cpszLogFile << endl;
          str = "Could not create FileLogger";
          str += cpszLogFile;
          UIMA_EXC_THROW_NEW(Uima_runtime_error,
                           UIMA_MSG_ID_LITERAL_STRING,
                           UIMA_MSG_ID_LITERAL_STRING,
                           ErrorMessage(UIMA_MSG_ID_LITERAL_STRING, str.c_str()),
                           ErrorInfo::unrecoverable);
        } else {
          cv_pclSingletonInstance->registerLogger(cv_pclSingletonInstance->iv_fileLogger);
        }
      } 

      //instantiate framework logger
      cv_pclSingletonInstance->iv_frameworkLogger = new LogFacility(icu::UnicodeString("org.apache.uima.cpp"), cv_pclSingletonInstance->iv_logLevel);

      cv_pclSingletonInstance->iv_frameworkLogger->logMessage("ResourceManager Instance created.");
    } // release mutex
    UIMA_TPRINT("ResourceManager instance created");
    return(*cv_pclSingletonInstance);
  }

  /* static */ ResourceManager & ResourceManager::getInstance(void)
  /* ----------------------------------------------------------------------- */
  {
    assert(EXISTS(cv_pclSingletonInstance));
    return(*cv_pclSingletonInstance);
  }

  /* static */ bool ResourceManager::hasInstance(void)
  /* ----------------------------------------------------------------------- */
  {
    return((bool) EXISTS(cv_pclSingletonInstance));
  }
  /* ----------------------------------------------------------------------- */
  void ResourceManager::deleteInstance(void) {
    UIMA_TPRINT(_TEXT("deleting..."));
    // acquire mutex
    if (cv_pclSingletonInstance != 0 ) {
      try {
        XMLPlatformUtils::Terminate();
      }
      catch (const XMLException& ) {
        cv_pclSingletonInstance->iv_utLastErrorId = UIMA_ERR_RESMGR_COULD_NOT_TERMINATE_XML4C;
        assertWithMsg(false, "XML4C termination failed");
      }
     
      if (cv_pclSingletonInstance->iv_frameworkLogger != NULL) {
        delete cv_pclSingletonInstance->iv_frameworkLogger;
      }

      if (cv_pclSingletonInstance->iv_fileLogger != NULL) {
        delete cv_pclSingletonInstance->iv_fileLogger;
      }

      assert(EXISTS(cv_pclSingletonInstance));
      delete cv_pclSingletonInstance;
      cv_pclSingletonInstance = 0;

      // Terminate apr (undo matching apr_initialize)
      apr_terminate();
//#if !defined( NDEBUG ) && defined(_MSC_VER) && defined(_CRTDBG_MAP_ALLOC)   
//      int iRetVal = _CrtDumpMemoryLeaks();
//#endif
      UIMA_TPRINT("ResMgr instance deleted");
    }
    assert( cv_pclSingletonInstance == 0 );
    // release mutex
  }

  bool
  ResourceManager::createFilenameForLanguage(Language & rclLanguage,
      const TCHAR * cpszExtension,
      bool bUseAlternateTerritories,
      const util::Location & crclDirToUse,
      util::Filename & rclFilename)  {
    string                     str(rclLanguage.asString());

    assert(EXISTS(cpszExtension));
    assert(*cpszExtension == _TEXT('.'));              /* extension starts with a dot */
    /* we need to restrict ourselves to DOS 8+3 filenames */
    if (str.length() > UIMA_MAX_VALID_FILENAME_SIZE) {
      str.resize(UIMA_MAX_VALID_FILENAME_SIZE);
    }
    /* create a filename based on the complete language name
       e.g. language is en-us and file is en-us.tsw */
    util::Filename              clFilename(crclDirToUse, str.c_str(), cpszExtension);
    UIMA_TPRINT(_TEXT("1st Filename: '") << clFilename.getAsCString() << _TEXT("' existent: ") << clFilename.isExistent());
    if (clFilename.isExistent()) {
      rclFilename = clFilename;
      return(true);                                   /* done! */
    } else {
      /* if the user did specify a territory, we could look a little bit further... */
      if (rclLanguage.hasTerritory()) {
        /* give it another try using just the language name without the territory
           e.g. language is en-us and file is en.tsw */
        clFilename.setNew( crclDirToUse,rclLanguage.getLanguageCode(),cpszExtension );
        UIMA_TPRINT(_TEXT("2nd Filename: '") << clFilename.getAsCString() << _TEXT("' existent: ") << clFilename.isExistent());
      }
    }
    if (bUseAlternateTerritories && !clFilename.isExistent()) {
      /* give it another try using just the language name without the territory
         e.g. language is en and file is en-us.tsw
         this means a little bit more effort - we need to walk the directory */
      util::DirectoryWalk     clDirWalk(crclDirToUse.getAsCString());
      string                  strSearchPattern(rclLanguage.getLanguageCode());

      strSearchPattern += _TEXT("*");
      strSearchPattern += cpszExtension;
      UIMA_TPRINT(_TEXT("Search pattern: '") << strSearchPattern.c_str() << _TEXT("'"));
      while (clDirWalk.isValid()) {
        if (clDirWalk.isFile() && clDirWalk.matchesWildcardPattern(strSearchPattern.c_str())) {
          clFilename.setNewName(clDirWalk.getNameWithoutPath());
          break;
        }
        clDirWalk.setToNext();
      }
      UIMA_TPRINT(_TEXT("3rd Filename: '") << clFilename.getAsCString() << _TEXT("' existent: ") << clFilename.isExistent());
    }
    rclFilename = clFilename;
    return(clFilename.isExistent());
  }

  LogFacility & ResourceManager::getLogger() {
    return *iv_frameworkLogger;
  }

  icu::UnicodeString ResourceManager::resolveFilename(icu::UnicodeString const & filename, icu::UnicodeString const & lastFilename) {
    auto_array<char> filename_cstr( new char[filename.length() + 1] );
    filename.extract(0, filename.length(), filename_cstr.get());

    auto_array<char> lastFilename_cstr( new char[lastFilename.length() + 1] );
    lastFilename.extract(0, lastFilename.length(), lastFilename_cstr.get());

    //build the filename
    util::Filename fileLoc(filename_cstr.get());

    // don't try our search mimic for absolute paths
    if (fileLoc.isAbsolute()) {
      return filename;
    }

    // relative path to the current directory
    if (fileLoc.isExistent()) {
      return filename;
    }

    // try in the same directory as lastFilename
    util::Filename locSameDirAsLast(lastFilename_cstr.get());
    locSameDirAsLast.setNewName(filename_cstr.get());

    if (locSameDirAsLast.isExistent()) {
      return locSameDirAsLast.getAsCString();
    }

    // try in the UIMACPP data directory
    util::Location const & fallbackLoc = ResourceManager::getInstance().getLocationData();

    std::string nameInDataDir( fallbackLoc.getAsCString() );
    nameInDataDir += filename_cstr.get();
    util::Filename fileInDataDir( nameInDataDir.c_str() );
    fileInDataDir.normalizeAbsolute();                // Normalize to native / or \ separators
    if (fileInDataDir.isExistent()) {
      return icu::UnicodeString(fileInDataDir.getAsCString());
    }

    nameInDataDir.clear();
    nameInDataDir = fallbackLoc.getAsCString();
    nameInDataDir += "descriptors/";
    nameInDataDir += filename_cstr.get();
    fileInDataDir.setNew(nameInDataDir.c_str());
    fileInDataDir.normalizeAbsolute();
    if (fileInDataDir.isExistent()) {
      return icu::UnicodeString(fileInDataDir.getAsCString());
    }

    nameInDataDir.clear();
    nameInDataDir = fallbackLoc.getAsCString();
    nameInDataDir += "specifiers/";
    nameInDataDir += filename_cstr.get();
    fileInDataDir.setNew(nameInDataDir.c_str());
    fileInDataDir.normalizeAbsolute();
    if (fileInDataDir.isExistent()) {
      return icu::UnicodeString(fileInDataDir.getAsCString());
    }

    // return the original filename here, will trigger an XML exception since
    // it couldn't be found anywhere
    return filename;
  }



}

/* <EOF> */




