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

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

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


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

#if defined(_MSC_VER)
#include <stdio.h>
#include <eh.h>
#include <windows.h>
#include <winbase.h>
#endif

#include "uima/pragmas.hpp" //must be included first to disable warnings
#include "uima/msg.h"
#include <string>
#include <sstream>

#include "uima/macros.h"
#include "uima/trace.hpp"

#include "uima/strconvert.hpp"
#include "uima/unistrref.hpp"
#include "uima/comp_ids.h"
#include "uima/exceptions.hpp"
#include "uima/msgstrtab.h"

using namespace std;

namespace uima {

///Constructor with just the message id
  ErrorMessage::ErrorMessage(
    TyMessageId                          utMsgId
  ) :
      iv_utMsgId(utMsgId) {
    if ( iv_utMsgId == 0) {
      iv_utMsgId = UIMA_MSG_ID_NO_MESSAGE_AVAILABLE;
    }
  }
///Constructor with a single char * parameter
  ErrorMessage::ErrorMessage(
    TyMessageId                          utMsgId,
    const char *                            cpszParam1
  ) :
      iv_utMsgId(utMsgId) {
    assert( iv_utMsgId != 0 );
    iv_vecParams.push_back((string)cpszParam1);
  }

///Constructor with a single string parameter
  ErrorMessage::ErrorMessage(
    TyMessageId           utMsgId,
    const string &           crstrParam1
  ) :
      iv_utMsgId(utMsgId) {
    assert( iv_utMsgId != 0 );
    iv_vecParams.push_back(crstrParam1);
  }

///Constructor with a single UChar * parameter
  ErrorMessage::ErrorMessage(
    TyMessageId                         utMsgId,
    const UChar *                          cpuszParam1
  ) :
      iv_utMsgId(utMsgId) {
    assert( iv_utMsgId != 0 );
    string s;
    UnicodeStringRef(cpuszParam1).extract(s);         // Convert to default encoding for platform
    iv_vecParams.push_back(s);
  }

///Constructor with a single UnicodeString parameter
  ErrorMessage::ErrorMessage(
    TyMessageId                         utMsgId,
    const icu::UnicodeString &             crustrParam1
  ) :
      iv_utMsgId(utMsgId) {
    assert( iv_utMsgId != 0 );
    string s;
    UnicodeStringRef(crustrParam1).extract(s);         // Convert to default encoding for platform
    iv_vecParams.push_back(s);
  }

///Constructor with a single int parameter
  ErrorMessage::ErrorMessage(
    TyMessageId           utMsgId,
    int                      iParam1
  ) :
      iv_utMsgId(utMsgId) {
    assert( iv_utMsgId != 0 );
    string s;
    iv_vecParams.push_back(long2String(iParam1, s));
  }

///Constructor with a single unsigned int parameter
  ErrorMessage::ErrorMessage(
    TyMessageId           utMsgId,
    unsigned int             uiParam1
  ) :
      iv_utMsgId(utMsgId) {
    assert( iv_utMsgId != 0 );
    string s;
    iv_vecParams.push_back(long2String((int) uiParam1, s));
  }


///Constructor with a single long parameter
  ErrorMessage::ErrorMessage(
    TyMessageId           utMsgId,
    long                     lParam1
  ) :
      iv_utMsgId(utMsgId) {
    assert( iv_utMsgId != 0 );
    string s;
    iv_vecParams.push_back(long2String(lParam1, s));
  }

///Constructor with a single unsigned long parameter
  ErrorMessage::ErrorMessage(
    TyMessageId           utMsgId,
    unsigned long            ulParam1
  ) :
      iv_utMsgId(utMsgId) {
    assert( iv_utMsgId != 0 );
    string s;
    iv_vecParams.push_back(long2String((long) ulParam1, s));
  }

///Constructor with a single double parameter
  ErrorMessage::ErrorMessage(
    TyMessageId           utMsgId,
    const double             dParam1
  ) :
      iv_utMsgId(utMsgId) {
    assert( iv_utMsgId != 0 );
    string s;
    iv_vecParams.push_back(double2String(dParam1, s));
  }

///Constructor with a full parameter vector
  ErrorMessage::ErrorMessage(
    TyMessageId           utMsgId,
    const vector<string> &   crvecParams
  ) :
      iv_utMsgId(utMsgId),
      iv_vecParams(crvecParams) {
    assert( iv_utMsgId != 0 );
  }


  ///add parameter to message id
  void
  ErrorMessage::addParam(const char * cpsz) {
    iv_vecParams.push_back(cpsz);
  }
  ///add parameter to message id
  void
  ErrorMessage::addParam(const string & str) {
    iv_vecParams.push_back(str);
  }
  ///add parameter to message id
  void
  ErrorMessage::addParam(const UChar * cpuszParam) {
    string s;
    UnicodeStringRef(cpuszParam).extract(s);         // Convert to default encoding for platform
    iv_vecParams.push_back(s);
  }
  ///add parameter to message id
  void
  ErrorMessage::addParam(const icu::UnicodeString & crustrParam) {
    string s;
    UnicodeStringRef(crustrParam).extract(s);         // Convert to default encoding for platform
    iv_vecParams.push_back(s);
  }

  void ErrorMessage::addParam(uima::UnicodeStringRef const & crParam) {
    icu::UnicodeString str(crParam.getBuffer(), crParam.length() );
    addParam(str);
  }

  ///add parameter to message id
  void
  ErrorMessage::addParam(long l) {
    string str;
    convertToString(l, str);
    iv_vecParams.push_back(str);
  }
  ///add parameter to message id
  void
  ErrorMessage::addParam(unsigned long ul) {
    string str;
    convertToString(ul, str);
    iv_vecParams.push_back(str);
  }
  ///add parameter to message id
  void
  ErrorMessage::addParam(int i) {
    string str;
    convertToString(i, str);
    iv_vecParams.push_back(str);
  }
  ///add parameter to message id
  void
  ErrorMessage::addParam(unsigned int ui) {
    string str;
    convertToString(ui, str);
    iv_vecParams.push_back(str);
  }
  ///add parameter to message id
  void
  ErrorMessage::addParam(double d) {
    string str;
    convertToString(d, str);
    iv_vecParams.push_back(str);
  }

  /*------------------------------- Constructors -------------------------------*/

  ErrorContext::ErrorContext(
    const ErrorMessage &     crclMessage,
    const char*                   pszFilename,
    const char*                   pszFunction,
    unsigned long                 ulLineNumber
  ):
      iv_clMessage(crclMessage),
      iv_pszFilename(pszFilename),
      iv_pszFunction(pszFunction),
      iv_ulLineNo(ulLineNumber) {}

#ifdef OS_STL
  Exception::~Exception()
#else
  Exception::~Exception() UIMA_THROW0()
#endif
  {}

  /*------------------------------ Output Support ------------------------------*/

  string
  ErrorMessage::asString() const {

    size_t numparams = getMessageParams().size();

    // Check for unknown message id
    if (iv_utMsgId < 0 || iv_utMsgId > UIMA_MSG_ID_SIGNATURE_END) {
      return string("Unknown message id " + iv_utMsgId);
    }

    //parameter substitution

    //locate message in message table
    const TCHAR ** messages = gs_aszMessageStringTable;
    const TCHAR * msg = messages[iv_utMsgId];

    TCHAR * buf = new TCHAR[UIMA_MSG_MAX_STR_LEN];
    memset(buf,'\0',UIMA_MSG_MAX_STR_LEN);

    int numwritten=0;

    TCHAR * trg = buf;
    while (*msg) {
      if (numwritten > UIMA_MSG_MAX_STR_LEN) {
        break;
      }
      if (*msg == UIMA_MSG_REPLACE_CHAR) {
        msg = msg+1;
        if (*msg == UIMA_MSG_REPLACE_CHAR) {
          *trg = *msg;
          trg = trg +1;
          ;
          msg = msg+1;
          numwritten++;
        } else {  //replace %n with the corresponding param
          unsigned long index;
          int len;
          string arg;
          // determine the number of the specified argument ...
          index = (unsigned long) atol(msg);
          if (index > numparams)       // param not defined
          {
            arg = "???";      // replace it by "dont-know"
          } else {
            // ... the indexed argument ...
            arg = iv_vecParams[index - 1]; // zero-based array!
            //assert(arg.length() > 0);
          }
          len = arg.length();
          // ... and then copy the argument
          if (UIMA_MSG_MAX_STR_LEN-numwritten < len) {
            len = UIMA_MSG_MAX_STR_LEN - numwritten;
          }
          if (len > 0) {
            strncpy(trg, arg.c_str(), len);
            trg = trg+len;
          }
          msg = msg+1;
          while ( isdigit(*msg) ) { //handle arg number 10 or more
            msg = msg+1;
          }
        }
      } else {
        *trg = *msg;
        trg = trg+1;
        msg = msg+1;
      }
    }
    //cout << buf << endl;
   string target(buf);
   delete[] buf ;
   return target;
	 //string target;
	 //target.assign(buf, UIMA_MSG_MAX_STR_LEN);                   // Copy the result to the string
   //delete buf;
	 //return target;
  }

  ostream &
  operator << (
    ostream &            os,
    const ErrorMessage & errorMsg
  ) {
    os << errorMsg.asString();
    return(os);
  }

  string
  ErrorContext::asString() const {
    string s;
    s += getMessage().asString();
    if (getFileName() != NULL) {
      s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "     File     : " + getFileName();
    }
    if (getFunctionName() != NULL) {
      s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "     Function : " + getFunctionName();
    }
    if (getLineNumber() != 0) {
      string sNum;
      long2String(getLineNumber(), sNum);
      s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "     Line     : " + sNum;
    }

    return(s);
  }

  ostream &
  operator << (
    ostream            & os,
    const ErrorContext & errContext
  ) {
    os << errContext.asString();
    return (os);
  }

  void ErrorMessage::reset(void) {
    iv_utMsgId = UIMA_MSG_ID_NO_MESSAGE_AVAILABLE;
    iv_vecParams.clear();
  }

  /* ----------------------------------------------------------------------- */
  /*   ErrorInfo                                                        */
  /* ----------------------------------------------------------------------- */

  /*------------------------------- Statics  -----------------------------------*/
//initialize static member var to an initial value

  const char * ErrorInfo::cv_cpszContextPrefix   = "   While      : ";
  const char * ErrorInfo::cv_cpszIndent          = "";


  /*------------------------------- Constructors -------------------------------*/

  ErrorInfo::ErrorInfo(
    const ErrorMessage     & rclMessage,
    TyErrorId                ulErrorId,
    ErrorInfo::EnSeverity    enSeverity
  ) :
      iv_clErrorMsg(rclMessage),
      iv_ulErrorId(ulErrorId),
      iv_enSeverity(enSeverity),
      iv_vecContexts() {}

  ErrorInfo::ErrorInfo( void ) :
      iv_clErrorMsg(),
      iv_ulErrorId(UIMA_ERR_NONE),
      iv_enSeverity(recoverable),
      iv_vecContexts() {}

  ErrorInfo::~ErrorInfo() {}

//constructor (copy)
//? Exception::Exception(
//?   const Exception&            rclException
//? )
//? {
//? }

  /*---------------------------- Exception Context ----------------------------*/
  void
  ErrorInfo::addContext( const ErrorContext & crclContext ) {
    iv_vecContexts.push_back(crclContext);
  }

  const ErrorContext *
  ErrorInfo::contextPtrAtIndex( size_t uiContextIndex ) const {
    if (uiContextIndex >= iv_vecContexts.size()) {
      return(NULL);
    }
    return(&iv_vecContexts[uiContextIndex]);
  }

  /*------------------------------ Output Support ------------------------------*/
  string
  ErrorInfo::asString() const {
    string s;
    if (getErrorId() == UIMA_ERR_NONE) {
      s += string("No Error\n");
      return (s);
    }
    if (getErrorId() != UIMA_ERR_NONE) {
      s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "Error number  : ";
      string sErr;
      long2String( getErrorId(), sErr);
      s += sErr;
    }
    s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "Recoverable   : " + (isRecoverable() ? "Yes" : "No");
    s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "Error         : " + getMessage().asString();
    for (size_t i = 0; i < contextCount(); ++i) {
      s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + ErrorInfo::getGlobalErrorInfoContextPrefix();
      assert(EXISTS(contextPtrAtIndex(i)));   //lint !e666: Expression with side effects passed to repeated parameter 1 in macro EXISTS
      s += contextPtrAtIndex(i)->asString();
    }
    s += string("\n");

    return (s);
  }

///output support for streams
  ostream &
  operator << (
    ostream         & os,
    const ErrorInfo & errInfo
  ) {
    os << errInfo.asString();
    return(os);
  }

  void ErrorInfo::reset(void) {
    iv_clErrorMsg.reset();
    iv_ulErrorId = UIMA_ERR_NONE;
    iv_enSeverity = recoverable;
    iv_vecContexts.clear();
  }

  /* ----------------------------------------------------------------------- */
  /*   Exception                                                        */
  /* ----------------------------------------------------------------------- */

  Exception::Exception(
    const ErrorMessage    & rclMessage,
    TyErrorId                 ulErrorId,
    ErrorInfo::EnSeverity   enSeverity
  ) :
      EXCEPTION_BASE_CLASS(),
      iv_clErrorInfo(rclMessage, ulErrorId, enSeverity) {}

  Exception::Exception(
    const ErrorInfo & crclErrorInfo
  ) :
      EXCEPTION_BASE_CLASS(),
      iv_clErrorInfo(crclErrorInfo) {}

  /*------------------------------ Exception Type ------------------------------*/

  const char * Exception::getName() const {
    return(_TEXT("unspecified exception"));
  }

  /*------------------------- Application Termination --------------------------*/
  void Exception::terminate() {
    exit(iv_clErrorInfo.getErrorId());  //lint !e713: Loss of precision (arg. no. 1) (unsigned long to int)
  }

  /*------------------------------ Throw Support -------------------------------*/
  void Exception::assertParameter(
    const char*       /*exceptionText*/,
    ErrorContext   /*context*/ ) {
    assert(false);
    //not tested yet (and not used anywhere!)
  }

  /*------------------------- Logging Support ----------------------------------*/

  void Exception::logExceptionData() {
    util::Trace clTrace(util::enTraceDetailLow, UIMA_TRACE_ORIGIN, UIMA_TRACE_COMPID_EXCEPTIONS);

    clTrace.dump(_TEXT("Exception occured"), asString().c_str());
    //not implemented yet
  }

  /*------------------------------ Output Support ------------------------------*/
  string
  Exception::asString() const {
    //output the (class) name of the exception and its error info after it.
    return string("\n") +
           ErrorInfo::getGlobalErrorInfoIndent() +
           "Exception     : " +
           getName() +
           "\n" +
           getErrorInfo().asString() +
           "\n";
  }



  ostream &
  operator << (
    ostream            & os,
    const Exception & exception
  ) {
    //output the (class) name of the exception and its error info after it.
    os << exception.asString();
    return(os);
  }

  /*------------------------------ Static Method -------------------------------*/

  // Release contents of string container allocated by asString method

  void
  Exception::release(std::string & msg) {
    msg.clear();               // Empty string
    msg.reserve(1);            // Reduce capacity so will use internal buffer & free external one
  }

//private:
  /*----------------------------- Hidden Functions -----------------------------*/
  Exception& Exception::operator=( const Exception&   /*exc*/ ) {
    assert(false);
    return(*this);                                     //lint !e527  unreachable
  }  //lint !e1745: member not assigned by private assignment operator

  /* ----------------------------------------------------------------------- */
  /*   Implementations of predefined exceptions                              */
  /* ----------------------------------------------------------------------- */


  /*
    The following classes reimplement the ANSI standard exception hierarchy from
    stdexcept.h as UIMACPP exceptions with context and message id support
  */
  UIMA_EXC_CLASSIMPLEMENT(Uima_logic_error        ,Exception);
  UIMA_EXC_CLASSIMPLEMENT(Uima_runtime_error      ,Exception);

  UIMA_EXC_CLASSIMPLEMENT(Uima_domain_error       ,Uima_logic_error);
  UIMA_EXC_CLASSIMPLEMENT(Uima_invalid_argument   ,Uima_logic_error);
  UIMA_EXC_CLASSIMPLEMENT(Uima_length_error       ,Uima_logic_error);
  UIMA_EXC_CLASSIMPLEMENT(Uima_out_of_range       ,Uima_logic_error);

  UIMA_EXC_CLASSIMPLEMENT(Uima_range_error        ,Uima_runtime_error);
  UIMA_EXC_CLASSIMPLEMENT(Uima_overflow_error     ,Uima_runtime_error);
  UIMA_EXC_CLASSIMPLEMENT(Uima_underflow_error    ,Uima_runtime_error);


  /**
    The following exceptions are used by helper test classes that are no longer in the UIMACPP library:
          CommandLineDriver DocBuffer ParseHandlers
  */
  UIMA_EXC_CLASSIMPLEMENT(ConsoleAbortExc        ,Exception);
  UIMA_EXC_CLASSIMPLEMENT(ParseHandlerExc        ,Exception);
  UIMA_EXC_CLASSIMPLEMENT(ExcDocBuffer           ,Uima_out_of_range);

  /** code page conversion errors */
  UIMA_EXC_CLASSIMPLEMENT(CodePageConversionException, uima::Exception);
  /**
    The following exception is used to report failures from APR functions
  */
  UIMA_EXC_CLASSIMPLEMENT(AprFailureException, Exception);

  /*
    The following classes provide a starting point for an exception hierarchy
  */
//? UIMA_EXC_CLASSIMPLEMENT(ExcAssertionFailure, Exception);
  UIMA_EXC_CLASSIMPLEMENT(ExcIllFormedInputError , Uima_runtime_error);
  UIMA_EXC_CLASSIMPLEMENT(ExcInvalidParameter    , Uima_invalid_argument);
  UIMA_EXC_CLASSIMPLEMENT(ExcIndexOutOfRange     , Uima_out_of_range);
//? UIMA_EXC_CLASSIMPLEMENT(ExcDeviceError      ,Uima_runtime_error);
  UIMA_EXC_CLASSIMPLEMENT(ExcInvalidRequest      , Uima_runtime_error);
  UIMA_EXC_CLASSIMPLEMENT(ExcResourceExhausted   , Uima_runtime_error);
  UIMA_EXC_CLASSIMPLEMENT(ExcOutOfMemory         , ExcResourceExhausted);
//? UIMA_EXC_CLASSIMPLEMENT(ExcOutOfSystemResource, ResourceExhausted);
//? UIMA_EXC_CLASSIMPLEMENT(ExcOutOfWindowResource, ResourceExhausted);
  UIMA_EXC_CLASSIMPLEMENT(ExcFileNotFoundError   , Uima_runtime_error);

// Windows specific CException
  ExcWinCException::ExcWinCException(
    ErrorMessage             clMessage,
    TyErrorId                  ulErrorId,
    ErrorInfo::EnSeverity    enSeverity
  )
      : Uima_runtime_error (clMessage, ulErrorId, enSeverity) {
    ;
  }

  const char*
  ExcWinCException :: getName() const {
    return( "ExcWinCException" );
  }

  ExcWinCException::~ExcWinCException () CHILD_DESTRUCT_THROW0() {
    ;
  }

  ExcWinCException::ExcWinCException (const ExcWinCException & a) : Uima_runtime_error (a) {
    ;
  }


  // Windows exceptions can be mapped only when compiled with MS VC++
#if defined(_MSC_VER)

  void translation_func( unsigned int u, _EXCEPTION_POINTERS* pExp ) {
    const char * cpszMsg = NULL;
    switch (u) {
    case EXCEPTION_ACCESS_VIOLATION:
      cpszMsg ="\"ACCESS VIOLATION\"";
      break;
    case EXCEPTION_DATATYPE_MISALIGNMENT:
      cpszMsg ="\"DATATYPE MISALIGNMENT\"";
      break;
    case EXCEPTION_BREAKPOINT:
      cpszMsg ="\"BREAKPOINT\"";
      break;
    case EXCEPTION_SINGLE_STEP:
      cpszMsg ="\"SINGLE STEP\"";
      break;
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
      cpszMsg ="\"ARRAY BOUNDS EXCEEDED\"";
      break;
    case EXCEPTION_FLT_DENORMAL_OPERAND:
      cpszMsg ="\"FLT DENORMAL OPERAND\"";
      break;
    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
      cpszMsg ="\"FLT DIVIDE_BY ZERO\"";
      break;
    case EXCEPTION_FLT_INEXACT_RESULT:
      cpszMsg ="\"FLT INEXACT_RESULT\"";
      break;
    case EXCEPTION_FLT_INVALID_OPERATION:
      cpszMsg ="\"FLT INVALID OPERATION\"";
      break;
    case EXCEPTION_FLT_OVERFLOW:
      cpszMsg ="\"FLT OVERFLOW\"";
      break;
    case EXCEPTION_FLT_STACK_CHECK:
      cpszMsg ="\"FLT STACK_CHECK\"";
      break;
    case EXCEPTION_FLT_UNDERFLOW:
      cpszMsg ="\"FLT UNDERFLOW\"";
      break;
    case EXCEPTION_INT_DIVIDE_BY_ZERO:
      cpszMsg ="\"INT DIVIDE BY ZERO\"";
      break;
    case EXCEPTION_INT_OVERFLOW:
      cpszMsg ="\"INT OVERFLOW\"";
      break;
    case EXCEPTION_PRIV_INSTRUCTION:
      cpszMsg ="\"PRIV INSTRUCTION\"";
      break;
    case EXCEPTION_IN_PAGE_ERROR:
      cpszMsg ="\"IN PAGE_ERROR\"";
      break;
    case EXCEPTION_ILLEGAL_INSTRUCTION:
      cpszMsg ="\"ILLEGAL INSTRUCTION\"";
      break;
    case EXCEPTION_NONCONTINUABLE_EXCEPTION:
      cpszMsg ="\"NONCONTINUABLE EXCEPTION\"";
      break;
    case EXCEPTION_STACK_OVERFLOW:
      cpszMsg ="\"STACK OVERFLOW\"";
      break;
    case EXCEPTION_INVALID_DISPOSITION:
      cpszMsg ="\"INVALID DISPOSITION\"";
      break;
    case EXCEPTION_GUARD_PAGE:
      cpszMsg ="\"GUARD PAGE\"";
      break;
    case EXCEPTION_INVALID_HANDLE:
      cpszMsg ="\"INVALID HANDLE\"";
      break;
    case CONTROL_C_EXIT:
      cpszMsg ="\"CONTROL C EXIT\"";
      break;
    default:
      cpszMsg = "Unknows Windows C Exception";
      break;
    }
    // throw our own type of exception so we know at least what was going on
    // instead of just getting an unknown ... C++ excepition
    throw ExcWinCException( ErrorMessage(UIMA_MSG_ID_EXC_WINDOWS_EXCEPTION, cpszMsg),
                            (TyErrorId)UIMA_ERR_ENGINE_WINDOWS_EXCEPTION,
                            ErrorInfo::unrecoverable);
  }

#define UIMA_ENVVAR_DONT_MAP_WINDOWS_EXCEPTIONS     "UIMA_DONT_MAP_WINDOWS_EXCEPTIONS"

  // _set_se_translator should be called at the beginning of main
  // since we have no access to main here, we declare a static var of a dummy
  // type which does the _set_se_translator call in it's constructor
  // Note: this only works if the compiler properly executes the ctors of
  // such static vars in DLLs
  class Dummy {
  public:
    Dummy( void ) {
      if ( getenv(UIMA_ENVVAR_DONT_MAP_WINDOWS_EXCEPTIONS) == NULL) {
        _set_se_translator( translation_func );
      }
    }
  };
  // static var of our dummy type
  Dummy clDummy;
#endif

}
