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

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


/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */

#include "uima/pragmas.hpp"

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

#include "uima/resmgr.hpp"

#include <iostream>
#include "uima/lowlevel_indexiterator.hpp"
#include "uima/lowlevel_fsheap.hpp"
#include "uima/lowlevel_typesystem.hpp"

#include "uima/fsfilterbuilder.hpp"
#include "uima/cas.hpp"
#include "uima/listfs.hpp"
#include "uima/arrayfs.hpp"

#include "uima/lowlevel_indexrepository.hpp"
#include "uima/lowlevel_fsfilter.hpp"

#include "uima/xmltypesystemreader.hpp"

#include "xercesc/util/PlatformUtils.hpp"
#include "xercesc/sax/SAXParseException.hpp"

#include "uima/internal_casimpl.hpp"
#include "uima/internal_fspromoter.hpp"
#include "uima/fsindexrepository.hpp"
#include "uima/typenamespace.hpp"
#include "uima/tt_types.hpp"
#include "uima/internal_aggregate_engine.hpp"
#include "uima/casdefinition.hpp"
#include "uima/taespecifierbuilder.hpp"
#include "xercesc/parsers/XercesDOMParser.hpp"
#include "xercesc/parsers/SAXParser.hpp"
#include "xercesc/dom/DOMException.hpp"
#include "xercesc/dom/DOMNamedNodeMap.hpp"
#include "xercesc/dom/DOMDocument.hpp"
#include "xercesc/dom/DOMElement.hpp"
#include "xercesc/dom/DOMNodeList.hpp"
#include "xercesc/framework/MemBufInputSource.hpp"
#include "uima/xmlerror_handler.hpp"

using namespace uima;
using namespace uima::internal;

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

#ifndef NDEBUG
#define ASSERT_OR_THROWEXCEPTION(x) assert(x)
#else
#define ASSERT_OR_THROWEXCEPTION(x) if (!(x)) { cerr << __FILE__ << ": Error in line " << __LINE__ << endl; exit(1); }
#endif


#define LOG(x) cout << "[" << __FILE__ << ", " << __LINE__ << "]: " << x << endl

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

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

/* ----------------------------------------------------------------------- */
/*       Implementation                                                    */
/* ----------------------------------------------------------------------- */

static icu::UnicodeString ustrCreatorID("test");

namespace uima {
  namespace internal {
    class TTDefinition : public CASDefinition {
    public:
      void createTTTAESpecifier(TextAnalysisEngineSpecifier & result) {
        /* insert lines to match original code so LOG msgs have same line numbers!
        */
        const util::Location & crDataDir = ResourceManager::getInstance().getLocationData();
        std::string nameInDataDir(crDataDir.getAsCString() );
        nameInDataDir += "descriptors";

        util::Filename typesystemFile(nameInDataDir.c_str(),"tt_typesystem.xml");
        typesystemFile.normalize();

        util::Filename indexesFile(nameInDataDir.c_str(),"tt_indexes.xml");
        indexesFile.normalize();

        icu::UnicodeString typesystemFileUnicode( typesystemFile.getAsCString() );
        icu::UnicodeString indexesFileUnicode( indexesFile.getAsCString() );

        // add the typesystem from an xml file
		std::string tt_types("<?xml version=\"1.0\"?> <taeDescription><analysisEngineMetaData> <typeSystemDescription> <imports> <import location=\"");
        tt_types.append( typesystemFile.getAsCString() );
 
        tt_types.append("\"/> </imports> </typeSystemDescription> <fsIndexCollection> <imports> <import location=\"");
        tt_types.append(indexesFile.getAsCString() );
        tt_types.append("\"/> </imports> </fsIndexCollection> </analysisEngineMetaData> </taeDescription>");

        uima::TextAnalysisEngineSpecifierBuilder builder;
        XercesDOMParser parser;
        uima::XMLErrorHandler errorHandler;
        parser.setErrorHandler(& errorHandler);

		MemBufInputSource memSource((XMLByte const *) tt_types.c_str(), tt_types.length(), "TT typesystem" );

        ///XIncluder includer;
        ///InputSource const & is = includer.resolveXIncludes(memSource);
        ///parser.parse( is );
        parser.parse(memSource);
        DOMDocument* doc = parser.getDocument();
        assert(EXISTS(doc));

        // get top node
        DOMElement * rootElem = doc->getDocumentElement();
        assert(EXISTS(rootElem));

        //         icu::UnicodeString fileLoc( typesystemFile.getAsCString() );
        builder.buildTae(result, rootElem, ".");
      }

      void createPredefinedTTTypes() {
        TextAnalysisEngineSpecifier specifier;
        createTTTAESpecifier(specifier);

        mergeTypeSystem(specifier);

        addTypePriorities(specifier);
      }


      void createPredefinedTTIndexes() {
        TextAnalysisEngineSpecifier specifier;
        createTTTAESpecifier(specifier);

        uima::AnnotatorContext anc(& specifier);
        createIndexesFromANC(anc);
      }

      void createTypes() {
        CASDefinition::createTypes();
        createPredefinedTTTypes();
      }

      void createIndexes() {
        CASDefinition::createIndexes();
        createPredefinedTTIndexes();
      }



      TTDefinition()
          : CASDefinition(NULL) {}


      ~TTDefinition()   { }

      void commitTypeSystem() {
        CASDefinition::commitTypeSystem();
      }

      void commitIndexDefinition() {
        CASDefinition::commitIndexDefinition();
      }


    };
  }
}

uima::internal::CASImpl * getCASImpl(uima::internal::CASDefinition & casDef) {
  ErrorInfo errorInfo;
  return (uima::internal::CASImpl*) Framework::createCAS(casDef, errorInfo);
}


class TestCAS {
  uima::internal::TTDefinition * iv_casDef;
  uima::internal::CASImpl * iv_cas;
public:
  TestCAS()
      : iv_casDef() {
    iv_casDef = new uima::internal::TTDefinition();
    iv_casDef->init();
    iv_casDef->commit();
//       iv_cas = new uima::internal::TCASImpl(*iv_casDef, 5000, 5000, 5000);
    ErrorInfo errorInfo;
    iv_cas =  (uima::internal::CASImpl*)Framework::createCAS(*iv_casDef, errorInfo);
  }
  ~TestCAS() {
    delete iv_cas;
    delete iv_casDef;
  }

  uima::internal::TTDefinition & getCASDef() {
    return *iv_casDef;
  }
  uima::internal::CASImpl & getCAS() {
    return * iv_cas;
  }
};

/*
void prepareCAS(CAS & cas) {
   uima::internal::TCASImpl & tcas = uima::internal::TCASImpl::promoteCAS(cas);
   tcas.createPredefinedTTTypes();

   tcas.commitTypeSystem();

   tcas.createPredefinedTTIndexes();
}
*/


void testLowLevelTypeSystem() {
  LOG("testLowlevelTypeSystem() started");


  ASSERT_OR_THROWEXCEPTION( uima::TypeSystem::NAMESPACE_SEPARATOR == UIMA_NAMESPACE_SEPARATOR_CHAR );
  ASSERT_OR_THROWEXCEPTION( uima::TypeSystem::FEATURE_SEPARATOR == UIMA_TYPE_FEATURE_SEPARATOR_CHAR);

  /*
    top
       t1 [f1: t3, g1:t4]
         t11 [f11: t21]
            t111
         t12 [f12: t211]
         t13 [f13: t14]
            t131 [f131: t132, g131: top]
            t132
         t14 [f14: t2]
       t2 [f2:t2]
         t21 [f21:t2, g21: t211]
           t211
              t2111
       t3
         t31 [f31: t32, g31: t321]
         t32
            t321 [f321: t4]
       t4
   */
  TTDefinition ttdef;
  ttdef.init();
  lowlevel::TypeSystem& ts = ttdef.getTypeSystem();

  lowlevel::TyFSType top = ts.getTopType();
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(top) );
  lowlevel::TyFSType t1 = ts.createType(top, "t1", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t1) );
  lowlevel::TyFSType t2 = ts.createType(top, "t2", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t2) );
  lowlevel::TyFSType t3 = ts.createType(top, "t3", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t3) );
  lowlevel::TyFSType t31 = ts.createType(t3, "t31", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t31) );
  lowlevel::TyFSType t32 = ts.createType(t3, "t32", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t32) );
  lowlevel::TyFSType t321 = ts.createType(t32, "t321", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t321) );
  lowlevel::TyFSType t4 = ts.createType(top, "t4", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t4) );
  lowlevel::TyFSType t21 = ts.createType(t2, "t21", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t21) );
  lowlevel::TyFSType t211 = ts.createType(t21, "t211", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t211) );
  lowlevel::TyFSType t2111 = ts.createType(t211, "t2111", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t2111) );
  lowlevel::TyFSType t11 = ts.createType(t1, "t11", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t11) );
  lowlevel::TyFSType t111 = ts.createType(t11, "t111", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t111) );
  lowlevel::TyFSType t12 = ts.createType(t1, "t12", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t12) );
  lowlevel::TyFSType t13 = ts.createType(t1, "t13", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t13) );
  lowlevel::TyFSType t14 = ts.createType(t1, "t14", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t14) );
  lowlevel::TyFSType t131 = ts.createType(t13, "t131", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t131) );
  lowlevel::TyFSType t132 = ts.createType(t13, "t132", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t132) );

  lowlevel::TyFSFeature f1 = ts.createFeature(t1, t3, false, "f1", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f1) );
  lowlevel::TyFSFeature g1 = ts.createFeature(t1, t4, false, "g1", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(g1) );
  lowlevel::TyFSFeature f11 = ts.createFeature(t11, t21, false, "f11", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f11) );
  lowlevel::TyFSFeature f12 = ts.createFeature(t12, t211, false, "f12", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f12) );
  lowlevel::TyFSFeature f13 = ts.createFeature(t13, t14, false, "f13", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f13) );
  lowlevel::TyFSFeature f131 = ts.createFeature(t131, t132, false, "f131", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f131) );
  lowlevel::TyFSFeature g131 = ts.createFeature(t131, top, false, "g131", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(g131) );
  lowlevel::TyFSFeature f14 = ts.createFeature(t14, t2, false, "f14", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f14) );
  lowlevel::TyFSFeature f2 = ts.createFeature(t2, t2, false, "f2", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f2) );
  lowlevel::TyFSFeature f21 = ts.createFeature(t21, t2, false, "f21", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f21) );
  lowlevel::TyFSFeature g21 = ts.createFeature(t21, t211, false, "g21", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(g21) );
  lowlevel::TyFSFeature f31 = ts.createFeature(t31, t32, false, "f31", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f31) );
  lowlevel::TyFSFeature g31 = ts.createFeature(t31, t321, false, "g31", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(g31) );
  lowlevel::TyFSFeature f321 = ts.createFeature(t321, t4, false, "f321", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f321) );

  ttdef.commit();

  assert( ts.debugIsConsistent() );
#ifndef NDEBUG
  ts.print(cout);
#endif

  // check subsumption
#define SUBSCHECK_N 17
  lowlevel::TyFSType subscheck[SUBSCHECK_N][2] = {
        {top, t1},     // 1
        {top, top},    // 2
        {t11, t111},  // 3
        {t13, t131}, // 4
        {t13, t132}, // 5
        {t2, t21}, // 6
        {t21, t211}, // 7
        {t211, t2111}, // 8
        {t3, t31}, // 9
        {t3, t32}, // 10
        {t4, t4}, // 11
        {top, t2111}, // 12
        {t1, t111}, // 13
        {t2, t2111}, // 14
        {t3, t321}, // 15
        {top, t321}, // 16
        {top, top}  // 17
      };

  int i;
  for (i=0; i<SUBSCHECK_N; ++i) {
    lowlevel::TyFSType st1 = subscheck[i][0];
    lowlevel::TyFSType st2 = subscheck[i][1];
    ASSERT_OR_THROWEXCEPTION( ts.subsumes(st1, st2) );
    if (st1 == st2) {
      ASSERT_OR_THROWEXCEPTION( ts.subsumes(st2, st1) );
    } else {
      ASSERT_OR_THROWEXCEPTION( ! ts.subsumes(st2, st1) );
    }

  }

  // check appropriateness
#define APPROPCHECK 14
  int appropcheck[APPROPCHECK][2] = {
                                      {
                                        t1, f1
                                      }
                                      , // 0
                                      {t1, g1}, // 1
                                      {t111, f1}, //2
                                      {t12, g1}, //3
                                      {t131, g1}, //4
                                      {t131, f131}, //5
                                      {t131, g131}, //6
                                      {t14, f14}, //7
                                      {t21, f21}, //8
                                      {t211, f21}, //9
                                      {t2111, f21}, //10
                                      {t31, f31}, //11
                                      {t31, f31}, //12
                                      {t321, f321} //13
                                    };

  for (i=0; i< APPROPCHECK; ++i) {
    lowlevel::TyFSType act = appropcheck[i][0];
    lowlevel::TyFSFeature acf = appropcheck[i][1];

    UIMA_TPRINT(" Checking approp: feature " << acf << ", type " << act);
    ASSERT_OR_THROWEXCEPTION( ts.isAppropriateFeature(act, acf) );

    ASSERT_OR_THROWEXCEPTION( acf == ts.getFeatureFromOffset(act, ts.getFeatureOffset( acf) ) );

  }

  LOG("  Testing OO API TypeSystem calls");
  Type oot1 = ts.getType("t1");
  ASSERT_OR_THROWEXCEPTION( oot1.isValid() );
  Type oot11 = ts.getType("t11");
  ASSERT_OR_THROWEXCEPTION( oot11.isValid() );

  ASSERT_OR_THROWEXCEPTION( oot1.subsumes(oot11) );
  ASSERT_OR_THROWEXCEPTION( ! oot11.subsumes(oot1) );

//   FeatureStructure oofs11 = cas.createFS(oot11);

  LOG("  Finished Testing OO API TypeSystem calls");


  LOG("testLowlevelTypeSystem() finished");
}


void testLowLevelTypeSystemExceptions() {
  LOG("testLowlevelTypeSystenExceptions() started");

  TTDefinition ttdef;
  ttdef.init();

  uima::lowlevel::TypeSystem & rTypeSystem = ttdef.getTypeSystem();

  uima::lowlevel::TyFSType intType = rTypeSystem.getTypeByName(CAS::TYPE_NAME_INTEGER);

  bool bExceptionThrown = false;

  LOG("Creating feature on top");
  try {
    rTypeSystem.createFeature( rTypeSystem.getTopType(), intType, false, "bla", "test");
  } catch (uima::lowlevel::FeatureIntroductionFailedException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION( bExceptionThrown );

  LOG("Creating subtype of integer");
  bExceptionThrown = false;
  try {
    rTypeSystem.createType( intType, "bla", "test");
  } catch (uima::lowlevel::TypeCreationFailedException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION( bExceptionThrown );

  LOG("Creating feature on integer");
  bExceptionThrown = false;
  try {
    rTypeSystem.createFeature( intType, intType, false, "bla", "test");
  } catch (uima::lowlevel::FeatureIntroductionFailedException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION( bExceptionThrown );

  LOG("testLowlevelTypeSystenExceptions() finished");
}


/************************************************************************************/
/*
void testOOTypeSystem() {
   LOG("testOOTypeSystem() started");
   / *
     top
        t1 [f1: t3, g1:t4]
          t11 [f11: t21]
             t111
          t12 [f12: t211]
          t13 [f13: t14]
             t131 [f131: t132, g131: top]
             t132
          t14 [f14: t2]
        t2 [f2:t2]
          t21 [f21:t2, g21: t211]
            t211
               t2111
        t3
          t31 [f31: t32, g31: t321]
          t32
             t321 [f321: t4]
        t4
    * /

   Type someType;
   ASSERT_OR_THROWEXCEPTION( ! someType.isValid() );
   Feature someFeature;
   ASSERT_OR_THROWEXCEPTION( ! someFeature.isValid() );

   uima::internal::TCASImpl cas(50000);
   FSSystem & fsSystem = cas.getFSSystem();
   Type top = fsSystem.getTopType();
   Type t1 = top.addSubType("t1");
   ASSERT_OR_THROWEXCEPTION( t1.isValid() );
   Type t2 = top.addSubType("t2");
   ASSERT_OR_THROWEXCEPTION( t2.isValid() );
   Type t21 = t2.addSubType("t21");
   ASSERT_OR_THROWEXCEPTION( t21.isValid() );
   Type t3 = top.addSubType("t3");
   ASSERT_OR_THROWEXCEPTION( t3.isValid() );
   Type t4 = top.addSubType("t4");
   ASSERT_OR_THROWEXCEPTION( t4.isValid() );

   Feature f1 = t1.introduceFeature("f1", t3);
   ASSERT_OR_THROWEXCEPTION( f1.isValid() );
   Feature g1 = t1.introduceFeature("g1", t4);
   ASSERT_OR_THROWEXCEPTION( g1.isValid() );

   Type t11 = t1.addSubType("t11");
   ASSERT_OR_THROWEXCEPTION( t11.isValid() );
   Feature f11 = t11.introduceFeature("f11", t21);
   ASSERT_OR_THROWEXCEPTION( f11.isValid() );

   Type t11prime = fsSystem.findTypeByName("t11");
   ASSERT_OR_THROWEXCEPTION( t11 == t11prime );

   cas.commitTypeSystem();

   ASSERT_OR_THROWEXCEPTION( t1.subsumes(t11) );
   ASSERT_OR_THROWEXCEPTION( ! t11.subsumes(t1) );

   FeatureStructure fs11 = fsSystem.createFS(t11);


   LOG("testOOTypeSystem() finished");
}
*/


/************************************************************************************/

void testLowLevelFSHeap() {
  LOG("testLowlevelFSHeap started");

  TestCAS testcas;
  lowlevel::TypeSystem& ts = testcas.getCASDef().getTypeSystem();


  assert( ts.debugIsConsistent() );
  LOG("Type system commited");

  lowlevel::FSHeap & heap = testcas.getCAS().getHeap();
//   FSHeap heap(ts, 50000);
  LOG("Creating annotation name string");
  icu::UnicodeString usAnnotationTypeName(CAS::TYPE_NAME_ANNOTATION);
  LOG(" annotation name string created");
  lowlevel::TyFSType annotationType = ts.getTypeByName( usAnnotationTypeName );
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(annotationType) );
  lowlevel::TyFSFeature beginPosFeat = ts.getFeatureByBaseName(annotationType, CAS::FEATURE_BASE_NAME_BEGIN );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(beginPosFeat) );
  lowlevel::TyFSFeature endPosFeat = ts.getFeatureByBaseName( annotationType, CAS::FEATURE_BASE_NAME_END );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(endPosFeat) );

  lowlevel::TyFSType tokenAnnotationType = ts.getTypeByName( TT::TYPE_NAME_TOKEN_ANNOTATION );
  ASSERT_OR_THROWEXCEPTION( ts.isValidType( tokenAnnotationType ) );
  lowlevel::TyFSFeature lemmaEntryFeat = ts.getFeatureByBaseName( tokenAnnotationType, TT::FEATURE_BASE_NAME_LEMMA_ENTRIES );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature( lemmaEntryFeat ) );

  lowlevel::TyFSType lemmaType = ts.getTypeByName( TT::TYPE_NAME_LEMMA );
  ASSERT_OR_THROWEXCEPTION( ts.isValidType( lemmaType ) );
  lowlevel::TyFSType keyFeature = ts.getFeatureByBaseName( lemmaType, TT::FEATURE_BASE_NAME_KEY );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature( keyFeature ) );

  lowlevel::TyFSType listType = ts.getTypeByName(CAS::TYPE_NAME_FS_LIST );
  ASSERT_OR_THROWEXCEPTION( ts.isValidType( listType ) );
  lowlevel::TyFSType ne_listType = ts.getTypeByName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST );
  ASSERT_OR_THROWEXCEPTION( ts.isValidType( ne_listType ) );
  lowlevel::TyFSType e_listType = ts.getTypeByName(CAS::TYPE_NAME_EMPTY_FS_LIST );
  ASSERT_OR_THROWEXCEPTION( ts.isValidType( e_listType ) );
  lowlevel::TyFSFeature headFeature = ts.getFeatureByBaseName(ne_listType, CAS::FEATURE_BASE_NAME_HEAD );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature( headFeature ) );
  lowlevel::TyFSFeature tailFeature = ts.getFeatureByBaseName(ne_listType, CAS::FEATURE_BASE_NAME_TAIL );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature( tailFeature ) );

  lowlevel::TyFS annot1 = heap.createFS(annotationType);
  ASSERT_OR_THROWEXCEPTION( heap.getType(annot1) == annotationType );
  heap.setIntValue(annot1, beginPosFeat, 42);
  ASSERT_OR_THROWEXCEPTION( heap.getIntValue(annot1, beginPosFeat) == 42 );
  heap.setIntValue(annot1, endPosFeat, 37);
  ASSERT_OR_THROWEXCEPTION( heap.getIntValue(annot1, endPosFeat) == 37 );


  lowlevel::TyFS lemma1 = heap.createFS(lemmaType);
  icu::UnicodeString uskey("lemmaKey");
  UnicodeStringRef ulsKey(uskey.getBuffer(), uskey.length());

//   lowlevel::TyFS stringFS = heap.createStringFeatureStructure(ulsKey);
  int ulsOff = heap.addString(ulsKey);
  heap.setStringValue(lemma1, keyFeature, ulsOff);
  UnicodeStringRef ulsKey1 = heap.getFSAsString( heap.getFSValue(lemma1, keyFeature) );
  ASSERT_OR_THROWEXCEPTION( ulsKey1 == ulsKey );

  lowlevel::TyFS lemmaList = heap.createFS( heap.getTypeSystem().getTypeByName(CAS::TYPE_NAME_FS_LIST) );


  lowlevel::TyFS tokenAnnot1 = heap.createFS(tokenAnnotationType);
  ASSERT_OR_THROWEXCEPTION( heap.getType(tokenAnnot1) == tokenAnnotationType );
  heap.setIntValue(tokenAnnot1, beginPosFeat, 43);
  ASSERT_OR_THROWEXCEPTION( heap.getIntValue(tokenAnnot1, beginPosFeat) == 43 );
  heap.setIntValue(tokenAnnot1, endPosFeat, -37);
  ASSERT_OR_THROWEXCEPTION( heap.getIntValue(tokenAnnot1, endPosFeat) == -37 );
  heap.setFSValue(tokenAnnot1, lemmaEntryFeat, lemmaList);
  ASSERT_OR_THROWEXCEPTION( heap.getFSValue(tokenAnnot1, lemmaEntryFeat) == lemmaList );

  lowlevel::TyFS tokenAnnot2 = heap.createFS(tokenAnnotationType);
  ASSERT_OR_THROWEXCEPTION( heap.getType(tokenAnnot2) == tokenAnnotationType );
  heap.setIntValue(tokenAnnot2, beginPosFeat, 0);
  ASSERT_OR_THROWEXCEPTION( heap.getIntValue(tokenAnnot2, beginPosFeat) == 0 );
  heap.setIntValue(tokenAnnot2, endPosFeat, 5);
  ASSERT_OR_THROWEXCEPTION( heap.getIntValue(tokenAnnot2, endPosFeat) == 5 );
  heap.setFSValue(tokenAnnot2, lemmaEntryFeat, lemmaList);
  ASSERT_OR_THROWEXCEPTION( heap.getFSValue(tokenAnnot2, lemmaEntryFeat) == lemmaList );

  LOG("testLowlevelFSHeap finished");
}


/************************************************************************************/

struct StrAnnotation {
  lowlevel::TyFSType type;
  int begin;
  int end;
};

struct StrToken {
  StrAnnotation annot;
  size_t lemma;
};


struct StrSentence {
  StrAnnotation annot;
};


struct StrLemma {
  lowlevel::TyFSType type;
  int keyIndex;
//   icu::UnicodeString* key;
  int pos;
};


void checkForwardOrder(lowlevel::FSHeap const & heap, auto_ptr<uima::lowlevel::IndexIterator> & it, uima::lowlevel::IndexComparator const * cpComp, vector<lowlevel::TyFS> const & fsVec) {
  size_t i=0;
  vector<lowlevel::TyFS> retrievedFSs;
  for (it->moveToFirst(); it->isValid(); it->moveToNext()) {
    LOG("  Found FS");
    retrievedFSs.push_back(it->get());
  }

  // check that FSs were retrieved in correct order
  LOG("retrieved FSs: " << retrievedFSs.size() << ", expected FSs: " << fsVec.size());
  ASSERT_OR_THROWEXCEPTION(retrievedFSs.size() == fsVec.size());

  for (i=0; i<retrievedFSs.size(); ++i) {
    if (retrievedFSs[i] != fsVec[i]) {
      // if the FSs are not token identical, they must be equal w.r.t. the comparator of the index
//         ASSERT_OR_THROWEXCEPTION( ix.getComparator()->compare( retrievedFSs[i], fsVec[i] ) == 0 );
      ASSERT_OR_THROWEXCEPTION( cpComp->compare(heap, retrievedFSs[i], fsVec[i] ) == 0 );
    }
  }

}


void checkReverseOrder(lowlevel::FSHeap const & heap,auto_ptr<uima::lowlevel::IndexIterator> & it, uima::lowlevel::IndexComparator const * cpComp, vector<lowlevel::TyFS> const & fsVec) {
  size_t i=0;
  vector<lowlevel::TyFS> retrievedFSs;
  for (it->moveToLast(); it->isValid(); it->moveToPrevious()) {
    LOG("  found FS");
    retrievedFSs.push_back(it->get());
  }
  LOG("retrieved FSs: " << retrievedFSs.size() << ", expected FSs: " << fsVec.size());
  ASSERT_OR_THROWEXCEPTION(retrievedFSs.size() == fsVec.size());
  for (i=0; i<retrievedFSs.size(); ++i) {
    size_t revi = fsVec.size() - i - 1;
    if (retrievedFSs[i] != fsVec[revi] ) {
      // if the FSs are not token identical, they must be equal w.r.t. the comparator of the index
      ASSERT_OR_THROWEXCEPTION( cpComp->compare(heap, retrievedFSs[i], fsVec[revi] ) == 0 );
    }
  }

}

void checkPreviousNextMovements(auto_ptr<uima::lowlevel::IndexIterator> & it, uima::lowlevel::IndexComparator const * cpComp, vector<lowlevel::TyFS> const & fsVec) {
  size_t i=0;
  vector<lowlevel::TyFS> retrievedFSs;
  for (it->moveToLast(); it->isValid(); it->moveToPrevious()) {
    LOG("  found FS");
    retrievedFSs.push_back(it->get());
  }
  LOG("retrieved FSs: " << retrievedFSs.size() << ", expected FSs: " << fsVec.size());
  ASSERT_OR_THROWEXCEPTION(retrievedFSs.size() == fsVec.size());

  size_t n = retrievedFSs.size();
  it->moveToFirst();
  for (i=0; i<n-1; ++i) {
    ASSERT_OR_THROWEXCEPTION(it->isValid());
    uima::lowlevel::TyFS current = it->get();
    LOG("move forward");
    it->moveToNext();
    ASSERT_OR_THROWEXCEPTION(it->isValid());
    //uima::lowlevel::TyFS next = it->get();
    LOG("move back again");
    it->moveToPrevious();
    ASSERT_OR_THROWEXCEPTION(it->isValid());
    LOG("checking");
    ASSERT_OR_THROWEXCEPTION( it->get() == current );
  }

}



void checkOrderedIndex(uima::lowlevel::IndexABase const & ixBase, vector<lowlevel::TyFS> const & fsVec) {
  lowlevel::FSHeap const & heap = ixBase.getFSHeap();
  bool bIsMaximalType = ixBase.getFSHeap().getTypeSystem().isMaximalType( ixBase.getType() );

  uima::lowlevel::IndexComparator const * cpComp = NULL;
  if (bIsMaximalType) {
    uima::lowlevel::internal::OrderedSingleIndex const * cpIXSingle = (uima::lowlevel::internal::OrderedSingleIndex const *) & ixBase;
    cpComp = cpIXSingle->getComparator();
  } else {
    uima::lowlevel::internal::OrderedCompositeIndex const * cpIXComposite = (uima::lowlevel::internal::OrderedCompositeIndex const *) & ixBase;
    cpComp = cpIXComposite->getComparator();

  }
  ASSERT_OR_THROWEXCEPTION( EXISTS(cpComp) );
  auto_ptr<lowlevel::IndexIterator> it(ixBase.createIterator());

  LOG("checking forward order");
  checkForwardOrder(heap, it, cpComp, fsVec);

  LOG("checking reverse order");
  checkReverseOrder(heap, it, cpComp, fsVec);

  LOG("checking forward order again");
  checkForwardOrder(heap, it, cpComp, fsVec);

  LOG("checking forward order again");
  checkForwardOrder(heap, it, cpComp, fsVec);

  LOG("checking reverse order again");
  checkReverseOrder(heap, it, cpComp, fsVec);


  LOG("checking moveToPrevious/moveToNext pairs");
  checkPreviousNextMovements(it, cpComp, fsVec);
}

void checkSetIndex(lowlevel::IndexABase const & ix, size_t num) {
  LOG("Checking set index");
  LOG("Index size: " << ix.getSize() );
  vector<lowlevel::TyFS> retrievedFSs;
  auto_ptr<lowlevel::IndexIterator> it(ix.createIterator());
  for (it->moveToFirst(); it->isValid(); it->moveToNext()) {
    retrievedFSs.push_back(it->get());
  }
  size_t i;
  for (i=0; i<retrievedFSs.size(); ++i) {
    LOG("FS retrieved: " << (int) retrievedFSs[i]);
  }
  LOG("Retrieved FSs: " << retrievedFSs.size() << ", expected FS: " << num);
  ASSERT_OR_THROWEXCEPTION( retrievedFSs.size() == num );
}

void testLowLevelIndex() {
  LOG("testLowlevelIndex started");

  TTDefinition ttdef;
  ttdef.init();
  ttdef.commitTypeSystem();
  lowlevel::TypeSystem & ts = ttdef.getTypeSystem();

  int i = 0;

  assert( ts.debugIsConsistent() );

  uima::lowlevel::IndexDefinition & ixDef = ttdef.getIndexDefinition();

  // get some types and features
  lowlevel::TyFSType annotType = ts.getTypeByName( CAS::TYPE_NAME_ANNOTATION );
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(annotType) );
  lowlevel::TyFSType lemmaType = ts.getTypeByName( TT::TYPE_NAME_LEMMA );
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(lemmaType) );
  lowlevel::TyFSType tokenAnnotType = ts.getTypeByName( TT::TYPE_NAME_TOKEN_ANNOTATION );
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(tokenAnnotType) );
  lowlevel::TyFSType sentAnnotType = ts.getTypeByName( TT::TYPE_NAME_SENTENCE_ANNOTATION );
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(sentAnnotType) );

  lowlevel::TyFSFeature beginPosFeat = ts.getFeatureByBaseName( annotType, CAS::FEATURE_BASE_NAME_BEGIN );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(beginPosFeat) );
  lowlevel::TyFSFeature endPosFeat = ts.getFeatureByBaseName( annotType, CAS::FEATURE_BASE_NAME_END );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(endPosFeat) );
  lowlevel::TyFSFeature keyFeat = ts.getFeatureByBaseName( lemmaType, TT::FEATURE_BASE_NAME_KEY );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(keyFeat) );
  lowlevel::TyFSFeature posFeat = ts.getFeatureByBaseName( lemmaType, TT::FEATURE_BASE_NAME_PART_OF_SPEECH );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(posFeat) );
  lowlevel::TyFSFeature lemmaEntryFeat = ts.getFeatureByBaseName( tokenAnnotType, TT::FEATURE_BASE_NAME_LEMMA_ENTRIES );
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(lemmaEntryFeat) );

  // prepare comparators
  vector<lowlevel::TyFSFeature> tokenKeyFeatures;
  vector<uima::lowlevel::IndexComparator::EnKeyFeatureComp> tokenComparators;
  tokenKeyFeatures.push_back(beginPosFeat);
  tokenKeyFeatures.push_back(endPosFeat);
  tokenComparators.resize(2, uima::lowlevel::IndexComparator::STANDARD_COMPARE );
//   lowlevel::IndexComparator annotComp(heap, annotType, keyFeatures);

  vector<lowlevel::TyFSFeature> lemmaKeyFeatures;
  vector<uima::lowlevel::IndexComparator::EnKeyFeatureComp> lemmaComparators;
  lemmaKeyFeatures.push_back( keyFeat );
  lemmaKeyFeatures.push_back( posFeat );
  lemmaComparators.resize(2, uima::lowlevel::IndexComparator::STANDARD_COMPARE );
//   lowlevel::IndexComparator lemmaComp(heap, lemmaType, keyFeatures);

  // create indexes
  const icu::UnicodeString ORDEREDIX = "42";
  const icu::UnicodeString SETIX = "37";
  const icu::UnicodeString FIFOIX = "4711";
  ixDef.defineIndex(lowlevel::IndexDefinition::enOrdered, annotType, tokenKeyFeatures, tokenComparators, ORDEREDIX);
  ASSERT_OR_THROWEXCEPTION( ixDef.getIndexKind(ORDEREDIX) == lowlevel::IndexDefinition::enOrdered );
//   ASSERT_OR_THROWEXCEPTION( ixStore.getComparator(ORDEREDIX) == & annotComp );

  ixDef.defineIndex(lowlevel::IndexDefinition::enSet, lemmaType, lemmaKeyFeatures, lemmaComparators, SETIX);
  ASSERT_OR_THROWEXCEPTION( ixDef.getIndexKind(SETIX) == lowlevel::IndexDefinition::enSet );
//   ASSERT_OR_THROWEXCEPTION( ixStore.getComparator(SETIX) == & lemmaComp );
//   ixStore.createFIFOIndex(annotType, FIFOIX);

  ttdef.commitIndexDefinition();

  // create some feature structures
//#define LEMMA_NUM 5
  const size_t DUPLICATE_LEMMAS = 1;
  vector<icu::UnicodeString> lemmaStrings;
  lemmaStrings.push_back("s1");
  lemmaStrings.push_back("s2");
  lemmaStrings.push_back("s3");
  struct StrLemma lemmasTobeCreated[] = {
                                          {
                                            lemmaType, 0, 1
                                          }
                                          , // 0
                                          { lemmaType, 0, 1}, // 1
                                          { lemmaType, 1, 1}, // 2
                                          { lemmaType, 0, 2}, // 3
                                          { lemmaType, 2, 3}, // 4
                                          /*
                                          { lemmaType, & lemmaStrings[0], 1}, // 0
                                          { lemmaType, & lemmaStrings[0], 1}, // 1
                                          { lemmaType, & lemmaStrings[1], 1}, // 2
                                          { lemmaType, & lemmaStrings[0], 2}, // 3
                                          { lemmaType, & lemmaStrings[2], 3}, // 4
                                          */
                                        };
  size_t LEMMA_NUM = NUMBEROF(lemmasTobeCreated);

  struct StrToken tokensToBeCreated[] = {
                                          {
                                            tokenAnnotType, 0, 5, 0
                                          }
                                          ,  // 0
                                          { tokenAnnotType, 5, 8, 1},  // 1
                                          { tokenAnnotType, 5, 8, 1},  // 2
                                        };
//#define TOKEN_NUM 3
  size_t TOKEN_NUM = NUMBEROF(tokensToBeCreated);
  assert( TOKEN_NUM == 3);

  struct StrSentence sentencesToBeCreated[] = {
        {
          sentAnnotType, 0, 8
        }
        ,  //0
      };
  size_t SENTENCE_NUM = NUMBEROF(sentencesToBeCreated);

  // define the orders of all annotations
  int annotationOrder[] = {
                          //      int annotationOrder[TOKEN_NUM + SENTENCE_NUM] = {
                            // sentence 0, token 0, token 1, token 2
                            0, SENTENCE_NUM + 0, SENTENCE_NUM + 1, SENTENCE_NUM + 2
                          };
  assert( NUMBEROF(annotationOrder) == SENTENCE_NUM + TOKEN_NUM );

  LOG("Token number: " << TOKEN_NUM);
  LOG("Lemma number: " << LEMMA_NUM);

//      uima::internal::TCASImpl tcasimpl(ttdef, 5000, 5000, 5000);
   uima::internal::CASImpl * pCas = getCASImpl(ttdef);
  uima::internal::CASImpl & tcasimpl = *pCas;

  uima::lowlevel::FSHeap & heap = tcasimpl.getHeap();
  uima::lowlevel::IndexRepository & ixStore = tcasimpl.getIndexRepository();

  vector<lowlevel::TyFS> tokens;
  vector<lowlevel::TyFS> sentences;
  vector<lowlevel::TyFS> lemmas;

  for (i=0; i<(int)LEMMA_NUM; ++i) {
    lowlevel::TyFS fs = heap.createFS( lemmasTobeCreated[i].type );
    icu::UnicodeString const & lemmaKey = lemmaStrings[ lemmasTobeCreated[i].keyIndex ];
    UnicodeStringRef key(lemmaKey );
    int keyOff = heap.addString(key);
    heap.setStringValue(fs, keyFeat, keyOff);
    heap.setIntValue(fs, posFeat, lemmasTobeCreated[i].pos);

    lowlevel::TyFS lemmaList = heap.createFS( heap.getTypeSystem().getTypeByName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST) );
    lowlevel::TyFS eList = heap.createFS( heap.getTypeSystem().getTypeByName(CAS::TYPE_NAME_EMPTY_FS_LIST) );
    heap.setFSValue( lemmaList, heap.getTypeSystem().getFeatureByBaseName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST, CAS::FEATURE_BASE_NAME_TAIL), eList );
    heap.setFSValue( lemmaList, heap.getTypeSystem().getFeatureByBaseName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST, CAS::FEATURE_BASE_NAME_HEAD), fs );
    lemmas.push_back(lemmaList);
  }
  ASSERT_OR_THROWEXCEPTION( lemmas.size() == LEMMA_NUM );


  for (i=0; i<(int)TOKEN_NUM; ++i) {
    ASSERT_OR_THROWEXCEPTION( tokensToBeCreated[i].annot.type == tokenAnnotType );
    lowlevel::TyFS fs = heap.createFS( tokensToBeCreated[i].annot.type );
    heap.setIntValue(fs, beginPosFeat, tokensToBeCreated[i].annot.begin );
    heap.setIntValue(fs, endPosFeat, tokensToBeCreated[i].annot.end );
    heap.setFSValue(fs, lemmaEntryFeat, lemmas[ tokensToBeCreated[i].lemma ] );
    tokens.push_back(fs);
  }
  ASSERT_OR_THROWEXCEPTION( tokens.size() == TOKEN_NUM );

  for (i=0; i<(int)SENTENCE_NUM; ++i) {
    ASSERT_OR_THROWEXCEPTION( sentencesToBeCreated[i].annot.type == sentAnnotType );
    lowlevel::TyFS fs = heap.createFS( sentencesToBeCreated[i].annot.type );
    heap.setIntValue(fs, beginPosFeat, sentencesToBeCreated[i].annot.begin );
    heap.setIntValue(fs, endPosFeat, sentencesToBeCreated[i].annot.end );
    sentences.push_back(fs);
  }

  vector<lowlevel::TyFS> annotations;
  for (i=0; i<(int)(TOKEN_NUM + SENTENCE_NUM); ++i) {
    int fsix = annotationOrder[i];
    /*
    if (fsix < TOKEN_NUM) {
       annotations.push_back(tokens[fsix]);
    }
    else if (fsix < (TOKEN_NUM + SENTENCE_NUM) ) {
       annotations.push_back( sentences[fsix - TOKEN_NUM] );
    }
    */
    if (fsix < (int)SENTENCE_NUM) {
      annotations.push_back( sentences[fsix] );
    } else if (fsix < (int)(TOKEN_NUM + SENTENCE_NUM) ) {
      annotations.push_back(tokens[fsix - SENTENCE_NUM]);
    } else {
      ASSERT_OR_THROWEXCEPTION(false);
    }
  }

#ifndef NDEBUG
  heap.print(cout);
#endif

  // off we go...


  //Tests:
//   1. add tokens/lemmas to all indexes
//      ensure that tokens are returned in the right order
//      ensure that duplicates of lemmas are not inserted
  //

  // 1. add to all indexes
  LOG("Adding FSs in right order...");
  for (i=0; i<(int)tokens.size(); ++i) {
    LOG("Adding token " << (size_t) tokens[i]);
    LOG("  type of token: " << ts.getTypeName( heap.getType(tokens[i]) ) );
    ixStore.add(tokens[i]);
  }
  LOG("  tokens added");
  LOG("  Adding lemmas....");
  for (i=0; i<(int)lemmas.size(); ++i) {
    lowlevel::TyFS lemma = heap.getFSValue(lemmas[i], heap.getTypeSystem().getFeatureByBaseName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST, CAS::FEATURE_BASE_NAME_HEAD) );
    ASSERT_OR_THROWEXCEPTION( heap.getType( lemma ) == heap.getTypeSystem().getTypeByName(TT::TYPE_NAME_LEMMA) );
    ixStore.add( lemma );
  }
  LOG("   " << lemmas.size() << " lemmas added");
  LOG("Lemmas in index:");
  {
    i=0;
    auto_ptr<uima::lowlevel::IndexIterator> it( ixStore.getLowlevelIndex(SETIX, lemmaType).createIterator() );
    for (it->moveToFirst(); it->isValid(); it->moveToNext() ) {
      LOG(" lemma number: " << i);
      uima::lowlevel::TyFS lemma = it->get();
      LOG("   key: " << heap.getStringValue(lemma, keyFeat));
      LOG("   pos: " << heap.getIntValue(lemma, posFeat) );
      ++i;
    }
  }
  LOG("FSs added");

  LOG("Check indexes...");
  // check ordered index
  checkOrderedIndex(ixStore.getLowlevelIndex(ORDEREDIX, tokenAnnotType), tokens);
  // check built-in annotation index
  checkOrderedIndex(ixStore.getLowlevelIndex( tcasimpl.getAnnotationIndexID(), tokenAnnotType), tokens);
  // check set index
  checkSetIndex(ixStore.getLowlevelIndex(SETIX, lemmaType), (LEMMA_NUM - DUPLICATE_LEMMAS) );

  LOG("  Indexes checked");

  ixStore.reset();
  // add in reverse order
  LOG("Adding FSs in reverse order...");
  for (i=tokens.size() - 1; i>=0; i--) {
    LOG("i: " << i );
    assert( heap.debugIsValidHeapCell(tokens[i]) );
    ixStore.add(tokens[i]);
  }
  for (i=lemmas.size() - 1; i>=0; --i) {
    lowlevel::TyFS lemma = heap.getFSValue(lemmas[i], heap.getTypeSystem().getFeatureByBaseName(CAS::TYPE_NAME_NON_EMPTY_FS_LIST, CAS::FEATURE_BASE_NAME_HEAD) );
    ASSERT_OR_THROWEXCEPTION( heap.getType( lemma ) == heap.getTypeSystem().getTypeByName(TT::TYPE_NAME_LEMMA) );
    ixStore.add( lemma );
  }
  LOG("Checking indexes");
  // check ordered index
  checkOrderedIndex(ixStore.getLowlevelIndex(ORDEREDIX, tokenAnnotType), tokens);
  // check built-in annotation index
  checkOrderedIndex(ixStore.getLowlevelIndex(tcasimpl.getAnnotationIndexID(),tokenAnnotType), tokens);
  // check set index
  checkSetIndex(ixStore.getLowlevelIndex(SETIX, lemmaType), (LEMMA_NUM - DUPLICATE_LEMMAS) );
  LOG("Indexes checked");

  // 2. add to a single index with id
  ixStore.reset();

  LOG("Add to single index with ID");
  for (i=0; i<(int)tokens.size(); ++i) {
    ixStore.add(tokens[i], ORDEREDIX);
  }
  LOG("Checking index");
  checkOrderedIndex(ixStore.getLowlevelIndex(ORDEREDIX, tokenAnnotType), tokens);
  ASSERT_OR_THROWEXCEPTION( ixStore.getLowlevelIndex( tcasimpl.getAnnotationIndexID(), tokenAnnotType).getSize() == 0 );
  LOG("Index checked");

  // 3. test composite indexes
  ixStore.reset();
  LOG("Add to composite index");
  for (i=0; i<(int)tokens.size(); ++i) {
    ixStore.add(tokens[i]);
  }
  for (i=0; i<(int)sentences.size(); ++i) {
    ixStore.add(sentences[i]);
  }

  lowlevel::IndexABase const & ix = ixStore.getLowlevelIndex( tcasimpl.getAnnotationIndexID(), annotType);
  LOG("Checking index");
  checkOrderedIndex(ix, annotations);
  LOG("Index checked");

  // 4. test delete index
  icu::UnicodeString anIxID = tcasimpl.getAnnotationIndexID();
  ixStore.remove(tokens[0]);
  auto_ptr<lowlevel::IndexIterator> it( ixStore.getLowlevelIndex( anIxID, tokenAnnotType).createIterator() );

  it->moveToFirst();
  ASSERT_OR_THROWEXCEPTION( it->get() != tokens[0]);
  ASSERT_OR_THROWEXCEPTION( it->get() == tokens[1]);

  i=1;
  while (it->isValid()) {
    ASSERT_OR_THROWEXCEPTION( it->get() == tokens[i] );
    it->moveToNext();
    ++i;
  }
  delete pCas;
  LOG("testLowlevelIndex finished");

}


/************************************************************************************/
void testEmptyStrings() {
  LOG("testEmptyStrings() started");
  TTDefinition ttdef;
  ttdef.init();

  lowlevel::TypeSystem& ts = ttdef.getTypeSystem();
  lowlevel::TyFSType t = ts.createType(ts.getTopType(), "t", ustrCreatorID);

  lowlevel::TyFSType floatType = ts.getTypeByName(CAS::TYPE_NAME_STRING);

  lowlevel::TyFSFeature f = ts.createFeature(t, floatType, false, "f", ustrCreatorID);

  ttdef.commit();

//      uima::internal::TCASImpl tcas(ttdef, 300, 300, 300);
   uima::internal::CASImpl * pCas = getCASImpl(ttdef);
  uima::internal::CASImpl & tcas = *pCas;

  uima::lowlevel::FSHeap& heap = tcas.getHeap();

  lowlevel::TyFS fs = heap.createFS(t);
  UnicodeStringRef uref = heap.getStringValue(fs, f);
  delete pCas;
  ASSERT_OR_THROWEXCEPTION( uref.getBuffer() == NULL );
  LOG("testEmptyStrings() finished");
}

/************************************************************************************/
void testFloatFeatures() {
  LOG("testFloatFeatures started");
  TTDefinition ttdef;
  ttdef.init();

  lowlevel::TypeSystem& ts = ttdef.getTypeSystem();
  lowlevel::TyFSType t = ts.createType(ts.getTopType(), "t", ustrCreatorID);


  lowlevel::TyFSType floatType = ts.getTypeByName(CAS::TYPE_NAME_FLOAT);

  lowlevel::TyFSFeature f = ts.createFeature(t, floatType, false, "f", ustrCreatorID);

  ttdef.commit();
//       uima::internal::TCASImpl tcas(ttdef, 30, 30, 30);
//       uima::internal::CASImpl tcas(ttdef, 30, 30, 30);
//        uima::internal::CASImpl & tcas = *uima::internal::CASImpl::createCASImpl(ttdef, false);

//     ErrorInfo errorInfo;
//     uima::internal::CASImpl & tcas = *(uima::internal::CASImpl*) Framework::createCAS(ttdef, errorInfo);
   uima::internal::CASImpl * pCas = getCASImpl(ttdef);
  uima::internal::CASImpl & tcas = *pCas;

  lowlevel::FSHeap& heap = tcas.getHeap();

  lowlevel::TyFS fs = heap.createFS(t);
  float x = 0.4237f;
  heap.setFloatValue(fs, f, x);
  
  float y = heap.getFloatValue(fs, f);
  ASSERT_OR_THROWEXCEPTION(x == y);
  delete pCas;
  LOG("testFloatFeatures finished");
}



/************************************************************************************/

void testNestedStructures() {
  LOG("testNestedStructures started");

  TTDefinition ttdef;
  ttdef.init();

  lowlevel::TypeSystem& ts = ttdef.getTypeSystem();
  lowlevel::TyFSType top = ts.getTopType();
  lowlevel::TyFSType t1 = ts.createType(top, "t1", ustrCreatorID);
  lowlevel::TyFSType t2 = ts.createType(top, "t2", ustrCreatorID);
  lowlevel::TyFSType t3 = ts.createType(top, "t3", ustrCreatorID);
  lowlevel::TyFSType t4 = ts.createType(top, "t4", ustrCreatorID);
  lowlevel::TyFSType t5 = ts.createType(top, "t5", ustrCreatorID);

  lowlevel::TyFSFeature f11 = ts.createFeature(t1, t2, false, "f11", ustrCreatorID);
  lowlevel::TyFSFeature f12 = ts.createFeature(t1, t3, false, "f12", ustrCreatorID);
  lowlevel::TyFSFeature f2 = ts.createFeature(t2, t4, false, "f2", ustrCreatorID);
  lowlevel::TyFSFeature f3 = ts.createFeature(t3, t5, false, "f3", ustrCreatorID);

  ttdef.commit();

//      uima::internal::TCASImpl tcas(ttdef, 400, 400, 400);
   uima::internal::CASImpl * pCas = getCASImpl(ttdef);
  uima::internal::CASImpl & tcas = *pCas;

//#ifndef NDEBUG
//   ts.print(cout);
//#endif

  lowlevel::FSHeap & heap = tcas.getHeap();

  lowlevel::TyFS fs_t1 = heap.createFS( t1 );
  lowlevel::TyFS fs_t2 = heap.createFS( t2 );
  lowlevel::TyFS fs_t3 = heap.createFS( t3 );
  lowlevel::TyFS fs_t4 = heap.createFS( t4 );
  lowlevel::TyFS fs_t5 = heap.createFS( t5 );

  ASSERT_OR_THROWEXCEPTION( heap.isUntouchedFSValue( fs_t1, f11 ) );
  heap.setFSValue(fs_t1, f11, fs_t2);
  ASSERT_OR_THROWEXCEPTION( ! heap.isUntouchedFSValue( fs_t1, f11 ) );
  heap.setFSValue(fs_t1, f12, fs_t3);
  heap.setFSValue(fs_t2, f2, fs_t4);
  heap.setFSValue(fs_t3, f3, fs_t5);

//#ifndef NDEBUG
//   heap.print(cout);
//#endif

  ASSERT_OR_THROWEXCEPTION( heap.getType( heap.getFSValue(fs_t1, f11) ) == t2 );
  ASSERT_OR_THROWEXCEPTION( heap.getType( heap.getFSValue(fs_t1, f12) ) == t3 );
  ASSERT_OR_THROWEXCEPTION( heap.getType( heap.getFSValue(fs_t2, f2) ) == t4 );
  ASSERT_OR_THROWEXCEPTION( heap.getType( heap.getFSValue(fs_t3, f3) ) == t5 );

  ASSERT_OR_THROWEXCEPTION( heap.getFSValue(fs_t1, f11) == fs_t2 );
  ASSERT_OR_THROWEXCEPTION( heap.getFSValue(fs_t1, f12) == fs_t3 );
  ASSERT_OR_THROWEXCEPTION( heap.getFSValue(fs_t2, f2) == fs_t4 );
  ASSERT_OR_THROWEXCEPTION( heap.getFSValue(fs_t3, f3) == fs_t5 );

  delete pCas;
  LOG("testNestedStructures finished");
}



/************************************************************************************/


void testOOIndex() {
  LOG("testOOIndex() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();
  uima::FSIndexRepository & indexRep = tcas.getIndexRepository();

  TypeSystem const & typeSys = tcas.getTypeSystem();

  Type annotType = typeSys.getType(TT::TYPE_NAME_TOKEN_ANNOTATION);
  Feature beginPosFeature = annotType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_BEGIN);
  Feature endPosFeature = annotType.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_END);


  LOG("Creating FSs");
  FeatureStructure fs1 = tcas.createFS(annotType);
  ASSERT_OR_THROWEXCEPTION( fs1.isUntouchedFSValue(beginPosFeature) );
  fs1.setIntValue( beginPosFeature, 1 );
  ASSERT_OR_THROWEXCEPTION( ! fs1.isUntouchedFSValue(beginPosFeature) );
  fs1.setIntValue( endPosFeature, 2 );
  FeatureStructure fs2 = tcas.createFS(annotType);
  fs2.setIntValue( beginPosFeature, 2 );
  fs2.setIntValue( endPosFeature, 3 );
  FeatureStructure fs3 = tcas.createFS(annotType);
  fs3.setIntValue( beginPosFeature, 3 );
  fs3.setIntValue( endPosFeature, 4 );
  FeatureStructure fs4 = tcas.createFS(annotType);
  fs4.setIntValue( beginPosFeature, 4 );
  fs4.setIntValue( endPosFeature, 5 );
  FeatureStructure fs41 = tcas.createFS(annotType);
  fs41.setIntValue( beginPosFeature, 4 );
  fs41.setIntValue( endPosFeature, 5 );
  LOG("...FSs created");

  FeatureStructure fsArray[] = {
                                 fs1, fs2, fs3, fs4, fs41
                               };
  size_t fsArraySize = NUMBEROF(fsArray);

  LOG("Adding FSs to index");
  indexRep.addFS(fs1);
  indexRep.addFS(fs3);
  indexRep.addFS(fs41);
  indexRep.addFS(fs4);
  indexRep.addFS(fs2);
  LOG("...FSs Added");

  FSIndex ordIx = tcas.getAnnotationIndex(annotType);
  ASSERT_OR_THROWEXCEPTION( ordIx.getSize() == fsArraySize );

  LOG("Checking ordered index...");
  FSIterator ordIt = ordIx.iterator();
  size_t i=0;
  for (ordIt.moveToFirst(); ordIt.isValid(); ordIt.moveToNext()) {
    LOG("Checking " << i << "th FS");
    FeatureStructure fs1 = ordIt.get();
    FeatureStructure fs2 = fsArray[i];
//      ASSERT_OR_THROWEXCEPTION( ordIt.get() == fsArray[i] );
    ASSERT_OR_THROWEXCEPTION( fs1.getIntValue( beginPosFeature ) == fs2.getIntValue( beginPosFeature ) );
    ASSERT_OR_THROWEXCEPTION( fs1.getIntValue( endPosFeature ) == fs2.getIntValue( endPosFeature ) );
    ++i;
  }
  LOG("...Ordered index checked");


  LOG("Checking deletion");
  indexRep.removeFS(fsArray[0]);
  FSIterator ordIt2 = ordIx.iterator();
  ordIt2.moveToFirst();
  ASSERT_OR_THROWEXCEPTION( ! (ordIt2.get() == fsArray[0]) );
  ASSERT_OR_THROWEXCEPTION( ordIt2.get() == fsArray[1] );
  i=1;
  while (ordIt2.isValid()) {
    ASSERT_OR_THROWEXCEPTION( ordIt2.get() != fsArray[0] );
    ordIt2.moveToNext();
    ++i;
  }

  LOG("Deletion checked");


  LOG("testOOIndex() finished");
}




/************************************************************************************/

void testOOExceptions() {
  LOG("testOOExceptions() started");

  bool bExceptionThrown = false;

  Type t;
  try {
    UnicodeStringRef name = t.getName();
  } catch (InvalidFSTypeObjectException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }

  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);

  TTDefinition ttdef;
  ttdef.init();

  Type lemmaType = ttdef.getTypeSystem().getType(TT::TYPE_NAME_LEMMA);
  Type annotType = ttdef.getTypeSystem().getType(CAS::TYPE_NAME_ANNOTATION);
  Feature beginPosFeat = annotType.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_BEGIN);
  Feature endPosFeat = annotType.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_END);

  Type invalidType;
  Feature invalidFeat;


  ttdef.commit();
//   tcas.createPredefinedTTIndexes();

//      uima::internal::TCASImpl tcas(ttdef, 50000, 50000, 50000);
   uima::internal::CASImpl * pCas = getCASImpl(ttdef);
  uima::internal::CASImpl & tcas = *pCas;


  // check invalid fs
  FeatureStructure invalidFS;
  bExceptionThrown = false;
  try {
    (void)invalidFS.getIntValue(beginPosFeat);
  } catch (InvalidFSObjectException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);

  // check fs creation with invalid type
  bExceptionThrown = false;
  try {
    FeatureStructure fs1 = tcas.createFS(invalidType);
  } catch (InvalidFSTypeObjectException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);

  FeatureStructure annotFS = tcas.createFS(annotType);

  // check getting invalid feature
  // check getting inappropriate feature
  bExceptionThrown = false;
  try {
    FeatureStructure fs = annotFS.getFSValue(invalidFeat);
  } catch (InvalidFSFeatureObjectException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);

  // check getting inappropriate feature

  bExceptionThrown = false;
  try {
    FeatureStructure lemmaFS = tcas.createFS(lemmaType);
    FeatureStructure fs = lemmaFS.getFSValue(beginPosFeat);
  } catch (FeatureNotAppropriateException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);

  // getting an approproate feature with non builtin range type
  bExceptionThrown = false;
  try {
    FeatureStructure fs = annotFS.getFSValue(beginPosFeat);
  } catch (FeatureNotAppropriateException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);

  // setting incompatible value
  bExceptionThrown = false;
  try {
    annotFS.setFSValue(beginPosFeat, annotFS);
  } catch (IncompatibleValueTypeException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);

  /*
  // getting string/array value from fs
  bExceptionThrown = false;
  try {
     internal::StringFS strFS(annotFS);
     UnicodeStringRef p = strFS.getStringValue();
  }
  catch (FSIsNotStringException & exc) {
     LOG("Exception thrown correctly: " << exc.asString());
     bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);
  */

  // invalid arrays
  ArrayFS invalidArrayFS(invalidFS);
  bExceptionThrown = false;
  try {
    size_t i = invalidArrayFS.size();
  } catch (InvalidFSObjectException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);

  // array size
  bExceptionThrown = false;
  try {
    ArrayFS arrFS(annotFS);
    (void)arrFS.size();
  } catch (FSIsNotArrayException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);


  bExceptionThrown = false;
  LOG("Testing InvalidIndexIDException");
  try {
    tcas.getIndexRepository().getIndex("bla", annotType);
  } catch (InvalidIndexIDException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);


  bExceptionThrown = false;
  LOG("Testing WrongFSTypeForIndexException");
  icu::UnicodeString const & crIndexID = tcas.getAnnotationIndexID();
  try {
    tcas.getIndexRepository().getIndex(crIndexID, lemmaType);
  } catch (WrongFSTypeForIndexException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  ASSERT_OR_THROWEXCEPTION(bExceptionThrown);

  bExceptionThrown = false;
  LOG("Testing CouldNotCreateFSOfFinalTypeException");
  try {
    tcas.createFS( tcas.getTypeSystem().getType( uima::CAS::TYPE_NAME_INTEGER ) );
  } catch ( CouldNotCreateFSOfFinalTypeException & exc) {
    LOG("Exception thrown correctly: " << exc.asString());
    bExceptionThrown = true;
  }
  delete pCas;
  LOG("testOOExceptions() finished");
}


/************************************************************************************/


void testOOFilterBuilder() {
  LOG("testOOFilterBuilder() started");

  TTDefinition ttdef;
  ttdef.init();
  


  TypeSystem const & typeSystem  = ttdef.getTypeSystem();

  Type tokenType = typeSystem.getType(TT::TYPE_NAME_TOKEN_ANNOTATION);
  Feature beginFeat = tokenType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_BEGIN);
  Feature endFeat = tokenType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_END);

  Type stringType = typeSystem.getType(CAS::TYPE_NAME_STRING);


  uima::lowlevel::TypeSystem & lolTS = ttdef.getTypeSystem();
  lowlevel::TyFSType lolTokenType = uima::internal::FSPromoter::demoteType( tokenType );
  lowlevel::TyFSType lolMyTokenType = lolTS.createType(lolTokenType, "MyToken", ustrCreatorID);
  lolTS.createFeature(lolMyTokenType, lolTokenType, false, "MyRecursiveFeature", ustrCreatorID);
  lolTS.createFeature(lolMyTokenType, uima::internal::FSPromoter::demoteType(stringType), false, "MyStringFeature", ustrCreatorID);


  Type myTokenType = typeSystem.getType("MyToken");
  Feature myRecursiveFeature = myTokenType.getFeatureByBaseName("MyRecursiveFeature");
  Feature myStringFeature = myTokenType.getFeatureByBaseName("MyStringFeature");


//   lowlevel::TypeSystem const & typeSystem = tcas.getFSSystem().getLowlevelTypeSystem();
//   lowlevel::TyFSType lolTokenType = typeSystem.getType(CAS::TYPE_NAME_TOKEN_ANNOTATION);
//   lowlevel::TyFSType lolMyTokenType = typeSystem.getType("MyToken");

  ttdef.commit();
//      uima::internal::TCASImpl tcas(ttdef, 4000, 4000, 4000);
   uima::internal::CASImpl * pCas = getCASImpl(ttdef);
  uima::internal::CASImpl & tcas = *pCas;

  uima::FSIndexRepository & indexRep = tcas.getIndexRepository();

  StrToken tokens[] = {
                        {
                          lolTokenType, 0, 3, 0
                        }
                        , // 0
                        { lolMyTokenType, 3, 5, 0}, // 1
                        { lolTokenType, 5, 8, 0}, // 2
                        { lolMyTokenType, 9, 11, 0}, // 3
                        { lolMyTokenType, 15, 16, 0} // 4
                      };
  size_t tokenNum = NUMBEROF(tokens);
  size_t myTokenNum = 3;

  FeatureStructure oldFS;
  size_t i;
  for (i=0; i<tokenNum; ++i) {
    icu::UnicodeString typeName = lolTS.getTypeName( tokens[i].annot.type );
    Type type = typeSystem.getType(typeName);

    FeatureStructure fs = tcas.createFS(type);
    fs.setIntValue(beginFeat, tokens[i].annot.begin);
    fs.setIntValue(endFeat, tokens[i].annot.end);
    if (type == myTokenType) {
      ASSERT_OR_THROWEXCEPTION(oldFS.isValid() );
      fs.setFSValue(myRecursiveFeature, oldFS);
      char c[32];
      sprintf(c,"%d",i);                  //cosItoa(i, c);

      icu::UnicodeString us("string");
      us.append(icu::UnicodeString(c));
//         icu::UnicodeString icuus( (UChar*) us.data(), us.length() );
//         UnicodeStringRef p = fsSystem.addString(icuus);
//         UnicodeStringRef lstr( (UniChar const *) p.first, p.second);
//         LOG("Adding string '" << lstr << "'");
//         FeatureStructure stringFS = fsSystem.createStringFS(p.first, p.second);
      fs.setStringValue(myStringFeature, us);
    }
    oldFS = fs;
    indexRep.addFS(fs);
  }
  LOG("Annotations created");

  FSIterator ixit;
  ANIndex ix = tcas.getAnnotationIndex(tokenType);

  vector<Feature> vFeaturePath;
  FSFilterBuilder const & builder = tcas.getFSFilterBuilder();

  //////////////////////////////////////////
  LOG("Checking type filter");

  //TODO: the filter passed to ix.filteredIterator is wrapped in another object,
  // added to ixit, and never deleted.
  // LEAK!!!

  FSFilter * typeFilter = builder.createTypeFilter(tokenType, false);
  ixit = ix.filteredIterator(typeFilter);
  i=0;
  for (ixit.moveToFirst(); ixit.isValid(); ixit.moveToNext()) {
    ASSERT_OR_THROWEXCEPTION( ixit.get().getType() == myTokenType );
    ++i;
  }
  ASSERT_OR_THROWEXCEPTION(i == myTokenNum);

  delete typeFilter;
  typeFilter = NULL;
  LOG("...type filter checked");

  //////////////////////////////////////////
  LOG("Checking AND/int feature value filter");
  vFeaturePath.clear();
  vFeaturePath.push_back(beginFeat);
  FSFilter * intFeatureFilter1 = builder.createIntFeatureFilter(vFeaturePath, FSFilterBuilder::EQUALS, 5);
  vFeaturePath.clear();
  vFeaturePath.push_back(endFeat);
  FSFilter * intFeatureFilter2 = builder.createIntFeatureFilter(vFeaturePath, FSFilterBuilder::LESS, 10);
  FSFilter * conjFeatureFilter = builder.createANDFilter(intFeatureFilter1, intFeatureFilter2);

  ixit = ix.filteredIterator(conjFeatureFilter);
  i=0;
  for (ixit.moveToFirst(); ixit.isValid(); ixit.moveToNext()) {
    FeatureStructure fs = ixit.get();
    ASSERT_OR_THROWEXCEPTION( !( (fs.getIntValue(beginFeat) == 5) && (fs.getIntValue(endFeat) < 10) ) );
    ++i;
  }
  LOG(" Found " << i << " filtered FSs");
  ASSERT_OR_THROWEXCEPTION( i == 4 );

  LOG("... AND/int feature value filter checked");

  /////////////////////////////////////////////
  LOG("Checking NOT filter");
  FSFilter * notFilter = builder.createNOTFilter(conjFeatureFilter);

  ixit = ix.filteredIterator(notFilter);
  i=0;
  for (ixit.moveToFirst(); ixit.isValid(); ixit.moveToNext()) {
    FeatureStructure fs = ixit.get();
    ASSERT_OR_THROWEXCEPTION( ( (fs.getIntValue(beginFeat) == 5) && (fs.getIntValue(endFeat) < 10) ) );
    ++i;
  }
  LOG(" Found " << i << " filtered FSs");
  ASSERT_OR_THROWEXCEPTION( i == 1 );
  notFilter->deInit();
  delete notFilter;
  notFilter = NULL;
  LOG("... NOT filter checked");

  ////////////////////////////////////////////////////

  LOG("Checking match filter");
  FSFilter * myTokenTypeFilter1 = builder.createTypeFilter(myTokenType, true);
  FSFilter * myTokenTypeFilter2 = builder.createTypeFilter(myTokenType, true);
  vFeaturePath.clear();
  vFeaturePath.push_back(myRecursiveFeature);
  FSFilter * matchFilter = builder.createMatchFilter(vFeaturePath, myTokenTypeFilter2);
  FSFilter * andFilter = builder.createANDFilter(myTokenTypeFilter1, matchFilter);

  LOG("Creating iterator");
  ixit = ix.filteredIterator(andFilter);
  LOG("... Iterator created");

  i=0;
  for (ixit.moveToFirst(); ixit.isValid(); ixit.moveToNext()) {
    FeatureStructure fs = ixit.get();
    ASSERT_OR_THROWEXCEPTION( tokenType.subsumes( fs.getType() ));
    ++i;
  }
  LOG("Found " << i << " FSs");
  ASSERT_OR_THROWEXCEPTION(i==4);

  andFilter->deInit();
  delete andFilter;
  LOG("... match filter checked");

  //////////////////////////////////////////////////////
  LOG("Checking string filter");
  FSFilter * myTokenTypeFilter3 = builder.createTypeFilter(myTokenType, true);

  vFeaturePath.clear();
  vFeaturePath.push_back(myStringFeature);

  icu::UnicodeString usMatch("string3");
  FSFilter * stringFilter = builder.createStringFeatureFilter(vFeaturePath, usMatch.getBuffer(), usMatch.length() );
//   FSFilter * matchFilter2 = builder.createMatchFilter(vFeaturePath, stringFilter);
  FSFilter * andFilter2 = builder.createANDFilter(myTokenTypeFilter3, stringFilter);

  LOG("Creating iterator");
  ixit = ix.filteredIterator(andFilter2);
  LOG("... Iterator created");

  i=0;
  for (ixit.moveToFirst(); ixit.isValid(); ixit.moveToNext()) {
    FeatureStructure fs = ixit.get();
    if (fs.getType() == myTokenType) {
      UnicodeStringRef p = fs.getStringValue(myStringFeature);
      icu::UnicodeString str( p.getBuffer(), p.length() );
      LOG(" found string: " << str);
      ASSERT_OR_THROWEXCEPTION( ! (str == usMatch ));
    }
    ++i;
  }
  LOG("Found " << i << " FSs");
  ASSERT_OR_THROWEXCEPTION(i == (tokenNum - 1));
  andFilter2->deInit();
  delete andFilter2;
  delete pCas;

  LOG("... string filter checked");

  LOG("testOOFilterBuilder() finished");
}



/************************************************************************************/

void testIteratorSetToPosition() {
  LOG("testIteratorSetToPosition() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();

  lowlevel::TypeSystem const & typeSystem = testcas.getCASDef().getTypeSystem();
  lowlevel::TyFSType tokenType = typeSystem.getTypeByName(TT::TYPE_NAME_TOKEN_ANNOTATION);
  lowlevel::TyFSFeature beginFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_BEGIN);
  lowlevel::TyFSFeature endFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_END);

  lowlevel::FSHeap & fsHeap = tcas.getHeap();

  StrToken tokens[] = {
                        {
                          tokenType, 0, 3, 0
                        }
                        , // 0
                        { tokenType, 3, 5, 0}, // 1
                        { tokenType, 5, 8, 0}, // 2
                        { tokenType, 9, 11, 0}, // 3
                        { tokenType, 15, 16, 0}, // 4
                        { tokenType, 17, 20, 0} // 5
                      };
  size_t tokenNum = NUMBEROF(tokens);

  lowlevel::IndexRepository & indexRep = tcas.getIndexRepository();

  size_t i;
  for (i=0; i<tokenNum; ++i) {
    lowlevel::TyFS token = fsHeap.createFS(tokens[i].annot.type);
    fsHeap.setIntValue(token, beginFeature, tokens[i].annot.begin);
    fsHeap.setIntValue(token, endFeature, tokens[i].annot.end);
    indexRep.add(token);
  }

  icu::UnicodeString const & ixID = tcas.getAnnotationIndexID();

  lowlevel::IndexABase const & ix = indexRep.getLowlevelIndex(ixID, tokenType);

  auto_ptr<lowlevel::IndexIterator> it1(ix.createIterator() );
  auto_ptr<lowlevel::IndexIterator> it2(ix.createIterator());

  const size_t numberOfAdvances = 2;
  it1->moveToFirst();

  for (i=0; i<numberOfAdvances; ++i) {
    ASSERT_OR_THROWEXCEPTION( it1->isValid() );
    it1->moveToNext();
  }

  ASSERT_OR_THROWEXCEPTION( it1->isValid() );

  LOG("Setting it2 to point to token from " << fsHeap.getIntValue(it1->get(), beginFeature) << " to " << fsHeap.getIntValue(it1->get(), endFeature) );
  bool bCouldBeSet = it2->moveTo(it1->get());

  ASSERT_OR_THROWEXCEPTION(bCouldBeSet);
  ASSERT_OR_THROWEXCEPTION( it2->isValid() );
  ASSERT_OR_THROWEXCEPTION( it2->get() == it1->get() );

  // check that rest tokens are also found
  for (i=numberOfAdvances; i<tokenNum; ++i) {
    ASSERT_OR_THROWEXCEPTION( it1->isValid() );
    ASSERT_OR_THROWEXCEPTION( it2->isValid() );
    LOG("Checking token from " << fsHeap.getIntValue(it1->get(), beginFeature) << " to " << fsHeap.getIntValue(it1->get(), endFeature) );
    ASSERT_OR_THROWEXCEPTION( it1->get() == it2->get() );
    it1->moveToNext();
    it2->moveToNext();
  }
  ASSERT_OR_THROWEXCEPTION( ! it1->isValid() );
  ASSERT_OR_THROWEXCEPTION( ! it2->isValid() );


  LOG("testIteratorSetToPosition() finished");
}



/************************************************************************************/


class MyLowlevelFilter : public lowlevel::FSFilter {
private:
  uima::internal::CASImpl const & iv_tcas;
  lowlevel::TyFSType annotType;
  lowlevel::TyFSFeature beginFeat;
public:
  MyLowlevelFilter(uima::internal::CASImpl const & tcas)
      : iv_tcas(tcas) {
    annotType = tcas.getHeap().getTypeSystem().getTypeByName(CAS::TYPE_NAME_ANNOTATION);
    beginFeat = tcas.getHeap().getTypeSystem().getFeatureByBaseName( annotType, CAS::FEATURE_BASE_NAME_BEGIN);
  }

  // filter those annotations whose begin position is less than 10
  bool isFiltered(lowlevel::TyFS fs) const {
    lowlevel::FSHeap const & crFSHeap = iv_tcas.getHeap();
    lowlevel::TypeSystem const & crTypeSystem = crFSHeap.getTypeSystem();

    // filter only annotations
    if (! crTypeSystem.subsumes( annotType, crFSHeap.getType(fs)) ) {
      return false;
    }
    int iBegin = crFSHeap.getIntValue(fs, beginFeat);
    return(iBegin < 10);
  }

};

void testFilters() {
  LOG("testFilters() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();

  lowlevel::TypeSystem const & typeSystem = testcas.getCASDef().getTypeSystem();
  lowlevel::TyFSType tokenType = typeSystem.getTypeByName(TT::TYPE_NAME_TOKEN_ANNOTATION);
  lowlevel::TyFSFeature beginFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_BEGIN);
  lowlevel::TyFSFeature endFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_END);

  lowlevel::FSHeap & fsHeap = tcas.getHeap();

  StrToken tokens[] = {
                        {
                          tokenType, 0, 3, 0
                        }
                        , // 0
                        { tokenType, 3, 5, 0}, // 1
                        { tokenType, 5, 8, 0}, // 2
                        { tokenType, 9, 11, 0}, // 3
                        { tokenType, 15, 16, 0}, // 4
                        { tokenType, 17, 20, 0} // 5
                      };
  size_t tokenNum = NUMBEROF(tokens);

  lowlevel::IndexRepository & indexRep = tcas.getIndexRepository();

  size_t i;
  for (i=0; i<tokenNum; ++i) {
    lowlevel::TyFS token = fsHeap.createFS(tokens[i].annot.type);
    fsHeap.setIntValue(token, beginFeature, tokens[i].annot.begin);
    fsHeap.setIntValue(token, endFeature, tokens[i].annot.end);
    indexRep.add(token);
  }

  icu::UnicodeString const & ixID = tcas.getAnnotationIndexID();

  lowlevel::IndexABase const & ix = indexRep.getLowlevelIndex(ixID, tokenType);

  LOG("Annotations created");

  MyLowlevelFilter* myFilter = new MyLowlevelFilter(tcas);

  lowlevel::IndexIterator* it = ix.createFilteredIterator(myFilter);
  LOG("filtered iterator created");

  it->moveToFirst();
  LOG("Checking first annotation");
  ASSERT_OR_THROWEXCEPTION( it->isValid() );
  lowlevel::TyFS fs = it->get();
  ASSERT_OR_THROWEXCEPTION( fsHeap.getIntValue(fs, beginFeature) == 15 );
  it->moveToNext();

  ASSERT_OR_THROWEXCEPTION( it->isValid() );
  fs = it->get();
  ASSERT_OR_THROWEXCEPTION( fsHeap.getIntValue(fs, beginFeature) == 17 );
  it->moveToNext();
  ASSERT_OR_THROWEXCEPTION( ! it->isValid() );

  delete it;
  delete myFilter;
  LOG("testFilters() finished");
}


/************************************************************************************/

/*
class PermanentComparator : public lowlevel::IndexComparator {
public:
   PermanentComparator(lowlevel::FSHeap const & heap, lowlevel::TyFSType type)
   : lowlevel::IndexComparator(heap, type) {
   }

   int compare(lowlevel::TyFS, lowlevel::TyFS) const {
      return 1;
   }
};
*/
void testPermanentStructures() {
  LOG("testPermanentStructures() skipped!!!");
#ifdef BYEBYEPERM
  LOG("testPermanentStructures() started");
  TTDefinition ttdef;
  ttdef.init();

  ttdef.commitTypeSystem();
  uima::lowlevel::IndexDefinition & indexDef = ttdef.getIndexDefinition();

  lowlevel::TypeSystem const & typeSystem = ttdef.getTypeSystem();
  lowlevel::TyFSType tokenType = typeSystem.getTypeByName(TT::TYPE_NAME_TOKEN_ANNOTATION);
  lowlevel::TyFSFeature beginFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_BEGIN);
  lowlevel::TyFSFeature endFeature = typeSystem.getFeatureByBaseName(tokenType, CAS::FEATURE_BASE_NAME_END);

  lowlevel::TyFeatureOffset beginFeatOffset = typeSystem.getFeatureOffset(beginFeature);
  lowlevel::TyFeatureOffset endFeatOffset = typeSystem.getFeatureOffset(endFeature);



  vector<lowlevel::TyFSFeature> tokenKeyFeatures;
  vector<uima::lowlevel::IndexComparator::EnKeyFeatureComp> tokenComparators;
  tokenKeyFeatures.push_back(beginFeature);
  tokenKeyFeatures.push_back(endFeature);
  tokenComparators.resize(2, uima::lowlevel::IndexComparator::STANDARD_COMPARE );

//   PermanentComparator* permComp = new PermanentComparator(heap, tokenType);
  indexDef.defineIndex(uima::lowlevel::IndexDefinition::enSet,
                       tokenType,
                       tokenKeyFeatures,
                       tokenComparators,
                       "2001",
                       true );
  ASSERT_OR_THROWEXCEPTION( indexDef.getIndexKind("2001") == uima::lowlevel::IndexDefinition::enSet );

  ttdef.commitIndexDefinition();

//      uima::internal::TCASImpl tcas(ttdef, 4000, 4000, 4000);
  uima::internal::CASImpl & tcas = getCASImpl(ttdef);

  icu::UnicodeString const & annotationIndexID = tcas.getAnnotationIndexID();

  lowlevel::FSHeap & heap = tcas.getHeap();
  lowlevel::IndexRepository & indexRep = tcas.getIndexRepository();

  lowlevel::TyFS permFS = heap.createFS( lowlevel::FSHeap::PERMANENT, tokenType );
  heap.setIntValue(permFS, beginFeature, 1);
  heap.setIntValue(permFS, endFeature, 2);

  lowlevel::TyFS tempFS1 = heap.createFS( lowlevel::FSHeap::TEMPORARY, tokenType );
  heap.setIntValue(tempFS1, beginFeature, 3);
  heap.setIntValue(tempFS1, endFeature, 4);

  ASSERT_OR_THROWEXCEPTION( permFS != lowlevel::FSHeap::INVALID_FS );
  ASSERT_OR_THROWEXCEPTION( tempFS1 != lowlevel::FSHeap::INVALID_FS );

  indexRep.add(tempFS1);

  lowlevel::IndexABase const & index = indexRep.getLowlevelIndex( annotationIndexID, tokenType );
  lowlevel::IndexABase const & permIndex = indexRep.getLowlevelIndex( "2001", tokenType);

  ASSERT_OR_THROWEXCEPTION( index.getSize() == 1 );
  ASSERT_OR_THROWEXCEPTION( permIndex.getSize() == 1 );
  LOG("FSs created");


  tcas.resetWithoutCreatingDocAnnotation();

  LOG("TCAS reset'd");

  ASSERT_OR_THROWEXCEPTION( index.getSize() == 0 );
  ASSERT_OR_THROWEXCEPTION( permIndex.getSize() == 1 );

  ASSERT_OR_THROWEXCEPTION( *tempFS1 == 0 );
  ASSERT_OR_THROWEXCEPTION( *(tempFS1 + beginFeatOffset) == 0 );
  ASSERT_OR_THROWEXCEPTION( *(tempFS1 + endFeatOffset) == 0 );

  LOG("temp fs checked");

  ASSERT_OR_THROWEXCEPTION( heap.getType(permFS) == tokenType );
  ASSERT_OR_THROWEXCEPTION( (size_t) heap.getFeatureWithOffset(permFS, beginFeatOffset) == 1 );
  ASSERT_OR_THROWEXCEPTION( (size_t) heap.getFeatureWithOffset(permFS, endFeatOffset) == 2 );

  LOG("perm fs checked");
//   delete permComp;
  LOG("testPermanentStructures() finished");
#endif
}


/************************************************************************************/

/*
// obsolete since IDs are now strings.
void testNewIndexID() {
   LOG("testNewIndexID() started");
   uima::internal::TCASImpl tcas(4000);

   tcas.commitTypeSystem();

   uima::lowlevel::TypeSystem & ts = tcas.getFSSystem().getLowlevelTypeSystem();

   // get some types and features
   lowlevel::TyFSType annotType = ts.getTypeByName( CAS::TYPE_NAME_ANNOTATION );
   ASSERT_OR_THROWEXCEPTION( ts.isValidType(annotType) );

   lowlevel::TyFSFeature beginPosFeat = ts.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_BEGIN );
   ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(beginPosFeat) );
   lowlevel::TyFSFeature endPosFeat = ts.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_END );
   ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(endPosFeat) );

   vector<lowlevel::TyFSFeature> keyFeatures;
   keyFeatures.push_back(beginPosFeat);
   keyFeatures.push_back(endPosFeat);
   lowlevel::KeyFeatureComparator annotComp(tcas.getFSSystem().getLowlevelFSHeap(), annotType, keyFeatures);

   uima::lowlevel::IndexRepository & ixRep = tcas.getFSSystem().getLowlevelIndexRepository();

   int id1 = ixRep.getNewIndexID();
   LOG("New index ID: " << id1);
   ASSERT_OR_THROWEXCEPTION( ! ixRep.isValidIndexId(id1) );
   ixRep.createOrderedIndex(annotType, & annotComp, id1);

   int id2 = ixRep.getNewIndexID();
   ASSERT_OR_THROWEXCEPTION( ! ixRep.isValidIndexId(id2) );
   ASSERT_OR_THROWEXCEPTION( id1 != id2 );


   LOG("testNewIndexID() finished");
}
*/

/************************************************************************************/
void testOOArrayFS() {
  LOG("testOOArrayFS() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas  = testcas.getCAS();

  FeatureStructure strFS1 = tcas.createListFS();
  FeatureStructure strFS2 = tcas.createListFS();
  FeatureStructure strFS3 = tcas.createListFS();
  FeatureStructure strFS4 = tcas.createListFS();
  FeatureStructure strFS5 = tcas.createListFS();

  FeatureStructure strings[] = {
                                 strFS1, strFS3, strFS2, strFS5, strFS4
                               };

  const size_t length = NUMBEROF(strings);
  size_t i=0;

  ArrayFS fs = tcas.createArrayFS(length);
  ASSERT_OR_THROWEXCEPTION( fs.size() == length );

  for (i=0; i<length; ++i) {
    fs.set(i, strings[i]);
  }

  for (i=0; i<length; ++i) {
    ASSERT_OR_THROWEXCEPTION( fs.get(i) == strings[i] );
  }

  LOG("testOOArrayFS() finished");
}

/************************************************************************************/
void testOOStringArrayFS() {
  LOG("testOOStringArray() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas  = testcas.getCAS();

  icu::UnicodeString str1("string1");
  icu::UnicodeString str2("string2");
  icu::UnicodeString str3("string3");
  icu::UnicodeString str4("string4");
  icu::UnicodeString str5("string5");

  UnicodeStringRef strings[] = {
                                 str1, str3, str2, str5, str4
                               };

  const size_t length = NUMBEROF(strings);
  size_t i=0;

  StringArrayFS fs = tcas.createStringArrayFS(length);
  ASSERT_OR_THROWEXCEPTION( fs.size() == length );

  for (i=0; i<length; ++i) {
    fs.set(i, strings[i]);
  }

  for (i=0; i<length; ++i) {
    ASSERT_OR_THROWEXCEPTION( fs.get(i) == strings[i] );
  }

  LOG("testOOStringArrayFS() finished");
}


/************************************************************************************/

void testOOListFunctionsOld() {
  LOG("testOOListFunctions() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();

  TypeSystem const & typeSystem = tcas.getTypeSystem();

  Type tokenAnnType = typeSystem.getType(TT::TYPE_NAME_TOKEN_ANNOTATION);
  Feature tokenNbrFeat = tokenAnnType.getFeatureByBaseName(TT::FEATURE_BASE_NAME_TOKEN_NUMBER);

  // create tokens
  FeatureStructure tok0 = tcas.createFS(tokenAnnType);
  tok0.setIntValue(tokenNbrFeat, 0);

  FeatureStructure tok1 = tcas.createFS(tokenAnnType);
  tok1.setIntValue(tokenNbrFeat, 1);

  FeatureStructure tok2 = tcas.createFS(tokenAnnType);
  tok2.setIntValue(tokenNbrFeat, 2);

  FeatureStructure tok3 = tcas.createFS(tokenAnnType);
  tok3.setIntValue(tokenNbrFeat, 3);

  FeatureStructure tok4 = tcas.createFS(tokenAnnType);
  tok4.setIntValue(tokenNbrFeat, 4);

  FeatureStructure tok5 = tcas.createFS(tokenAnnType);
  tok5.setIntValue(tokenNbrFeat, 5);

  FeatureStructure tok6 = tcas.createFS(tokenAnnType);
  tok6.setIntValue(tokenNbrFeat, 6);

  FeatureStructure tokens[] = {
                                tok0, tok1, tok2, tok3, tok4, tok5, tok6
                              };
  size_t tokNum = NUMBEROF(tokens);
  ASSERT_OR_THROWEXCEPTION( tokNum == 7);

  ListFS tokList = tcas.createListFS();

  ASSERT_OR_THROWEXCEPTION( tokList.isEmpty() );
  ASSERT_OR_THROWEXCEPTION( tokList.getLength() == 0 );

  tokList.addFirst(tok3);
  ASSERT_OR_THROWEXCEPTION( tokList.getLength() == 1 );

  tokList.addLast(tok4);
  tokList.addFirst(tok2);
  tokList.addLast(tok5);
  tokList.addFirst(tok1);
  tokList.addLast(tok6);
  tokList.addFirst(tok0);

  ListFS fs(tokList);
  ASSERT_OR_THROWEXCEPTION( tokList.getLength() == tokNum );
  size_t i;
  for (i=0; i<tokNum; ++i) {
    LOG("Examining list element " << i);
    assert(!fs.isEmpty());
    FeatureStructure element = fs.getHead();
    int j = element.getIntValue(tokenNbrFeat);
    ASSERT_OR_THROWEXCEPTION(i == j);
    fs.moveToNext();
  }
  ASSERT_OR_THROWEXCEPTION( fs.isEmpty() );

  ASSERT_OR_THROWEXCEPTION( tokList.getHead() == tok0 );

  tokList.setHead(tok6);
  ASSERT_OR_THROWEXCEPTION( tokList.getHead() == tok6);

  {
    // test appending of lists
    ListFS eList1 = tcas.createListFS();
    ASSERT_OR_THROWEXCEPTION( eList1.isEmpty() );
    ListFS neList1 = tcas.createListFS();
    neList1.addFirst(tok1);
    ASSERT_OR_THROWEXCEPTION( neList1.getLength() == 1 );
    eList1.append(neList1); // append a non-empty list to an empty list
    ASSERT_OR_THROWEXCEPTION( eList1.getLength() == 1 );
    ASSERT_OR_THROWEXCEPTION( neList1.getLength() == eList1.getLength() );

    ListFS eList2  = tcas.createListFS();
    ASSERT_OR_THROWEXCEPTION( eList2.isEmpty() );
    ListFS neList2 = tcas.createListFS();
    neList2.addFirst(tok1);
    ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
    neList2.append(eList2); // append an empty list to a non-empty list
    ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
    ASSERT_OR_THROWEXCEPTION( eList2.getLength() == 0 );

    ListFS neList3 = tcas.createListFS();
    neList3.addFirst(tok1);
    ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 1 );
    ListFS neList4 = tcas.createListFS();
    neList4.addFirst(tok2);
    ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );
    neList3.append(neList4); // append a non-empty list to a non-empty list
    ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 2 );
    ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );

    bool bExcCaught = false;
    ListFS neList5 = tcas.createListFS();
    neList5.addFirst(tok1);
    ASSERT_OR_THROWEXCEPTION( neList5.getLength() == 1 );
    try {
      neList5.append(neList5); // append a non-empty list to itself
    } catch (ListIsCircularException e) {
      bExcCaught = true;
    }
    ASSERT_OR_THROWEXCEPTION( bExcCaught );

    ListFS eList6 = tcas.createListFS();
    ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
    eList6.append(eList6); // append an empty list to itself
    ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );

    ListFS eList7 = tcas.createListFS();
    ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
    ListFS eList8 = tcas.createListFS();
    ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
    eList7.append(eList8); // append an empty list to an empty list
    ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
    ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );

  }

  {
    // test prepending of lists
    ListFS eList1 = tcas.createListFS();
    ASSERT_OR_THROWEXCEPTION( eList1.isEmpty() );
    ListFS neList1 = tcas.createListFS();
    neList1.addFirst(tok1);
    ASSERT_OR_THROWEXCEPTION( neList1.getLength() == 1 );
    eList1.prepend(neList1); // prepend a non-empty list to an empty list
    ASSERT_OR_THROWEXCEPTION( eList1.getLength() == 1 );
    ASSERT_OR_THROWEXCEPTION( neList1.getLength() == eList1.getLength() );

    ListFS eList2 = tcas.createListFS();
    ASSERT_OR_THROWEXCEPTION( eList2.isEmpty() );
    ListFS neList2 = tcas.createListFS();
    neList2.addFirst(tok1);
    ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
    neList2.prepend(eList2); // prepend an empty list to a non-empty list
    ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
    ASSERT_OR_THROWEXCEPTION( eList2.getLength() == 0 );

    ListFS neList3 = tcas.createListFS();
    neList3.addFirst(tok1);
    ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 1 );
    ListFS neList4 = tcas.createListFS();
    neList4.addFirst(tok2);
    ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );
    neList3.prepend(neList4); // prepend a non-empty list to a non-empty list
    ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 2 );
    ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 2 );

    bool bExcCaught = false;
    ListFS neList5 = tcas.createListFS();
    neList5.addFirst(tok1);
    ASSERT_OR_THROWEXCEPTION( neList5.getLength() == 1 );
    try {
      neList5.prepend(neList5); // prepend a non-empty list to itself
    } catch (ListIsCircularException e) {
      bExcCaught = true;
    }
    ASSERT_OR_THROWEXCEPTION( bExcCaught );

    ListFS eList6 = tcas.createListFS();
    ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
    eList6.prepend(eList6); // prepend an empty list to itself
    ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );

    ListFS eList7 = tcas.createListFS();
    ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
    ListFS eList8 = tcas.createListFS();
    ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
    eList7.prepend(eList8); // prepend an empty list to an empty list
    ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
    ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
  }

  ;
  // test nested addFirst/addLast
  ListFS list  = tcas.createListFS();
  list.addFirst(tok0);
  ListFS list0 = list;
  ASSERT_OR_THROWEXCEPTION( list.getLength()  == 1 );
  ASSERT_OR_THROWEXCEPTION( list0.getLength() == 1 );
  list = list.addLast(tok1).addLast(tok2).addLast(tok3);
  ASSERT_OR_THROWEXCEPTION( list.getLength()  == 1 );
  ASSERT_OR_THROWEXCEPTION( list0.getLength() == 4);
  list = list.addFirst(tok1).addFirst(tok2).addFirst(tok3);
  ASSERT_OR_THROWEXCEPTION( list.getLength()  == 4 );
  ASSERT_OR_THROWEXCEPTION( list0.getLength() == 4 );
  list = list.addLast(tok1).addFirst(tok2).addLast(tok3);
  ASSERT_OR_THROWEXCEPTION( list.getLength()  == 1 );
  ASSERT_OR_THROWEXCEPTION( list0.getLength() == 6 );
  // test nested append/prepend
  ListFS list1, list2, list3;
  list1 = tcas.createListFS();
  list1.addFirst(tok1);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 1 );
  list2 = tcas.createListFS();
  list2.addFirst(tok2);
  ASSERT_OR_THROWEXCEPTION( list2.getLength() == 1 );
  list3 = tcas.createListFS();
  list3.addFirst(tok3);
  ASSERT_OR_THROWEXCEPTION( list3.getLength() == 1 );

  list1 = list1.append(list2).append(list3);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 3 );

  list1 = tcas.createListFS();
  list1.addFirst(tok1);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 1 );
  list2 = tcas.createListFS();
  list2.addFirst(tok2);
  ASSERT_OR_THROWEXCEPTION( list2.getLength() == 1 );
  list3 = tcas.createListFS();
  list3.addFirst(tok3);
  ASSERT_OR_THROWEXCEPTION( list3.getLength() == 1 );

  list1 = list1.prepend(list2).prepend(list3);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 3 );


  list1 = tcas.createListFS();
  list1.addFirst(tok1);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 1 );
  list2 = tcas.createListFS();
  list2.addFirst(tok2);
  ASSERT_OR_THROWEXCEPTION( list2.getLength() == 1 );
  list3 = tcas.createListFS();
  list3.addFirst(tok3);
  ASSERT_OR_THROWEXCEPTION( list3.getLength() == 1 );

  list1 = list1.append(list2).prepend(list3);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 3 );



  LOG("testOOListFunctions() finished");
}


template<class T>
class SimpleEquals {
public:
  bool equals(T t1, T t2) const {
    return t1 == t2;
  }
};

class StringEquals {
public:
  bool equals(UnicodeStringRef const & crp1,
              UnicodeStringRef const & crp2) const {
    LOG("Comparing: " << crp1 << " with " << crp2);
    return((UnicodeStringRef) crp1) == ((UnicodeStringRef) crp2);
  }
};

template< class LFS_TYPE, class COMP>
void testOOListFunctionsTempl(CAS & tcas, vector< typename LFS_TYPE::HeadType > & vec, COMP const & crComp) {
  LOG("testOOListFunctionsTempl() started");

  LFS_TYPE list = LFS_TYPE::createListFS(tcas);

  ASSERT_OR_THROWEXCEPTION( list.isEmpty() );
  ASSERT_OR_THROWEXCEPTION( list.getLength() == 0 );

  list.addFirst(vec[3]);
  ASSERT_OR_THROWEXCEPTION( list.getLength() == 1 );

  list.addLast(vec[4]);
  list.addFirst(vec[2]);
  list.addLast(vec[5]);
  list.addFirst(vec[1]);
  list.addLast(vec[6]);
  list.addFirst(vec[0]);

  const size_t uiNUMBER_OF_ELEMENTS = 7;

  LFS_TYPE fs(list);
  ASSERT_OR_THROWEXCEPTION( list.getLength() == uiNUMBER_OF_ELEMENTS );
  size_t i;
  for (i=0; i<uiNUMBER_OF_ELEMENTS; ++i) {
    LOG("Examining list element " << i);
    assert(!fs.isEmpty());
    typename LFS_TYPE::HeadType element = fs.getHead();
    ASSERT_OR_THROWEXCEPTION( crComp.equals( element, vec[i]) );
    fs.moveToNext();
  }
  ASSERT_OR_THROWEXCEPTION( fs.isEmpty() );

  ASSERT_OR_THROWEXCEPTION( crComp.equals( list.getHead(), vec[0]) );

  list.setHead(vec[6]);
  ASSERT_OR_THROWEXCEPTION( crComp.equals( list.getHead(), vec[6]) );

  {
    // test appending of lists
    LFS_TYPE eList1 = LFS_TYPE::createListFS(tcas);
    ASSERT_OR_THROWEXCEPTION( eList1.isEmpty() );
    LFS_TYPE neList1 = LFS_TYPE::createListFS(tcas, vec[1]);
    ASSERT_OR_THROWEXCEPTION( neList1.getLength() == 1 );
    eList1.append(neList1); // append a non-empty list to an empty list
    ASSERT_OR_THROWEXCEPTION( eList1.getLength() == 1 );
    ASSERT_OR_THROWEXCEPTION( neList1.getLength() == eList1.getLength() );

    LFS_TYPE eList2  = LFS_TYPE::createListFS(tcas);
    ASSERT_OR_THROWEXCEPTION( eList2.isEmpty() );
    LFS_TYPE neList2 = LFS_TYPE::createListFS(tcas, vec[1]);
    ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
    neList2.append(eList2); // append an empty list to a non-empty list
    ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
    ASSERT_OR_THROWEXCEPTION( eList2.getLength() == 0 );

    LFS_TYPE neList3 = LFS_TYPE::createListFS(tcas, vec[1]);
    ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 1 );
    LFS_TYPE neList4 = LFS_TYPE::createListFS(tcas, vec[2]);
    ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );
    neList3.append(neList4); // append a non-empty list to a non-empty list
    ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 2 );
    ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );

    bool bExcCaught = false;
    LFS_TYPE neList5 = LFS_TYPE::createListFS(tcas, vec[1]);
    ASSERT_OR_THROWEXCEPTION( neList5.getLength() == 1 );
    try {
      neList5.append(neList5); // append a non-empty list to itself
    } catch (ListIsCircularException e) {
      bExcCaught = true;
    }
    ASSERT_OR_THROWEXCEPTION( bExcCaught );

    LFS_TYPE eList6 = LFS_TYPE::createListFS(tcas);
    ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
    eList6.append(eList6); // append an empty list to itself
    ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );

    LFS_TYPE eList7 = LFS_TYPE::createListFS(tcas);
    ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
    LFS_TYPE eList8 = LFS_TYPE::createListFS(tcas);
    ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
    eList7.append(eList8); // append an empty list to an empty list
    ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
    ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );

  }

  {
    // test prepending of lists
    LFS_TYPE eList1 = LFS_TYPE::createListFS(tcas);
    ASSERT_OR_THROWEXCEPTION( eList1.isEmpty() );
    LFS_TYPE neList1 = LFS_TYPE::createListFS(tcas, vec[1]);
    ASSERT_OR_THROWEXCEPTION( neList1.getLength() == 1 );
    eList1.prepend(neList1); // prepend a non-empty list to an empty list
    ASSERT_OR_THROWEXCEPTION( eList1.getLength() == 1 );
    ASSERT_OR_THROWEXCEPTION( neList1.getLength() == eList1.getLength() );

    LFS_TYPE eList2 = LFS_TYPE::createListFS(tcas);
    ASSERT_OR_THROWEXCEPTION( eList2.isEmpty() );
    LFS_TYPE neList2 = LFS_TYPE::createListFS(tcas, vec[1]);
    ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
    neList2.prepend(eList2); // prepend an empty list to a non-empty list
    ASSERT_OR_THROWEXCEPTION( neList2.getLength() == 1 );
    ASSERT_OR_THROWEXCEPTION( eList2.getLength() == 0 );

    LFS_TYPE neList3 = LFS_TYPE::createListFS(tcas, vec[1]);
    ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 1 );
    LFS_TYPE neList4 = LFS_TYPE::createListFS(tcas, vec[2]);
    ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 1 );
    neList3.prepend(neList4); // prepend a non-empty list to a non-empty list
    ASSERT_OR_THROWEXCEPTION( neList3.getLength() == 2 );
    ASSERT_OR_THROWEXCEPTION( neList4.getLength() == 2 );

    bool bExcCaught = false;
    LFS_TYPE neList5 = LFS_TYPE::createListFS(tcas, vec[1]);
    ASSERT_OR_THROWEXCEPTION( neList5.getLength() == 1 );
    try {
      neList5.prepend(neList5); // prepend a non-empty list to itself
    } catch (ListIsCircularException e) {
      bExcCaught = true;
    }
    ASSERT_OR_THROWEXCEPTION( bExcCaught );

    LFS_TYPE eList6 = LFS_TYPE::createListFS(tcas);
    ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );
    eList6.prepend(eList6); // prepend an empty list to itself
    ASSERT_OR_THROWEXCEPTION( eList6.getLength() == 0 );

    LFS_TYPE eList7 = LFS_TYPE::createListFS(tcas);
    ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
    LFS_TYPE eList8 = LFS_TYPE::createListFS(tcas);
    ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
    eList7.prepend(eList8); // prepend an empty list to an empty list
    ASSERT_OR_THROWEXCEPTION( eList7.getLength() == 0 );
    ASSERT_OR_THROWEXCEPTION( eList8.getLength() == 0 );
  }

  ;
  // test nested addFirst/addLast
  list  = LFS_TYPE::createListFS(tcas, vec[0]);
  LFS_TYPE list0 = list;
  ASSERT_OR_THROWEXCEPTION( list.getLength()  == 1 );
  ASSERT_OR_THROWEXCEPTION( list0.getLength() == 1 );
  list = list.addLast(vec[1]).addLast(vec[2]).addLast(vec[3]);
  ASSERT_OR_THROWEXCEPTION( list.getLength()  == 1 );
  ASSERT_OR_THROWEXCEPTION( list0.getLength() == 4);
  list = list.addFirst(vec[1]).addFirst(vec[2]).addFirst(vec[3]);
  ASSERT_OR_THROWEXCEPTION( list.getLength()  == 4 );
  ASSERT_OR_THROWEXCEPTION( list0.getLength() == 4 );
  list = list.addLast(vec[1]).addFirst(vec[2]).addLast(vec[3]);
  ASSERT_OR_THROWEXCEPTION( list.getLength()  == 1 );
  ASSERT_OR_THROWEXCEPTION( list0.getLength() == 6 );
  // test nested append/prepend
  LFS_TYPE list1, list2, list3;
  list1 = LFS_TYPE::createListFS(tcas, vec[1]);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 1 );
  list2 = LFS_TYPE::createListFS(tcas, vec[2]);
  ASSERT_OR_THROWEXCEPTION( list2.getLength() == 1 );
  list3 = LFS_TYPE::createListFS(tcas, vec[3]);
  ASSERT_OR_THROWEXCEPTION( list3.getLength() == 1 );

  list1 = list1.append(list2).append(list3);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 3 );

  list1 = LFS_TYPE::createListFS(tcas, vec[1]);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 1 );
  list2 = LFS_TYPE::createListFS(tcas, vec[2]);
  ASSERT_OR_THROWEXCEPTION( list2.getLength() == 1 );
  list3 = LFS_TYPE::createListFS(tcas, vec[3]);
  ASSERT_OR_THROWEXCEPTION( list3.getLength() == 1 );

  list1 = list1.prepend(list2).prepend(list3);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 3 );


  list1 = LFS_TYPE::createListFS(tcas, vec[1]);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 1 );
  list2 = LFS_TYPE::createListFS(tcas, vec[2]);
  ASSERT_OR_THROWEXCEPTION( list2.getLength() == 1 );
  list3 = LFS_TYPE::createListFS(tcas, vec[3]);
  ASSERT_OR_THROWEXCEPTION( list3.getLength() == 1 );

  list1 = list1.append(list2).prepend(list3);
  ASSERT_OR_THROWEXCEPTION( list1.getLength() == 3 );

  LOG("testOOListFunctionsTempl() finished");
}

void testOOListFunctions() {
  LOG("testOOFSListFunctions() started");
  testOOListFunctionsOld();

  TestCAS testcas;
  uima::internal::CASImpl& tcas = testcas.getCAS();

  TypeSystem const & typeSystem = tcas.getTypeSystem();

  Type tokenAnnType = typeSystem.getType(TT::TYPE_NAME_TOKEN_ANNOTATION);

  size_t i;
  vector<FeatureStructure> vecFS;
  for (i=0; i < 10; ++i) {
    vecFS.push_back(tcas.createFS(tokenAnnType));
  }
  SimpleEquals<FeatureStructure> fsComp;
  testOOListFunctionsTempl<ListFS>(tcas, vecFS, fsComp);

  vector<float> vecFloat;
  for (i=0; i < 10; ++i) {
    vecFloat.push_back((float)i);
  }
  SimpleEquals<float> floatComp;
  testOOListFunctionsTempl<FloatListFS>(tcas, vecFloat, floatComp);

  vector<int> vecInt;
  for (i=0; i < 10; ++i) {
    vecInt.push_back((int)i);
  }
  SimpleEquals<int> intComp;
  testOOListFunctionsTempl<IntListFS>(tcas, vecInt, intComp);

  LOG("Testing string lists");
  icu::UnicodeString us("12345678901234");
  UChar const * pu = us.getBuffer();
  vector<UnicodeStringRef > vecStr;
  for (i=0; i < 10; ++i) {
    UnicodeStringRef p(pu, i + 1);
    vecStr.push_back(p);
    LOG("string list element: " << i << ": " << p );
  }
  StringEquals streq;
  testOOListFunctionsTempl<StringListFS>(tcas, vecStr, streq);


  LOG("test deletion");

  IntListFS intList = tcas.createIntListFS();
  intList = intList.addLast(0);
  for (i=1; i<vecInt.size(); ++i) {
    intList.addLast(i);
  }

  IntListFS tempIntList = intList;
  size_t j=0;
  while (!tempIntList.isEmpty()) {
    int head = tempIntList.getHead();
    LOG("Head: " << head << ", expected int: " << j);
    ASSERT_OR_THROWEXCEPTION(j < vecInt.size() );
    ASSERT_OR_THROWEXCEPTION(head == vecInt[j]);
    ++j;
    tempIntList = tempIntList.getTail();
  }

  int iElemToBeDeleted = 2;
  tempIntList = intList;
  j=0;
  while (!tempIntList.isEmpty()) {
    int head = tempIntList.getHead();
    ASSERT_OR_THROWEXCEPTION(j < vecInt.size() );
    ASSERT_OR_THROWEXCEPTION(head == vecInt[j]);
    if (j == iElemToBeDeleted) {
      LOG("Deleting element: " << iElemToBeDeleted+1);
      IntListFS intList2 = tempIntList.getTail();
      ASSERT_OR_THROWEXCEPTION( ! intList2.isEmpty() );
      tempIntList.setTail( intList2.getTail() );
      break;
    }
    ++j;
    tempIntList = tempIntList.getTail();
  }
  ASSERT_OR_THROWEXCEPTION( ! tempIntList.isEmpty() );

  bool bDeleted = false;
  tempIntList = intList;
  j=0;
  while (!tempIntList.isEmpty()) {
    int head = tempIntList.getHead();
    ASSERT_OR_THROWEXCEPTION(j < vecInt.size() );
//      LOG("Head: " << head << ", expected int: " << j);

    if (j == iElemToBeDeleted+1) {
      LOG("Skipping deleted element: " << j );
      ++j;
      bDeleted = true;
    }
    LOG("Head: " << head << ", expected int: " << j);
    ASSERT_OR_THROWEXCEPTION(head == vecInt[j]);
    ++j;
    tempIntList = tempIntList.getTail();
  }
  ASSERT_OR_THROWEXCEPTION( bDeleted );

  LOG("testOOListFunctions() finished");
}


/************************************************************************************/

template < class T,
const uima::lowlevel::TyFSType LType,
const uima::lowlevel::TyFSType ELType,
const uima::lowlevel::TyFSType NELType,
const uima::lowlevel::TyFSType HeadFeat,
const uima::lowlevel::TyFSType TailFeat>
void testDeleteElementFromList(BasicListFS< T, LType, ELType, NELType, HeadFeat, TailFeat> list,
                               T const & element,
                               vector<T> const & v) {
  BasicListFS< T, LType, ELType, NELType, HeadFeat, TailFeat> newList = list.removeElement(element);
  int i=0;
  while (! list.isEmpty() ) {

    if (list.getHead() == element) {
      LOG("Element: " << element << " should have been deleted!!");
      ASSERT_OR_THROWEXCEPTION(false);
    }
    if (element == v[i]) {
      ASSERT_OR_THROWEXCEPTION( newList.isValid() );
      ++i;
    }
    list = list.getTail();
    ++i;
  }
  if ( newList.isValid() ) {
    ASSERT_OR_THROWEXCEPTION( newList.getHead() == element );
    BasicListFS< T, LType, ELType, NELType, HeadFeat, TailFeat> newListTail = newList.getTail();
    ASSERT_OR_THROWEXCEPTION( newListTail.isEmpty() );
  }
}

void testDeleteElementFromList() {
  LOG("testDeleteElementFromList() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();

  const int ELEMENT_NUM = 10;
  int i,j;
  for (j=0; j<ELEMENT_NUM; ++j) {
    IntListFS intList = tcas.createIntListFS();
    vector<int> v;
    LOG("Testing list of length " << j);
    for (i=0; i<j; ++i) {
      intList.addLast(i);
      v.push_back(i);
    }
    ASSERT_OR_THROWEXCEPTION( intList.getLength() == j );

    for (i=0; i<ELEMENT_NUM; ++i) {
      testDeleteElementFromList(intList, i, v);
    }

  }
  LOG("testDeleteElementFromList() finished");
}

/************************************************************************************/

void testNullFSs() {
  LOG("testNullFSs() started");
  ASSERT_OR_THROWEXCEPTION( uima::lowlevel::FSHeap::INVALID_FS == 0 );
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();

  LOG("Test Null FS on lowlevel API");
  uima::lowlevel::TypeSystem const & lolTypeSys = tcas.getHeap().getTypeSystem();
  uima::lowlevel::FSHeap & lolFSHeap = tcas.getHeap();
  uima::lowlevel::TyFSType lolAnnotType = lolTypeSys.getTypeByName(TT::TYPE_NAME_TOKEN_ANNOTATION);
  uima::lowlevel::TyFSFeature lolBeginPosFeature = lolTypeSys.getFeatureByBaseName(lolAnnotType, CAS::FEATURE_BASE_NAME_BEGIN);
  uima::lowlevel::TyFSFeature lolLemmaListFeature = lolTypeSys.getFeatureByBaseName(lolAnnotType, TT::FEATURE_BASE_NAME_LEMMA_ENTRIES);

  lowlevel::TyFS lolFS = lolFSHeap.createFS(lolAnnotType);
  ASSERT_OR_THROWEXCEPTION( lolFSHeap.getIntValue(lolFS, lolBeginPosFeature) == 0 );
  lowlevel::TyFS lolInvalidLemmaList = lolFSHeap.getFSValue(lolFS, lolLemmaListFeature );
  ASSERT_OR_THROWEXCEPTION( lolInvalidLemmaList == 0 );

  LOG("Test Null FS on OO API");
  TypeSystem const & typeSys = tcas.getTypeSystem();

  Type annotType = typeSys.getType(TT::TYPE_NAME_TOKEN_ANNOTATION);
  Feature beginPosFeature = annotType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_BEGIN);
  Feature lemmaListFeature = annotType.getFeatureByBaseName( TT::FEATURE_BASE_NAME_LEMMA_ENTRIES);

  FeatureStructure fs = tcas.createFS(annotType);
  ASSERT_OR_THROWEXCEPTION( fs.getIntValue(beginPosFeature) == 0 );
  FeatureStructure invalidLemmaList = fs.getFSValue(lemmaListFeature);
  ASSERT_OR_THROWEXCEPTION( ! invalidLemmaList.isValid() );

  LOG("testNullFSs() finished");
}

/************************************************************************************/

void testFullyQualifiedFeatureNames() {
  LOG("testFullyQualifiedFeatureNames() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();

  icu::UnicodeString annotBeginPos(CAS::TYPE_NAME_ANNOTATION);
  annotBeginPos.append(":");
  annotBeginPos.append(CAS::FEATURE_BASE_NAME_BEGIN);

  icu::UnicodeString tokenBeginPos(TT::TYPE_NAME_TOKEN_ANNOTATION);
  tokenBeginPos.append(":");
  tokenBeginPos.append(CAS::FEATURE_BASE_NAME_BEGIN);

  uima::TypeSystem const & typeSys = tcas.getTypeSystem();
  Type annotType = typeSys.getType(CAS::TYPE_NAME_ANNOTATION);
  ASSERT_OR_THROWEXCEPTION( annotType.isValid() );
  Type tokenType = typeSys.getType(TT::TYPE_NAME_TOKEN_ANNOTATION);
  ASSERT_OR_THROWEXCEPTION( tokenType.isValid() );

  LOG("get feature: '" << annotBeginPos << "'");
  Feature beginPosFeature = typeSys.getFeatureByFullName(annotBeginPos);
  ASSERT_OR_THROWEXCEPTION( beginPosFeature.isValid() );

  uima::Feature beginPosFeature1 = typeSys.getFeatureByFullName( tokenBeginPos );
  ASSERT_OR_THROWEXCEPTION( beginPosFeature1.isValid() );
  ASSERT_OR_THROWEXCEPTION( beginPosFeature1 == beginPosFeature );

  uima::Feature beginPosFeature2 = annotType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_BEGIN);
  ASSERT_OR_THROWEXCEPTION( beginPosFeature2.isValid() );
  ASSERT_OR_THROWEXCEPTION( beginPosFeature2 == beginPosFeature );

  uima::Feature beginPosFeature3 = tokenType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_BEGIN);
  ASSERT_OR_THROWEXCEPTION( beginPosFeature3.isValid() );
  ASSERT_OR_THROWEXCEPTION( beginPosFeature3 == beginPosFeature );

  /*
  uima::Feature beginPosFeature4 = typeSys.getFeature( CAS::TYPE_NAME_ANNOTATION, CAS::FEATURE_BASE_NAME_BEGIN);
  ASSERT_OR_THROWEXCEPTION( beginPosFeature4.isValid() );
  ASSERT_OR_THROWEXCEPTION( beginPosFeature4 == beginPosFeature );

  uima::Feature beginPosFeature5 = typeSys.getFeature( TT::TYPE_NAME_TOKEN_ANNOTATION, CAS::FEATURE_BASE_NAME_BEGIN);
  ASSERT_OR_THROWEXCEPTION( beginPosFeature5.isValid() );
  ASSERT_OR_THROWEXCEPTION( beginPosFeature5 == beginPosFeature );
  */
 
  LOG("testFullyQualifiedFeatureNames() finished");
}
/************************************************************************************/
void testTypeNameSpaces() {
  LOG("testTypeNameSpaces() started");
  /*
    top
       n1.t1 [f1: t3, g1:t4]
       n1.n2.t2 [f2:t2]
       n1.n2.t3
       n4.t1
   */
  TTDefinition ttdef;
  ttdef.init();

  lowlevel::TypeSystem& ts = ttdef.getTypeSystem();

  lowlevel::TyFSType top = ts.getTopType();
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(top) );
  lowlevel::TyFSType t1 = ts.createType(top, "n1.t1", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t1) );
  lowlevel::TyFSType t2 = ts.createType(top, "n1.n2.t2", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t2) );
  lowlevel::TyFSType t3 = ts.createType(top, "n1.n2.t3", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t3) );
  lowlevel::TyFSType t4 = ts.createType(top, "n4.t1", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidType(t4) );

  lowlevel::TyFSFeature f1 = ts.createFeature(t1, t3, false, "f1", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f1) );
  lowlevel::TyFSFeature g1 = ts.createFeature(t1, t4, false, "g1", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(g1) );
  lowlevel::TyFSFeature f2 = ts.createFeature(t2, t2, false, "f2", ustrCreatorID);
  ASSERT_OR_THROWEXCEPTION( ts.isValidFeature(f2) );

  ttdef.commit();

//      uima::internal::TCASImpl cas(ttdef, 1000, 1000, 1000);
   uima::internal::CASImpl * pCas = getCASImpl(ttdef);
  uima::internal::CASImpl & cas = *pCas;
  TypeSystem const & typeSys = cas.getTypeSystem();

  TypeNameSpace n1(typeSys, "n1");
  vector<Type> types;
  n1.getAllTypes(types);
  LOG("namespace size: " << types.size() << ", expected size: 1");
  ASSERT_OR_THROWEXCEPTION( types.size() == 1);

  ASSERT_OR_THROWEXCEPTION( n1.getType("t1").isValid() );

  TypeNameSpace n1n2(typeSys, "n1.n2");
  n1n2.getAllTypes(types);
  LOG("namespace size: " << types.size() << ", expected size: 2");
  ASSERT_OR_THROWEXCEPTION( types.size() == 2);
  ASSERT_OR_THROWEXCEPTION( n1n2.getType("t2").isValid() );
  ASSERT_OR_THROWEXCEPTION( n1n2.getType("t3").isValid() );

  TypeNameSpace n4(typeSys, "n4");
  n4.getAllTypes(types);
  LOG("namespace size: " << types.size() << ", expected size: 1");
  ASSERT_OR_THROWEXCEPTION( types.size() == 1);
  ASSERT_OR_THROWEXCEPTION( n4.getType("t1").isValid() );


  TypeNameSpaceImport import(typeSys);
  import.addNameSpace(n1);
  import.addNameSpace(n1n2);
  import.addNameSpace(n4);

  import.getAllTypes(types);

  LOG("namespace size: " << types.size() << ", expected size: 4");
  ASSERT_OR_THROWEXCEPTION(types.size() == 4);

  for ( unsigned int i = 0; i < types.size(); ++i ) {
    Type typ = types[i];
    LOG("  Type: " << typ.getName());
  }

  Type t;
  bool noConflict;
  noConflict = import.getType("t2", t);
  ASSERT_OR_THROWEXCEPTION( noConflict );
  ASSERT_OR_THROWEXCEPTION( t.isValid() );

  noConflict = import.getType("t3", t);
  ASSERT_OR_THROWEXCEPTION( noConflict );
  ASSERT_OR_THROWEXCEPTION( t.isValid() );

  noConflict = import.getType("t1", t);
  ASSERT_OR_THROWEXCEPTION( ! noConflict );
  ASSERT_OR_THROWEXCEPTION( ! t.isValid() );

  delete pCas;
  LOG("testTypeNameSpaces() finished");
}
/************************************************************************************/

void testCASReset() {
  LOG("testCASReset() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();
  uima::FSIndexRepository & indexRep = tcas.getIndexRepository();

  TypeSystem const & typeSys = tcas.getTypeSystem();

  Type annotType = typeSys.getType(TT::TYPE_NAME_TOKEN_ANNOTATION);
  Feature beginPosFeature = annotType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_BEGIN);
  Feature endPosFeature = annotType.getFeatureByBaseName( CAS::FEATURE_BASE_NAME_END);

  LOG("Creating FSs");
  FeatureStructure fs1 = tcas.createFS(annotType);
  ASSERT_OR_THROWEXCEPTION( fs1.isUntouchedFSValue(beginPosFeature) );
  fs1.setIntValue( beginPosFeature, 1 );
  ASSERT_OR_THROWEXCEPTION( ! fs1.isUntouchedFSValue(beginPosFeature) );
  fs1.setIntValue( endPosFeature, 2 );
  indexRep.addFS( fs1 );

  FeatureStructure fs2 = tcas.createFS(annotType);
  fs2.setIntValue( beginPosFeature, 1 );
  fs2.setIntValue( endPosFeature, 3 );
  indexRep.addFS( fs2 );

  FeatureStructure fs3 = tcas.createFS(annotType);
  fs3.setIntValue( beginPosFeature, 3 );
  fs3.setIntValue( endPosFeature, 4 );
  indexRep.addFS( fs3 );

  FeatureStructure fs4 = tcas.createFS(annotType);
  fs4.setIntValue( beginPosFeature, 4 );
  fs4.setIntValue( endPosFeature, 5 );
  indexRep.addFS( fs4 );

  FeatureStructure fs41 = tcas.createFS(annotType);
  fs41.setIntValue( beginPosFeature, 4 );
  fs41.setIntValue( endPosFeature, 5 );
  indexRep.addFS( fs41 );
  LOG("...FSs created");

  icu::UnicodeString const & indexID = tcas.getAnnotationIndexID();
  ASSERT_OR_THROWEXCEPTION( tcas.getIndexRepository().getIndex(indexID, annotType).getSize() == 5);
  ASSERT_OR_THROWEXCEPTION( fs1.isValid() );

  tcas.reset();

  ASSERT_OR_THROWEXCEPTION( tcas.getIndexRepository().getIndex(indexID, annotType).getSize() == 0);
  ASSERT_OR_THROWEXCEPTION( ! fs1.isValid() );



  LOG("testCASReset() finished");
}

/************************************************************************************/

void testClone() {
  LOG("testClone() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();

  uima::TypeSystem const & ts = tcas.getTypeSystem();

  uima::Type lemmaType = ts.getType(TT::TYPE_NAME_LEMMA);
  uima::Feature posFeature = lemmaType.getFeatureByBaseName( TT::FEATURE_BASE_NAME_PART_OF_SPEECH);
  uima::Feature morphIDFeature = lemmaType.getFeatureByBaseName( TT::FEATURE_BASE_NAME_MORPH_ID);
  uima::Feature keyFeature = lemmaType.getFeatureByBaseName( TT::FEATURE_BASE_NAME_KEY);

  const int pos = 1;
  const int morphID = 2;
  icu::UnicodeString str("str");
  UnicodeStringRef uref(str.getBuffer(), str.length());

  uima::FeatureStructure fs1 = tcas.createFS(lemmaType);
  fs1.setIntValue(posFeature, pos);
  fs1.setIntValue(morphIDFeature, morphID);
  fs1.setStringValueExternal(keyFeature, uref);

  uima::FeatureStructure fs2 = fs1.clone();

//   tcas.getFSSystem().getLowlevelFSHeap().print(cout);

  ASSERT_OR_THROWEXCEPTION( fs2.getIntValue(posFeature) == pos );
  UnicodeStringRef uref2 = fs2.getStringValue(keyFeature);
  ASSERT_OR_THROWEXCEPTION( uref2 == uref );
#ifdef EXTERNAL_STRINGS_ARE_SUPPORTED_AGAIN
  ASSERT_OR_THROWEXCEPTION( uref2.getBuffer() == uref.getBuffer() );
#endif
  ASSERT_OR_THROWEXCEPTION( fs2.getIntValue(morphIDFeature) == morphID );
  LOG("testClone() finished");
}


/************************************************************************************/

void testXMLTypeSystemReader() {
  LOG("testXMLTypeSystemReader() started");

  try {
    XMLPlatformUtils::Initialize();
  } catch (const XMLException&) {
    ASSERT_OR_THROWEXCEPTION(false);
  }

  TTDefinition ttdef;
  ttdef.init();

  lowlevel::TypeSystem & ts = ttdef.getTypeSystem();

  uima::XMLTypeSystemReader xmlReader(ts);
  LOG("Reading file");

  char const * xmlfile =
    "<?xml version=\"1.0\"?>"
    "<type_system>"
    "<type name=\"top\">"
    "  <type name=\"t1\">"
    "    <feature name=\"f1\" range=\"t21\" multirefs=\"false\"/>"
    "    <feature name=\"f2\" range=\"t1\" multirefs=\"true\"/>"
    "  </type>"
    "  <type name=\"t2\">"
    "     <type name=\"t21\">"
    "       <feature name=\"f1\" range=\"t21\" multirefs=\"false\"/>"
    "     </type>"
    "  </type>"
    "</type>"
    "</type_system>";

  xmlReader.readMemory(xmlfile, ustrCreatorID);
  ttdef.commit();

//      uima::internal::TCASImpl tcas(ttdef, 5000, 5000, 5000);
   uima::internal::CASImpl * pCas = getCASImpl(ttdef);
  uima::internal::CASImpl & tcas = *pCas;
  uima::TypeSystem const & crTypeSystem = tcas.getTypeSystem();

  uima::Type top = crTypeSystem.getTopType();
  ASSERT_OR_THROWEXCEPTION( top.isValid());

  uima::Type t1 = crTypeSystem.getType("t1");
  ASSERT_OR_THROWEXCEPTION( t1.isValid() );
  ASSERT_OR_THROWEXCEPTION( top.subsumes(t1) );

  uima::Type t2 = crTypeSystem.getType("t2");
  ASSERT_OR_THROWEXCEPTION( t2.isValid() );
  ASSERT_OR_THROWEXCEPTION( top.subsumes(t2) );

  uima::Type t21 = crTypeSystem.getType("t21");
  ASSERT_OR_THROWEXCEPTION( t21.isValid() );
  ASSERT_OR_THROWEXCEPTION( top.subsumes(t21) );
  ASSERT_OR_THROWEXCEPTION( t2.subsumes(t21) );

  uima::Feature f1 = t1.getFeatureByBaseName( "f1");
  ASSERT_OR_THROWEXCEPTION( f1.isValid() );
  uima::Type f1dom;
  f1.getRangeType(f1dom);
  ASSERT_OR_THROWEXCEPTION( f1dom == t21 );
  ASSERT_OR_THROWEXCEPTION( ! f1.isMultipleReferencesAllowed() );

  uima::Feature f2 = crTypeSystem.getFeatureByFullName("t1:f2");
  ASSERT_OR_THROWEXCEPTION( f2.isValid() );
  uima::Type f2dom;
  f2.getRangeType(f2dom);
  ASSERT_OR_THROWEXCEPTION( f2dom == t1 );
  ASSERT_OR_THROWEXCEPTION( f2.isMultipleReferencesAllowed() );



#ifndef NDEBUG
  ts.print(cout);
#endif

  XMLPlatformUtils::Terminate();
  delete pCas;
  LOG("testXMLTypeSystemReader() finished");
}



void testStringSubypes() {
  LOG("testStringSubypes() started");
  TTDefinition ttdef;
  ttdef.init();

  vector<icu::UnicodeString> v1;
  v1.push_back("a1");
  v1.push_back("b1");
  v1.push_back("c1");

  vector<icu::UnicodeString> v2;
  v2.push_back("a2");
  v2.push_back("b2");

  lowlevel::TypeSystem & ts = ttdef.getTypeSystem();
  lowlevel::TyFSType t1 = ts.createStringSubtype("t1", v1, "kreator");
  lowlevel::TyFSType t2 = ts.createStringSubtype("t2", v2, "kreator");

  lowlevel::TyFSType t = ts.createType(ts.getTopType(), "t", "kreator");
  lowlevel::TyFSFeature f1 = ts.createFeature(t, t1, false, "f1", "kreator");
  (void)ts.createFeature(t, t2, false, "f2", "kreator");

  ttdef.commit();

  ASSERT_OR_THROWEXCEPTION( ts.getTypeByName("t1") == t1 );
  ASSERT_OR_THROWEXCEPTION( ts.getTypeByName("t2") == t2 );

//      uima::internal::TCASImpl tcas(ttdef, 5000, 5000, 5000);
   uima::internal::CASImpl * pCas = getCASImpl(ttdef);
  uima::internal::CASImpl & tcas = *pCas;
  // lowlevel API
  lowlevel::FSHeap & heap = tcas.getHeap();

  lowlevel::TyFS fs1 = heap.createFS( t );

  icu::UnicodeString a1("a1");
  UnicodeStringRef a1Ref(a1);

  int a1Off = heap.addString(a1Ref);
  heap.setStringValue( fs1, f1, a1Off);
  ASSERT_OR_THROWEXCEPTION( heap.getStringValue( fs1, f1) == a1Ref);


  // OO API
  icu::UnicodeString inval("bla");

  FeatureStructure oo_fs = uima::internal::FSPromoter::promoteFS(fs1, tcas );
  Feature oo_f1 = tcas.getTypeSystem().getFeatureByFullName("t:f1");
  ASSERT_OR_THROWEXCEPTION( oo_f1.isValid() );
  icu::UnicodeString b1("b1");
  oo_fs.setStringValue( oo_f1, b1 );
  ASSERT_OR_THROWEXCEPTION( oo_fs.getStringValue(oo_f1) == b1 );

  bool bExcCaught = false;
  try {
    oo_fs.setStringValue(oo_f1, inval);
  } catch (WrongStringValueException const & exc) {
    bExcCaught = true;
    LOG("Exception thrown correctly: " << exc.asString());
  }
  ASSERT_OR_THROWEXCEPTION( bExcCaught );

  delete pCas;
  LOG("testStringSubypes() finished");
}


void testClone2() {
  LOG("testClone2() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();
  uima::TypeSystem const & ts = tcas.getTypeSystem();

  uima::Type lemmaType = ts.getType(TT::TYPE_NAME_LEMMA);
//   uima::Feature posFeature = lemmaType.getFeatureByBaseName( TT::FEATURE_BASE_NAME_PART_OF_SPEECH);
//   uima::Feature morphIDFeature = lemmaType.getFeatureByBaseName( TT::FEATURE_BASE_NAME_MORPH_ID);
  uima::Feature keyFeature = lemmaType.getFeatureByBaseName( TT::FEATURE_BASE_NAME_KEY);


  icu::UnicodeString str1("str1");
  uima::UnicodeStringRef ref1(str1);

  icu::UnicodeString str2("str2");
  uima::UnicodeStringRef ref2(str2);

  FeatureStructure fs1 = tcas.createFS(lemmaType);
  fs1.setStringValue(keyFeature, ref1);
  ASSERT_OR_THROWEXCEPTION( ref1 == fs1.getStringValue(keyFeature) );

//   tcas.getFSSystem().getLowlevelFSHeap().print(cout);

  FeatureStructure fs2 = fs1.clone();
//   tcas.getFSSystem().getLowlevelFSHeap().print(cout);
  fs2.setStringValue(keyFeature, ref2);
  ASSERT_OR_THROWEXCEPTION( ref2 == fs2.getStringValue(keyFeature) );

//   tcas.getFSSystem().getLowlevelFSHeap().print(cout);

  ASSERT_OR_THROWEXCEPTION( ref1 == fs1.getStringValue(keyFeature) );
  ASSERT_OR_THROWEXCEPTION( fs1.getStringValue(keyFeature) != fs2.getStringValue(keyFeature) );

  LOG("testClone2() finished");
}


void testClone3() {
  LOG("testClone3() started");
  TestCAS testcas;
  uima::internal::CASImpl & tcas = testcas.getCAS();
  uima::TypeSystem const & ts = tcas.getTypeSystem();
  uima::Type lemmaType = ts.getType(TT::TYPE_NAME_LEMMA);
  uima::Type keyStringEntryType = ts.getType(TT::TYPE_NAME_KEY_STRING_ENTRY);
  uima::Feature keyFeature = lemmaType.getFeatureByBaseName( TT::FEATURE_BASE_NAME_KEY);
  icu::UnicodeString str1("str1");
  uima::UnicodeStringRef ref1(str1);

  // 1. clone downward
  FeatureStructure fs1 = tcas.createFS(keyStringEntryType);
  fs1.setStringValue(keyFeature, ref1);
  ASSERT_OR_THROWEXCEPTION( ref1 == fs1.getStringValue(keyFeature) );

  FeatureStructure fs2 = fs1.clone( lemmaType );
  ASSERT_OR_THROWEXCEPTION( fs2.getType() == lemmaType );
  ASSERT_OR_THROWEXCEPTION( fs1.getStringValue(keyFeature) == fs2.getStringValue(keyFeature) );

  // 2. clone upward
  FeatureStructure fs3 = fs2.clone( keyStringEntryType );
  ASSERT_OR_THROWEXCEPTION( fs3.getType() == keyStringEntryType );
  ASSERT_OR_THROWEXCEPTION( fs3.getStringValue(keyFeature) == fs2.getStringValue(keyFeature) );

  // 3. clone sideways

  uima::Type canonFormType = ts.getType(TT::TYPE_NAME_CANONICAL_FORM);
  FeatureStructure fs4 = fs2.clone(canonFormType);
  ASSERT_OR_THROWEXCEPTION( fs4.getType() == canonFormType );
  ASSERT_OR_THROWEXCEPTION( fs4.getStringValue(keyFeature) == fs2.getStringValue(keyFeature) );

  ASSERT_OR_THROWEXCEPTION( fs2.getStringValue(keyFeature) == ref1);
  ASSERT_OR_THROWEXCEPTION( fs3.getStringValue(keyFeature) == ref1);
  ASSERT_OR_THROWEXCEPTION( fs4.getStringValue(keyFeature) == ref1);


  LOG("testClone3() finished");
}

/************************************************************************************/


int main() {
  LOG("*********************************");
  LOG("   UIMA5 regression test");
  LOG(" Please note that when running in debug");
  LOG(" mode the test routine testOOFilterBuilder()");
  LOG(" will report memory leaks because the TTDefinition");
  LOG(" does not properly clean up memory allocations.");

  LOG("*********************************");
  LOG("Go...");

  bool bSuccess = true;
  try {
    ResourceManager::createInstance("rsmgr");


    testLowLevelTypeSystem();
    testLowLevelTypeSystemExceptions();
    testLowLevelFSHeap();
    testFloatFeatures();
    testEmptyStrings();
    testLowLevelIndex();
    testNestedStructures();


  
    testStringSubypes();
    testFilters();
    testPermanentStructures();
    testIteratorSetToPosition();
   
    testOOIndex();
    testOOExceptions();

    testOOFilterBuilder();  //TTDefinition leak
    testOOArrayFS();
    testOOStringArrayFS();
    testClone();
    testClone2();
    testClone3();
    testOOListFunctions();
    testDeleteElementFromList();

    testCASReset();

    testNullFSs();


    testFullyQualifiedFeatureNames();
    testTypeNameSpaces();

    testXMLTypeSystemReader();
    
  } catch (Exception & exc) {
    LOG("UIMA exception: " << endl << exc.asString());
    bSuccess = false;
  } catch (SAXParseException const & saxexc) {
    LOG("SAXException: ");
    LOG( "Error at file " << UnicodeStringRef( (UChar*) saxexc.getSystemId() )
         << ", line " << saxexc.getLineNumber()
         << ", char " << saxexc.getColumnNumber()
         << "\n  Message: " << UnicodeStringRef( (UChar*)saxexc.getMessage()) );
    bSuccess = false;
  }
  catch (XMLException const & xmlexc) {
    LOG("XMLException: " << UnicodeStringRef( (UChar*) xmlexc.getMessage()) );
    bSuccess = false;
  }
  /*
  catch (...) {
     LOG("Unknown exception" << endl);
     bSuccess = false;
  }
  */

  if (!bSuccess) {
    LOG("*********************************");
    LOG("  UIMA5 regression test failed!!");
    LOG("*********************************");
    return 1;
  }

  LOG("*********************************");
  LOG("  UIMA5 regression test finished");
  LOG("                  successfully.");
  LOG("*********************************");
  return 0;
}


