/** \file engine.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:

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


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


/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */
#define UIMA_ENGINE_MAIN_CPP

#include "uima/pragmas.hpp" // must be first file to be included to get pragmas

#include <memory>

#include "uima/macros.h"

#include "uima/engine.hpp"
#include "uima/strconvert.hpp"
#include "uima/internal_aggregate_engine.hpp"
#include "uima/internal_primitive_engine.hpp"
#include "uima/internal_jedii_engine.hpp"
#include "uima/taespecifierbuilder.hpp"
#include "uima/internal_casimpl.hpp"
#include "uima/resmgr.hpp"
#include "uima/msg.h"
#include "uima/casdefinition.hpp"
#include "xercesc/framework/LocalFileInputSource.hpp"
#include "xercesc/framework/MemBufInputSource.hpp"
#include "uima/stltools.hpp"
XERCES_CPP_NAMESPACE_USE

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

/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Types / Classes                                                   */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Implementation                                                    */
/* ----------------------------------------------------------------------- */
using namespace std;
namespace uima {

  UIMA_EXC_CLASSIMPLEMENT(UnknownTypeException, Exception);
  UIMA_EXC_CLASSIMPLEMENT(UnknownFeatureException, Exception);
  UIMA_EXC_CLASSIMPLEMENT(UnknownRangeTypeException, Exception);
  UIMA_EXC_CLASSIMPLEMENT(IncompatibleRangeTypeException, Exception);
  UIMA_EXC_CLASSIMPLEMENT(AllowedStringValuesIncompatibleException, Exception);
  UIMA_EXC_CLASSIMPLEMENT(TypePriorityConflictException, Exception);
  UIMA_EXC_CLASSIMPLEMENT(IncompatibleIndexDefinitionsException, Exception);
  UIMA_EXC_CLASSIMPLEMENT(IncompatibleParentTypesException, Exception);
  UIMA_EXC_CLASSIMPLEMENT(CASIncompatibilityException, Exception);

  
  AnalysisEngineMetaData const & AnalysisEngine::getAnalysisEngineMetaData() const {
    assert( EXISTS(getAnnotatorContext().getTaeSpecifier().getAnalysisEngineMetaData()) );
    return *getAnnotatorContext().getTaeSpecifier().getAnalysisEngineMetaData();
  }

  TyErrorId AnalysisEngine::process(CAS & tcas) {
    return ((AnalysisEngine*) this)->process(tcas);
  }

  TyErrorId AnalysisEngine::process(CAS & tcas, ResultSpecification const & resultSpec) {
    return ((AnalysisEngine*) this)->process(tcas, resultSpec);
  }

  CASIterator  AnalysisEngine::processAndOutputNewCASes(CAS & tcas) {
    TyErrorId rc = ((AnalysisEngine*) this)->process(tcas);
    if (rc != UIMA_ERR_NONE) {
      UIMA_EXC_THROW_NEW(CASIteratorException,
                         UIMA_ERR_ENGINE_INVALID_CALLING_SEQUENCE,
                         UIMA_MSG_ID_EXCON_CALLING_ANNOTATOR_FUNCTION,
                         UIMA_MSG_ID_EXCON_CALLING_ANNOTATOR_FUNCTION,
                         ErrorInfo::unrecoverable);
    }
    return CASIterator(this);
  }

  /* static */ const char * AnalysisEngine::getVersionInfo(void)
  /* ----------------------------------------------------------------------- */
  {
    return(UIMA_STRINGIFY(UIMA_VERSION));
  }

  /* static */ const char * AnalysisEngine::getLevelInfo(void)
  /* ----------------------------------------------------------------------- */
  {
    return(TextAnalysisEngine::getVersionInfo());
  }

  /* static */ const char * AnalysisEngine::getErrorIdAsCString(TyErrorId utErrorId)
  /* ----------------------------------------------------------------------- */
  {
    const StErrorId2StringMapping * cpstErrorId2StringMapping = gs_astErrorId2StringMapping;
    size_t u;

    /* originally, we had a real big switch/case statement but this caused an
       "internal error" with the SUN compiler.
       now we perform a linear search - this method is not considered time critical */
    for (u = 0; u < NUMBEROF(gs_astErrorId2StringMapping); u++) {
      assert(EXISTS(cpstErrorId2StringMapping));
      if (utErrorId == cpstErrorId2StringMapping->iv_utErrorId) {
        assert(EXISTS(cpstErrorId2StringMapping->iv_cpszErrorId));
        return(cpstErrorId2StringMapping->iv_cpszErrorId);
      }
      ++cpstErrorId2StringMapping;
    }
#ifdef NDEBUG
    return(_TEXT("UIMA_ERR_UNKNOWN"));
#else
    string *            pstrRetVal = new string(_TEXT("??? UNKNOWN UIMACPP ERROR ID:")); /* this memory gets wasted - but this is only NDEBUG code!!! */
    string              strValue;

    long2String((long) utErrorId, strValue);
    assert(EXISTS(pstrRetVal));
    *pstrRetVal += strValue;
    *pstrRetVal += _TEXT(" - Please update file '" __FILE__ "' ???");
    /* this memory gets wasted - but this is only NDEBUG code!!! */
    return(pstrRetVal->c_str());  //lint !e429: Custodial pointer 'pstrRetVal' (line 596) has not been freed or returned
#endif
  }

  /* static */ void AnalysisEngine::printErrorIdTable(ostream & rclOutStream)
  /* ----------------------------------------------------------------------- */
  {
    const StErrorId2StringMapping * cpstErrorId2StringMapping = gs_astErrorId2StringMapping;
    size_t                     u;

    /* originally, we had a real big switch/case statement but this caused an
       "internal error" with the SUN compiler.
       now we perform a linear search - this method is not considered time critical */
    for (u = 0; u < NUMBEROF(gs_astErrorId2StringMapping); u++) {
      assert(EXISTS(cpstErrorId2StringMapping));
      assert(EXISTS(cpstErrorId2StringMapping->iv_cpszErrorId));
      rclOutStream << cpstErrorId2StringMapping->iv_utErrorId
      << " = "
      << cpstErrorId2StringMapping->iv_cpszErrorId
      << "\n";
      ++cpstErrorId2StringMapping;
    }
  }


  /**  
   * All variants of creating a TAE will eventually be mapped to this call.
   * Depending on the context, memory ownership over the different objects passed to this 
   * method may vary, thus the boolean parameters.
   * Toplevel TAEs alwasy own the ANC and the CAS Definition but if they are created
   * with an external TAESpec (see API calls for createTextAnalysisEngine()), they don't 
   * own this object. On the other hand, delegate AEs never own neither the ANC, the TAESpec
   * or the CASDefinition. 
   */
  /*static*/ AnalysisEngine * Framework::createAnalysisEngine(AnnotatorContext & rANC,
      bool bOwnsANC,
      bool bOwnsTAESpecifier,
      uima::internal::CASDefinition & casDefinition,
      bool ownsCASDefintion,
      ErrorInfo & rErrorInfo) {
    AnalysisEngine * pResult = NULL;
    assert( rErrorInfo.getErrorId() == UIMA_ERR_NONE );
    try {
      if (!bOwnsANC) {
        assert( ! bOwnsTAESpecifier );
      }

      // create the engine depending on the framework (UIMACPP or JEDII) or if it is primitive or aggregate.
      AnalysisEngineDescription const & crTAESpecifier = rANC.getTaeSpecifier();
      if (crTAESpecifier.getFrameworkImplName() == AnalysisEngineDescription::JAVA) {
        pResult = new uima::internal::JEDIIEngine( rANC, bOwnsANC, bOwnsTAESpecifier, casDefinition, ownsCASDefintion );
      } else {
        if (crTAESpecifier.isPrimitive()) {
          pResult = new uima::internal::PrimitiveEngine( rANC, bOwnsANC, bOwnsTAESpecifier, casDefinition, ownsCASDefintion );
        } else {
          pResult = new uima::internal::AggregateEngine( rANC, bOwnsANC, bOwnsTAESpecifier, casDefinition, ownsCASDefintion );
        }
      }

      if (pResult == NULL) {
        rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
        return NULL;
      }

      assert( EXISTS(pResult) );
      TyErrorId utErrorID = pResult->initialize( crTAESpecifier );
      if (utErrorID != UIMA_ERR_NONE) {
        ErrorInfo const & crLastError = pResult->getAnnotatorContext().getLogger().getLastError();
        if (crLastError.getErrorId() != UIMA_ERR_NONE) {
          rErrorInfo = crLastError;
        }
        // overwrite the error ID
        rErrorInfo.setErrorId( utErrorID );
        delete pResult;
        return NULL;
      }

      assert( EXISTS(pResult) );

      return  pResult;
    } catch (Exception & rExc) {
      rErrorInfo = rExc.getErrorInfo();
    }
    assert( rErrorInfo.getErrorId() != UIMA_ERR_NONE );
    if (pResult != NULL) {
      delete pResult;
    }
    return NULL;
  }


  TextAnalysisEngine * TextAnalysisEngine::createTAE(bool bIsFilename,
      icu::UnicodeString const & crString,
      ErrorInfo & rErrorInfo) {
		  return (TextAnalysisEngine*) Framework::createAnalysisEngine(bIsFilename,
			  crString, rErrorInfo);
	  }

    /*static*/
  /**   
   * create a TAE from a file name or an XML buffer (depending on first argument).
   */
  AnalysisEngine * Framework::createAnalysisEngine(bool bIsFilename,
      icu::UnicodeString const & crString,
      ErrorInfo & rErrorInfo) {
    try {
      rErrorInfo.reset();
      if (! ResourceManager::hasInstance()) {
        rErrorInfo.setErrorId(UIMA_ERR_ENGINE_RESMGR_NOT_INITIALIZED);
        return NULL;
      }

      /*
      We use quite a lot of auto_ptrs here because many of those methods can go wrong
      and throw exceptions but we still want to clean up all the memory we used thus far.
      */
      
	  XMLParser builder;
      auto_ptr<AnalysisEngineDescription> apTAESpecifier( new AnalysisEngineDescription() );
      if (apTAESpecifier.get() == NULL) {
        rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
        return NULL;
      }

      if (bIsFilename) {
        builder.parseAnalysisEngineDescription(* apTAESpecifier.get(), crString);
      } else {
        /*
           Some XML4C routines which have to do wiht parsing an in-memory 
           buffer don't work, so this is why we don't call
             builder.buildTaeFromMemory(* apTAESpecifier.get(), crString);
           here but rather create a temp file.
        */
        // Use what appears to be a thread-safe routine on Linux & Windows
        char* tmpFileName = tempnam(NULL, "TMP");

        ofstream ofs(tmpFileName);
        uima::operator<<(ofs, crString);
        ofs << endl;
        ofs.close();
        UIMA_TPRINT("Wrote descriptor to temp file:");
        UIMA_TPRINT(tmpFileName);
        builder.parseAnalysisEngineDescription(* apTAESpecifier.get(), tmpFileName);

        remove(tmpFileName);                // or unlink ??
        free(tmpFileName);                  // Free storage allocated by tempnam
      }

      apTAESpecifier->validate();
      apTAESpecifier->commit();

      auto_ptr<AnnotatorContext> apANC( new AnnotatorContext(apTAESpecifier.get()) );
      if (apANC.get() == NULL) {
        rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
        return NULL;
      }

      assert( EXISTS(apANC.get()) );

      auto_ptr<uima::internal::CASDefinition> apCASDef( uima::internal::CASDefinition::createCASDefinition(*apANC.get()) );
      // release auto_ptrs here because the createTAE transfers ownership to the engine
      //  Warning: this could cause a memory leak if the createTAE() method coudl not create
      //           the actual engine object.     suhre 02/11/03
      apTAESpecifier.release();
      AnalysisEngine * pResult = createAnalysisEngine(* apANC.release(), true,
                                     true,
                                     * apCASDef.release(), true,
                                     rErrorInfo);
           
      return pResult;
    } catch (Exception & rExc) {
      rErrorInfo = rExc.getErrorInfo();
    }
    assert( rErrorInfo.getErrorId() != UIMA_ERR_NONE );
    return NULL;
  }


     /*static*/
  TextAnalysisEngine * TextAnalysisEngine::createTextAnalysisEngine(char const * cpFileName, ErrorInfo & rErrorInfo) {
    icu::UnicodeString usFileName( cpFileName );
	return (TextAnalysisEngine*)Framework::createAnalysisEngine(cpFileName, rErrorInfo);
  }
    /*static*/
  AnalysisEngine * Framework::createAnalysisEngine(char const * cpFileName, ErrorInfo & rErrorInfo) {
    icu::UnicodeString usFileName( cpFileName );
    return createAnalysisEngine(true, usFileName, rErrorInfo);
  }


    /*static*/
  TextAnalysisEngine * TextAnalysisEngine::createTextAnalysisEngine(UChar const * cpBuffer, size_t uiLength, ErrorInfo & rErrorInfo) {
    
	  return (TextAnalysisEngine*)Framework::createAnalysisEngine(cpBuffer,uiLength, rErrorInfo);
  }

    /*static*/
  AnalysisEngine * Framework::createAnalysisEngine(UChar const * cpBuffer, 
				size_t uiLength, ErrorInfo & rErrorInfo) {
    // read-only constructor of unicode string
    icu::UnicodeString usXMLBuffer(false, cpBuffer, uiLength);
    return createAnalysisEngine(false, usXMLBuffer, rErrorInfo);
  }

    /*static*/
  TextAnalysisEngine * TextAnalysisEngine::createTextAnalysisEngine(AnalysisEngineDescription & crAEDesc, 
									ErrorInfo & rErrorInfo) {
		return (TextAnalysisEngine*) Framework::createAnalysisEngine(crAEDesc, rErrorInfo);
  }

    /*static*/
  AnalysisEngine * Framework::createAnalysisEngine(AnalysisEngineDescription & crTAESpec, ErrorInfo & rErrorInfo) {
    try {
      rErrorInfo.reset();
      if (! ResourceManager::hasInstance()) {
        rErrorInfo.setErrorId(UIMA_ERR_ENGINE_RESMGR_NOT_INITIALIZED);
        return NULL;
      }

      auto_ptr<AnnotatorContext> apANC( new AnnotatorContext(& crTAESpec) );
      if (apANC.get() == NULL) {
        rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
        return NULL;
      }

      assert( EXISTS(apANC.get()) );

      auto_ptr<uima::internal::CASDefinition> apCASDef( uima::internal::CASDefinition::createCASDefinition(*apANC.get()) );
      // release auto_ptrs here because the createTAE transfers ownership to the engine
      //  Warning: this could cause a memory leak if the createTAE() method coudl not create (construct)
      //           the actual engine object.     suhre 02/11/03
       AnalysisEngine * pResult = createAnalysisEngine(*apANC.release(), true,
                                     false,
                                     *apCASDef.release(), true,
                                     rErrorInfo);
      return pResult;
    } catch (Exception & rExc) {
      rErrorInfo = rExc.getErrorInfo();
    }
    return NULL;
  }




  /* ------------------------------------------------
   *  uima::Framework methods
   * ----------------------------------------------- */
  //create typesystem and set type priorities
  TypeSystem * Framework::createTypeSystem(AnalysisEngineMetaData const & ae, ErrorInfo& rErrorInfo) {
    rErrorInfo.reset();
    if (! ResourceManager::hasInstance()) {
      rErrorInfo.setErrorId(UIMA_ERR_ENGINE_RESMGR_NOT_INITIALIZED);
      return NULL;
    }

    uima::TypeSystem * pTs =  uima::internal::CASDefinition::createTypeSystem(ae);

    return pTs;
  }

  //create typesystem from description
  TypeSystem * Framework::createTypeSystem(TypeSystemDescription const & tsDesc,
      icu::UnicodeString const & creatorID,
      ErrorInfo& rErrorInfo) {
    rErrorInfo.reset();
    if (! ResourceManager::hasInstance()) {
      rErrorInfo.setErrorId(UIMA_ERR_ENGINE_RESMGR_NOT_INITIALIZED);
      return NULL;
    }

    uima::TypeSystem * pTs =  uima::internal::CASDefinition::createTypeSystem(tsDesc,creatorID);

    return pTs;
  }

  //create typesystem from description and set type priorities
  TypeSystem * Framework::createTypeSystem(TypeSystemDescription const & tsDesc,
      uima::AnalysisEngineMetaData::TyVecpTypePriorities const & typePriorities,
      icu::UnicodeString const & creatorID,
      ErrorInfo& rErrorInfo) {
    rErrorInfo.reset();
    if (! ResourceManager::hasInstance()) {
      rErrorInfo.setErrorId(UIMA_ERR_ENGINE_RESMGR_NOT_INITIALIZED);
      return NULL;
    }

    uima::TypeSystem * pTs =  uima::internal::CASDefinition::createTypeSystem(tsDesc,typePriorities,creatorID);

    return pTs;
  }


  //read in descriptor from and create TypeSystem per the specification
  TypeSystem * Framework::createTypeSystem(char const * crFileName, ErrorInfo& rErrorInfo) {

    XMLParser builder;
    AnalysisEngineMetaData * pAe = new AnalysisEngineMetaData();
	TypeSystemDescription * tsDesc = new TypeSystemDescription();
	
	UnicodeString ufn(crFileName);
    size_t uiLen = ufn.length();
    auto_array<UChar> arBuffer( new UChar[uiLen + 1] );
    assert( EXISTS(arBuffer.get()));
    ufn.extract(0, uiLen, arBuffer.get());
    (arBuffer.get())[uiLen] = 0; // terminate the buffer with 0

	LocalFileInputSource fileIS((XMLCh const *) arBuffer.get());

	builder.parseTypeSystemDescription(*tsDesc, fileIS);
    pAe->setTypeSystemDescription(tsDesc);

    auto_ptr<AnalysisEngineMetaData> apSpecifier(pAe  );
    if (apSpecifier.get() == NULL) {
      rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
      return NULL;
    }

    uima::TypeSystem * pTs =  uima::internal::CASDefinition::createTypeSystem(*apSpecifier.get());
    return pTs;
  }


  //read in xml descriptor from buffer and create typesystem per those specifications
  TypeSystem * Framework::createTypeSystem(UChar const * cpBuffer,
      size_t uiLength,
      ErrorInfo& rErrorInfo) {
    UnicodeStringRef usRef(cpBuffer, uiLength);
    XMLParser builder;
    AnalysisEngineMetaData * pAe = new AnalysisEngineMetaData();
	TypeSystemDescription * tsDesc = new TypeSystemDescription();
    MemBufInputSource memIS((XMLByte const *)usRef.asUTF8().c_str(),
		                    usRef.asUTF8().length(),
							"sysID");
	builder.parseTypeSystemDescription(*tsDesc,memIS);
    pAe->setTypeSystemDescription(tsDesc);

    auto_ptr<AnalysisEngineMetaData> apSpecifier(pAe  );
    if (apSpecifier.get() == NULL) {
      rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
      return NULL;
    }

    uima::TypeSystem * pTs =  uima::internal::CASDefinition::createTypeSystem(*apSpecifier.get());
    return pTs;

  }

  //read in xml descriptor from buffer and create typesystem per those specifications
  TypeSystem * Framework::createTypeSystemFromXMLBuffer( char const * cpBuffer,
      ErrorInfo& rErrorInfo) {
    XMLParser builder;
    AnalysisEngineMetaData * pAe = new AnalysisEngineMetaData();
	MemBufInputSource memIS((XMLByte const *) cpBuffer, strlen(cpBuffer), "sysID");
	TypeSystemDescription * tsDesc = new TypeSystemDescription();
	builder.parseTypeSystemDescription(*tsDesc, memIS);
    pAe->setTypeSystemDescription(tsDesc);

    auto_ptr<AnalysisEngineMetaData> apSpecifier(pAe  );
    if (apSpecifier.get() == NULL) {
      rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
      return NULL;
    }

    uima::TypeSystem * pTs =  uima::internal::CASDefinition::createTypeSystem(*apSpecifier.get());
    return pTs;

  }



  //create CAS with specified typesystem and only built in indices
  CAS * Framework::createCAS(TypeSystem & typesystem, ErrorInfo& rErrorInfo) {
    auto_ptr<uima::internal::CASDefinition> apCASDef( uima::internal::CASDefinition::createCASDefinition(typesystem) );
    if (apCASDef.get() == NULL) {
      rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
      return NULL;
    }

    CAS * pCas = uima::internal::CASImpl::createCASImpl(*apCASDef.release(), true);

    return pCas->getInitialView();
  }



  //create CAS with specified typesystem and indices/typePriorities defined in the AE descriptor
  CAS * Framework::createCAS(TypeSystem & typesystem, AnalysisEngineMetaData & aeDesc, ErrorInfo & rErrorInfo) {
    auto_ptr<uima::internal::CASDefinition> apCASDef( uima::internal::CASDefinition::createCASDefinition(typesystem, aeDesc) );
    if (apCASDef.get() == NULL) {
      rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
      return NULL;
    }
    CAS * pCas = uima::internal::CASImpl::createCASImpl(*apCASDef.release(), true);
    return pCas->getInitialView();
  }


  CAS * Framework::createCAS(TypeSystem & typesystem,
                             AnalysisEngineMetaData::TyVecpFSIndexDescriptions & fsIndexDesc,
                             AnalysisEngineMetaData::TyVecpTypePriorities  & prioDesc,
                             ErrorInfo & rErrorInfo)  {
    auto_ptr<uima::internal::CASDefinition>
    apCASDef( uima::internal::CASDefinition::createCASDefinition(typesystem, fsIndexDesc, prioDesc) );
    if (apCASDef.get() == NULL) {
      rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
      return NULL;
    }
    CAS * pCas = uima::internal::CASImpl::createCASImpl(*apCASDef.release(), true);
    return pCas->getInitialView();


  }

  //create TypeSystemDescription object from xml spec in buffer
  TypeSystemDescription * Framework::createTypeSystemDescription(UChar const * cpBuffer, size_t uiLength) {
    UnicodeStringRef usRef(cpBuffer, uiLength);
    XMLParser builder;
    TypeSystemDescription * tsDesc = new TypeSystemDescription();
    MemBufInputSource memIS((XMLByte const *) usRef.asUTF8().c_str(), 
		                     usRef.asUTF8().length(), "sysID");
	builder.parseTypeSystemDescription(*tsDesc,memIS);
    return tsDesc;
  }

  //read in xml from a file and create a TypeSystemDescription object
  TypeSystemDescription * Framework::createTypeSystemDescription(char const * crFileName) {
    XMLParser builder;
	LocalFileInputSource fileIS((XMLCh const *)crFileName);
	TypeSystemDescription * tsDesc = new TypeSystemDescription();
    builder.parseTypeSystemDescription(*tsDesc,fileIS);
	return tsDesc;
  }


  CAS * Framework::createCAS(uima::internal::CASDefinition & casdef, ErrorInfo & rErrorInfo) {
    CAS * pCas = uima::internal::CASImpl::createCASImpl(casdef, false);
    if (pCas == NULL) {
      rErrorInfo.setErrorId(UIMA_ERR_ENGINE_OUT_OF_MEMORY);
      return NULL;
    }
    return pCas->getInitialView();
  }






}


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





