/** \file cas.cpp .
-----------------------------------------------------------------------------


 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.

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

   Description:

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


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


/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp"
#include "uima/msg.h"
#include "uima/macros.h"

#include "uima/cas.hpp"
#include "uima/casdefinition.hpp"
#include "uima/internal_casimpl.hpp"
#include "uima/internal_typeshortcuts.hpp"
#include "uima/internal_fspromoter.hpp"
#include "uima/typesystem.hpp"
#include "uima/lowlevel_fsheap.hpp"
#include "uima/lowlevel_indexrepository.hpp"
#include "uima/listfs.hpp"
#include "uima/arrayfs.hpp"
#include "uima/lowlevel_typesystem.hpp"
#include "uima/lowlevel_typedefs.hpp"
#include "unicode/unistr.h"
#include "uima/fsfilterbuilder.hpp"
#include "uima/sofaid.hpp"
#include "uima/lowlevel_defaultfsiterator.hpp"
#include "uima/annotator_context.hpp"

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

#define UIMA_CAS_NAMESPACE "uima" UIMA_NAMESPACE_SEPARATOR "cas"
#define UIMA_CAS_PFX UIMA_CAS_NAMESPACE UIMA_NAMESPACE_SEPARATOR
#define UIMA_TCAS_NAMESPACE "uima" UIMA_NAMESPACE_SEPARATOR "tcas"
#define UIMA_TCAS_PFX UIMA_TCAS_NAMESPACE UIMA_NAMESPACE_SEPARATOR

#define ANNOTATION UIMA_TCAS_PFX "Annotation"
#define DOCUMENTANNOTATION UIMA_TCAS_PFX "DocumentAnnotation"
#define SOFA "sofa"
#define BEGIN "begin"
#define END "end"
#define LANGUAGE "language"
using namespace std;
namespace uima {
  icu::UnicodeString const CAS::ustrCREATOR_ID_CAS(lowlevel::TypeSystem::ustrCREATOR_ID_SYSTEM);

  char const * CAS::NAME_SPACE_UIMA_CAS = UIMA_CAS_NAMESPACE;

  char const * CAS::TYPE_NAME_TOP              = UIMA_CAS_PFX "TOP";
  char const * CAS::TYPE_NAME_INTEGER          = UIMA_CAS_PFX "Integer";
  char const * CAS::TYPE_NAME_STRING           = UIMA_CAS_PFX "String";
  char const * CAS::TYPE_NAME_FLOAT            = UIMA_CAS_PFX "Float";
  char const * CAS::TYPE_NAME_LIST_BASE        = UIMA_CAS_PFX "ListBase";
  char const * CAS::TYPE_NAME_FS_LIST           = UIMA_CAS_PFX "FSList";
  char const * CAS::TYPE_NAME_EMPTY_FS_LIST           = UIMA_CAS_PFX "EmptyFSList";
  char const * CAS::TYPE_NAME_NON_EMPTY_FS_LIST          = UIMA_CAS_PFX "NonEmptyFSList";
  char const * CAS::TYPE_NAME_FLOAT_LIST        = UIMA_CAS_PFX "FloatList";
  char const * CAS::TYPE_NAME_NON_EMPTY_FLOAT_LIST     = UIMA_CAS_PFX "NonEmptyFloatList";
  char const * CAS::TYPE_NAME_EMPTY_FLOAT_LIST      = UIMA_CAS_PFX "EmptyFloatList";
  char const * CAS::TYPE_NAME_INTEGER_LIST          = UIMA_CAS_PFX "IntegerList";
  char const * CAS::TYPE_NAME_NON_EMPTY_INTEGER_LIST       = UIMA_CAS_PFX "NonEmptyIntegerList";
  char const * CAS::TYPE_NAME_EMPTY_INTEGER_LIST        = UIMA_CAS_PFX "EmptyIntegerList";
  char const * CAS::TYPE_NAME_STRING_LIST       = UIMA_CAS_PFX "StringList";
  char const * CAS::TYPE_NAME_NON_EMPTY_STRING_LIST    = UIMA_CAS_PFX "NonEmptyStringList";
  char const * CAS::TYPE_NAME_EMPTY_STRING_LIST     = UIMA_CAS_PFX "EmptyStringList";
  char const * CAS::TYPE_NAME_ARRAY_BASE       = UIMA_CAS_PFX "ArrayBase";
  char const * CAS::TYPE_NAME_FS_ARRAY          = UIMA_CAS_PFX "FSArray";
  char const * CAS::TYPE_NAME_FLOAT_ARRAY       = UIMA_CAS_PFX "FloatArray";
  char const * CAS::TYPE_NAME_INTEGER_ARRAY         = UIMA_CAS_PFX "IntegerArray";
  char const * CAS::TYPE_NAME_STRING_ARRAY      = UIMA_CAS_PFX "StringArray";
  char const * CAS::TYPE_NAME_SOFA              = UIMA_CAS_PFX "Sofa";
  char const * CAS::TYPE_NAME_LOCALSOFA         = UIMA_CAS_PFX "Sofa";
  char const * CAS::TYPE_NAME_REMOTESOFA        = UIMA_CAS_PFX "Sofa";

  char const * CAS::FEATURE_BASE_NAME_HEAD          =  "head";
  char const * CAS::FEATURE_BASE_NAME_TAIL          =  "tail";
  char const * CAS::FEATURE_FULL_NAME_FS_LIST_TAIL  =  UIMA_CAS_PFX "NonEmptyFSList" UIMA_TYPE_FEATURE_SEPARATOR "tail";
  char const * CAS::FEATURE_FULL_NAME_FS_LIST_HEAD  =  UIMA_CAS_PFX "NonEmptyFSList" UIMA_TYPE_FEATURE_SEPARATOR "head";
  char const * CAS::FEATURE_BASE_NAME_SOFANUM       = "sofaNum";
  char const * CAS::FEATURE_BASE_NAME_SOFAID        = "sofaID";
  char const * CAS::FEATURE_BASE_NAME_SOFAMIME      = "mimeType";
  char const * CAS::FEATURE_BASE_NAME_SOFAURI       = "sofaURI";
  char const * CAS::FEATURE_BASE_NAME_SOFASTRING    = "sofaString";
  char const * CAS::FEATURE_BASE_NAME_SOFAARRAY     = "sofaArray";

  char const * CAS::TYPE_NAME_BOOLEAN          = UIMA_CAS_PFX "Boolean";
  char const * CAS::TYPE_NAME_BYTE          = UIMA_CAS_PFX "Byte";
  char const * CAS::TYPE_NAME_SHORT         = UIMA_CAS_PFX "Short";
  char const * CAS::TYPE_NAME_LONG          = UIMA_CAS_PFX "Long";
  char const * CAS::TYPE_NAME_DOUBLE          = UIMA_CAS_PFX "Double";

  char const * CAS::TYPE_NAME_BOOLEAN_ARRAY          = UIMA_CAS_PFX "BooleanArray";
  char const * CAS::TYPE_NAME_BYTE_ARRAY          = UIMA_CAS_PFX "ByteArray";
  char const * CAS::TYPE_NAME_SHORT_ARRAY         = UIMA_CAS_PFX "ShortArray";
  char const * CAS::TYPE_NAME_LONG_ARRAY          = UIMA_CAS_PFX "LongArray";
  char const * CAS::TYPE_NAME_DOUBLE_ARRAY          = UIMA_CAS_PFX "DoubleArray";

  char const * CAS::FEATURE_FULL_NAME_SOFANUM       = UIMA_CAS_PFX "Sofa" UIMA_TYPE_FEATURE_SEPARATOR "sofaNum";
  char const * CAS::FEATURE_FULL_NAME_SOFAID        = UIMA_CAS_PFX "Sofa" UIMA_TYPE_FEATURE_SEPARATOR "sofaID";
  char const * CAS::FEATURE_FULL_NAME_SOFAMIME      = UIMA_CAS_PFX "Sofa" UIMA_TYPE_FEATURE_SEPARATOR "mimeType";
  char const * CAS::FEATURE_FULL_NAME_SOFAURI       = UIMA_CAS_PFX "RemoteSofa" UIMA_TYPE_FEATURE_SEPARATOR "sofaURI";
  char const * CAS::FEATURE_FULL_NAME_SOFASTRING    = UIMA_CAS_PFX "LocalSofa" UIMA_TYPE_FEATURE_SEPARATOR "sofaString";
  char const * CAS::FEATURE_FULL_NAME_SOFAARRAY     = UIMA_CAS_PFX "LocalSofa" UIMA_TYPE_FEATURE_SEPARATOR "sofaArray";

  char const * CAS::INDEXID_SOFA              = "SofaIndex";
  char const * CAS::NAME_DEFAULT_TEXT_SOFA    = "_InitialView";
  char const * CAS::NAME_DEFAULT_SOFA         = "_InitialView";

  char const * CAS::TYPE_NAME_ANNOTATION_BASE       = UIMA_CAS_PFX "AnnotationBase";
  char const * CAS::TYPE_NAME_ANNOTATION            = ANNOTATION;
  char const * CAS::TYPE_NAME_DOCUMENT_ANNOTATION = DOCUMENTANNOTATION;
  char const * CAS::FEATURE_BASE_NAME_SOFA       = SOFA;
  char const * CAS::FEATURE_FULL_NAME_SOFA       = SOFA UIMA_TYPE_FEATURE_SEPARATOR SOFA;
  char const * CAS::FEATURE_BASE_NAME_BEGIN      = BEGIN;
  char const * CAS::FEATURE_FULL_NAME_BEGIN      = ANNOTATION UIMA_TYPE_FEATURE_SEPARATOR BEGIN;
  char const * CAS::FEATURE_BASE_NAME_END        = END;
  char const * CAS::FEATURE_FULL_NAME_END        = ANNOTATION UIMA_TYPE_FEATURE_SEPARATOR END;
  char const * CAS::FEATURE_BASE_NAME_LANGUAGE = LANGUAGE;
  char const * CAS::FEATURE_FULL_NAME_LANGUAGE = DOCUMENTANNOTATION UIMA_TYPE_FEATURE_SEPARATOR LANGUAGE;
  char const * CAS::INDEXID_ANNOTATION = "AnnotationIndex";
}
/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */

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

/*
 * Most of the methods in here use the lowlevel API directly.
*/

namespace uima {
  UIMA_EXC_CLASSIMPLEMENT( CouldNotCreateFSOfFinalTypeException, CASException );
  UIMA_EXC_CLASSIMPLEMENT( DuplicateSofaNameException, CASException );
  UIMA_EXC_CLASSIMPLEMENT( InvalidBaseCasMethod, CASException );

  CAS::CAS(uima::internal::CASDefinition & casDefs,
           size_t uiFSHeapPageSize,
           size_t uiStringHeapPageSize,
           size_t uiStringRefHeapPageSize)
      : iv_casDefinition( & casDefs ),
      iv_typeSystem(NULL),
      iv_heap(NULL),
      initialSofaCreated(false),
      iv_sofaNum(0),
      iv_sofaCount(0),
      iv_initialView(NULL),
      iv_indexRepository(NULL),
      iv_filterBuilder(NULL),
      iv_componentInfo(NULL),
      iv_utDocumentType(uima::lowlevel::TypeSystem::INVALID_TYPE),
      iv_utDocumentLangAsIntFeat(uima::lowlevel::TypeSystem::INVALID_FEATURE),
      iv_utDocumentLangAsStrFeat(uima::lowlevel::TypeSystem::INVALID_FEATURE),
      iv_cpDocument(NULL),
      iv_uiDocumentLength(0),
      iv_copyOfDocument(NULL),
      iv_tyDocumentAnnotation(uima::lowlevel::FSHeap::INVALID_FS) {
    // leave those as assertions, don't throw exceptions
    assert( casDefs.getTypeSystem().isCommitted() );
    assert( casDefs.getIndexDefinition().isCommitted() );

    iv_typeSystem = &casDefs.getTypeSystem();
    iv_heap = new uima::lowlevel::FSHeap(casDefs.getTypeSystem(),
                                         uiFSHeapPageSize,
                                         uiStringHeapPageSize,
                                         uiStringRefHeapPageSize);
    assert( EXISTS(iv_heap) );

    iv_indexRepository = new uima::lowlevel::IndexRepository(casDefs.getIndexDefinition(),
                         *iv_heap, *this);
    assert( EXISTS( iv_indexRepository) );

    iv_filterBuilder = new uima::FSFilterBuilder();
    assert( EXISTS(iv_filterBuilder) );
    isbaseCas = true;
    iv_baseCas = this;
    isDeletingViews = false;
    bOwnsCASDefinition=false;
  }

  // Constructor used for views
  CAS::CAS(CAS* inCas, SofaFS inSofa):
      iv_sofaNum(0),
      iv_sofaCount(0),
      iv_cpDocument(NULL),
      iv_uiDocumentLength(0),
      iv_copyOfDocument(NULL),
      iv_tyDocumentAnnotation(uima::lowlevel::FSHeap::INVALID_FS) {
    iv_casDefinition = inCas->iv_casDefinition;
    iv_typeSystem = inCas->iv_typeSystem;
    iv_heap = inCas->iv_heap;
    iv_componentInfo = inCas->iv_componentInfo;
    iv_utDocumentLangAsIntFeat = uima::lowlevel::TypeSystem::INVALID_FEATURE;
    iv_utDocumentLangAsStrFeat = uima::lowlevel::TypeSystem::INVALID_FEATURE;
    refreshCachedTypes();

    if (inSofa.isValid()) {
      lowlevel::TyFS tySofa = internal::FSPromoter::demoteFS(inSofa);
      iv_sofaNum = iv_heap->getIntValue(tySofa, internal::gs_tySofaNumFeature);
      UnicodeStringRef pDoc = iv_heap->getStringValue(tySofa, internal::gs_tySofaStringFeature);
      copyDocumentString(pDoc);
    } else {
      iv_sofaNum = 1;
    }

    // each view has unique indexRepository
    iv_indexRepository = new uima::lowlevel::IndexRepository(iv_casDefinition->getIndexDefinition(),
                         *iv_heap, *this);
    assert( EXISTS(iv_indexRepository) );
    if ((int)inCas->iv_sofa2indexMap.size() < iv_sofaNum+1) {
      inCas->iv_sofa2indexMap.resize(iv_sofaNum + 1);
    }
    // map to a Sofa's IR. This map is deleted when the CAS definition may change.
    inCas->iv_sofa2indexMap[iv_sofaNum] = iv_indexRepository;
    iv_filterBuilder = inCas->iv_filterBuilder;
    isbaseCas = false;
    iv_baseCas = inCas;
    bOwnsCASDefinition = false;
    isDeletingViews = false;
  }

  CAS::CAS(uima::internal::CASDefinition & casDefs,
           bool ownsCasDef,
           size_t uiFSHeapPageSize,
           size_t uiStringHeapPageSize,
           size_t uiStringRefHeapPageSize)
      : iv_casDefinition( & casDefs ),
      iv_typeSystem(NULL),
      iv_heap(NULL),
      iv_sofaNum(0),
      iv_sofaCount(0),
      initialSofaCreated(false),
      iv_initialView(NULL),
      iv_indexRepository(NULL),
      iv_filterBuilder(NULL),
      iv_componentInfo(NULL),
      iv_utDocumentType(uima::lowlevel::TypeSystem::INVALID_TYPE),
      iv_utDocumentLangAsIntFeat(uima::lowlevel::TypeSystem::INVALID_FEATURE),
      iv_utDocumentLangAsStrFeat(uima::lowlevel::TypeSystem::INVALID_FEATURE),
      iv_cpDocument(NULL),
      iv_uiDocumentLength(0),
      iv_copyOfDocument(NULL),
      iv_tyDocumentAnnotation(uima::lowlevel::FSHeap::INVALID_FS) {
    // leave those as assertions, don't throw exceptions
    assert( casDefs.getTypeSystem().isCommitted() );
    assert( casDefs.getIndexDefinition().isCommitted() );

    iv_typeSystem = &casDefs.getTypeSystem();
    iv_heap = new uima::lowlevel::FSHeap(casDefs.getTypeSystem(),
                                         uiFSHeapPageSize,
                                         uiStringHeapPageSize,
                                         uiStringRefHeapPageSize);
    assert( EXISTS(iv_heap) );

    iv_indexRepository = new uima::lowlevel::IndexRepository(casDefs.getIndexDefinition(),
                         *iv_heap, *this);
    assert( EXISTS( iv_indexRepository) );

    iv_filterBuilder = new uima::FSFilterBuilder();
    assert( EXISTS(iv_filterBuilder) );
    isbaseCas = true;
    iv_baseCas = this;
    bOwnsCASDefinition=ownsCasDef;
    isDeletingViews = false;
  }

  CAS::~CAS() {
    
    //always delete index repository
    if (this->iv_indexRepository != NULL) {
      delete iv_indexRepository;
      iv_indexRepository = NULL;
		}
    if (this->iv_cpDocument != NULL) {
      delete[] this->iv_cpDocument;
      this->iv_cpDocument = NULL;
    }
    //initial call to delete object
    if (this->isbaseCas) {
      this->iv_baseCas->isDeletingViews = true;
      
      if (this->iv_baseCas->iv_heap != NULL) {
        delete this->iv_baseCas->iv_heap;
        this->iv_baseCas->iv_heap = NULL;
      }
      if (iv_baseCas->iv_filterBuilder != NULL) {
        delete iv_baseCas->iv_filterBuilder;
        iv_baseCas->iv_filterBuilder = NULL;
      }
      if (this->iv_baseCas->bOwnsCASDefinition ) {
		    if (this->iv_baseCas->iv_casDefinition != NULL) { 
               delete this->iv_baseCas->iv_casDefinition;
			    this->iv_baseCas->iv_casDefinition = NULL;
		    }
      }
      map<int, CAS*>::iterator mIter;
      map<int,CAS*> mapcopy(this->iv_baseCas->iv_sofa2tcasMap);
      for ( mIter = mapcopy.begin( );
            mIter != mapcopy.end( ); mIter++ ) {
        CAS* tcas = mIter->second;
        if ( tcas != NULL) {
          delete tcas;
        }
      //this->iv_baseCas->iv_sofa2tcasMap.clear( );
      //this->iv_baseCas->iv_sofa2indexMap.clear();
      } 
    } else {
      if (!this->iv_baseCas->isDeletingViews) {
        dropView(this->getSofaNum());
        this->iv_baseCas->isDeletingViews=true;
        delete this->iv_baseCas;
      }
    }
  }


  FSFilterBuilder const & CAS::getFSFilterBuilder() const {
    assert( EXISTS(iv_filterBuilder) );
    return *iv_filterBuilder;
  }


  TypeSystem const & CAS::getTypeSystem(void) const {
    assert( EXISTS(iv_heap) );
    return *iv_typeSystem;
  }

  uima::lowlevel::FSHeap * CAS::getHeap() {
    assert( EXISTS(iv_heap) );
    return iv_heap;
  }



  TyErrorId CAS::reset() {
    assert( EXISTS(iv_heap) );
    assert( EXISTS(iv_indexRepository) );
    if (!isbaseCas) {
      iv_baseCas->reset();
    } else {
      // reset all views for this CAS
      map<int, CAS*>::iterator mIter;
      for ( mIter = iv_sofa2tcasMap.begin( ); mIter != iv_sofa2tcasMap.end( ); mIter++ ) {
        CAS* tcas = mIter->second;
        tcas->iv_cpDocument = NULL;
        if (NULL != tcas->iv_copyOfDocument)
          delete [] tcas->iv_copyOfDocument;
        tcas->iv_copyOfDocument = NULL;
        tcas->iv_uiDocumentLength = 0;
        tcas->iv_indexRepository->reset();
        tcas->iv_tyDocumentAnnotation = uima::lowlevel::FSHeap::INVALID_FS;
      }
      iv_heap->reset();
      iv_baseCas->initialSofaCreated = false;
      iv_sofaCount = 1; // for initial view
      iv_indexRepository->reset();
    }
    return UIMA_ERR_NONE;
  }



  FeatureStructure CAS::createFS(Type const & crType) {
    if (!crType.isValid()) {
      UIMA_EXC_THROW_NEW(InvalidFSTypeObjectException,
                         UIMA_ERR_INVALID_FSTYPE_OBJECT,
                         UIMA_MSG_ID_EXC_INVALID_FSTYPE_OBJECT,
                         ErrorMessage(UIMA_MSG_ID_EXCON_CREATING_FS),
                         ErrorInfo::recoverable
                        );
    }
    uima::lowlevel::TyFSType tyType = internal::FSPromoter::demoteType(crType);
    switch (tyType) {
    case uima::internal::gs_tyIntegerType:
    case uima::internal::gs_tyFloatType:
    case uima::internal::gs_tyStringType:
    case uima::internal::gs_tyBooleanType:
    case uima::internal::gs_tyByteType:
    case uima::internal::gs_tyShortType:
    case uima::internal::gs_tyLongType:
    case uima::internal::gs_tyDoubleType: {
        ErrorMessage errMessage(UIMA_MSG_ID_EXC_COULD_NOT_CREATE_FS_FINAL_TYPE );
        errMessage.addParam( crType.getName() );
        UIMA_EXC_THROW_NEW(CouldNotCreateFSOfFinalTypeException,
                           UIMA_ERR_COULD_NOT_CREATE_FS_OF_FINAL_TYPE,
                           errMessage,
                           UIMA_MSG_ID_EXCON_CREATING_FS,
                           ErrorInfo::recoverable
                          );
      }
    default:
      ;
    }

    // if new FS is annotation type, set the sofa feature
    lowlevel::TyFS temp= iv_heap->createFS(tyType);
    if (iv_heap->getTypeSystem().subsumes(internal::gs_tyAnnotationType, tyType)) {
      iv_heap->setFSValue(temp, internal::gs_tySofaRefFeature,
                          internal::FSPromoter::demoteFS(getSofa()));
    }
    return internal::FSPromoter::promoteFS(temp, *this );
  }

  int CAS::addString(UChar const * cpBuffer, size_t uiLength) {
    UnicodeStringRef uls( cpBuffer, uiLength );
    int shoff = iv_heap->addString(uls);
    return iv_heap->getStringAsFS(shoff);
  }


  int CAS::addString(icu::UnicodeString const & crString) {
    UnicodeStringRef uls( crString.getBuffer(), crString.length() );
    int shoff = iv_heap->addString(uls);
    return iv_heap->getStringAsFS(shoff);
  }

  int CAS::addString(const UnicodeStringRef & uls) {
    int shoff = iv_heap->addString(uls);
    return iv_heap->getStringAsFS(shoff);
  }

  ArrayFS CAS::createArrayFS(size_t uiLength) {
    return ArrayFS::createArrayFS(*this, uiLength);
  }
  FloatArrayFS CAS::createFloatArrayFS(size_t uiLength) {
    return FloatArrayFS::createArrayFS(*this, uiLength);
  }
  IntArrayFS CAS::createIntArrayFS(size_t uiLength) {
    return IntArrayFS::createArrayFS(*this, uiLength);
  }
  StringArrayFS CAS::createStringArrayFS(size_t uiLength) {
    return StringArrayFS::createArrayFS(*this, uiLength);
  }

  BooleanArrayFS CAS::createBooleanArrayFS(size_t uiLength) {
    return BooleanArrayFS::createArrayFS(*this, uiLength);
  }
  ByteArrayFS CAS::createByteArrayFS(size_t uiLength) {
    return ByteArrayFS::createArrayFS(*this, uiLength);
  }
  ShortArrayFS CAS::createShortArrayFS(size_t uiLength) {
    return ShortArrayFS::createArrayFS(*this, uiLength);
  }

  LongArrayFS CAS::createLongArrayFS(size_t uiLength) {
    return LongArrayFS::createArrayFS(*this, uiLength);
  }
  DoubleArrayFS CAS::createDoubleArrayFS(size_t uiLength) {
    return DoubleArrayFS::createArrayFS(*this, uiLength);
  }


  ListFS CAS::createListFS( ) {
    return ListFS::createListFS(*this);
  }
  FloatListFS CAS::createFloatListFS( ) {
    return FloatListFS::createListFS(*this);
  }
  IntListFS CAS::createIntListFS( ) {
    return IntListFS::createListFS(*this);
  }
  StringListFS CAS::createStringListFS( ) {
    return StringListFS::createListFS(*this);
  }

  /////////////////////////////////////////////////////////////
  // index

  FSIndexRepository & CAS::getIndexRepository( void ) {
    if (isbaseCas) {
      invalidBaseCasMethod();
    }
    assert( EXISTS(iv_indexRepository) );
    return *iv_indexRepository;
  }

  FSIndexRepository const & CAS::getIndexRepository( void ) const {
    if (isbaseCas) {
      ErrorMessage errMessage(UIMA_MSG_ID_EXC_INVALID_BASE_CAS_METHOD);
      UIMA_EXC_THROW_NEW(InvalidBaseCasMethod,
                         UIMA_ERR_INVALID_BASE_CAS_METHOD,
                         errMessage,
                         UIMA_MSG_ID_NO_MESSAGE_AVAILABLE,
                         ErrorInfo::unrecoverable
                        );
    }
    assert( EXISTS(iv_indexRepository) );
    return *iv_indexRepository;
  }

  lowlevel::IndexRepository  & CAS::getLowlevelIndexRepository( void ) const {
    if (isbaseCas) {
      ErrorMessage errMessage(UIMA_MSG_ID_EXC_INVALID_BASE_CAS_METHOD);
      UIMA_EXC_THROW_NEW(InvalidBaseCasMethod,
                         UIMA_ERR_INVALID_BASE_CAS_METHOD,
                         errMessage,
                         UIMA_MSG_ID_NO_MESSAGE_AVAILABLE,
                         ErrorInfo::unrecoverable
                        );
    }
    assert( EXISTS(iv_indexRepository) );
    return *iv_indexRepository;
  }

  FSIterator CAS::iterator() {
    lowlevel::IndexIterator* it = new uima::lowlevel::DefaultFSIterator(*iv_heap);
    return FSIterator(it, this );
  }

  /////////////////////////////////////////////////////////////////////////////
  // Get or Create CAS view for aSofa

  CAS* CAS::getView(SofaFS aSofa) {
    CAS* aTcas;
    int sofaNum = iv_heap->getIntValue(internal::FSPromoter::demoteFS(aSofa), internal::gs_tySofaNumFeature);
    map<int, CAS*>::iterator cit = iv_baseCas->iv_sofa2tcasMap.find(sofaNum);
    if (cit == iv_baseCas->iv_sofa2tcasMap.end()) {
      if (sofaNum > iv_baseCas->iv_sofaCount) {
        // This sofa must have just been created during binary deserialization
        assert(iv_baseCas->iv_sofaCount+1 == sofaNum);
        iv_baseCas->iv_sofaCount = sofaNum;
        if ( iv_sofaCount+1 > (int) iv_baseCas->iv_sofa2indexMap.size()) {
          iv_baseCas->iv_sofa2indexMap.resize(sofaNum + 1);
          iv_baseCas->iv_sofa2indexMap[sofaNum] = NULL;
        }
      }
      aTcas = (CAS*) new uima::internal::CASImpl(this->iv_baseCas, aSofa);
      assert ( EXISTS(aTcas) );
      pair<int, CAS*> p1(sofaNum, aTcas);
      iv_baseCas->iv_sofa2tcasMap.insert(p1);
      return aTcas;
    }
//    if (createDocAnn) {
//    (*cit).second->setDocumentAnnotationFromSofa( );
//    }
    if (sofaNum > iv_baseCas->iv_sofaCount) {
      // This sofa must have just been created during xcas deserialization
      assert(iv_baseCas->iv_sofaCount+1 == sofaNum);
      iv_baseCas->iv_sofaCount = sofaNum;
      if ( iv_sofaCount+1 > (int) iv_baseCas->iv_sofa2indexMap.size()) {
        iv_baseCas->iv_sofa2indexMap.resize(sofaNum + 1);
        iv_baseCas->iv_sofa2indexMap[sofaNum] = NULL;
      }
    }
    return (*cit).second;
  }


  // Get the CAS View from sofaNum value
  CAS* CAS::getViewBySofaNum(int sofaNum) {
    CAS* aTcas;
    map<int, CAS*>::iterator cit = iv_baseCas->iv_sofa2tcasMap.find(sofaNum);
    if (cit == iv_baseCas->iv_sofa2tcasMap.end()) {
      aTcas = (CAS*) new uima::internal::CASImpl(this->iv_baseCas, getSofa(sofaNum));
      assert ( EXISTS(aTcas) );
      pair<int, CAS*> p1(sofaNum, aTcas);
      iv_baseCas->iv_sofa2tcasMap.insert(p1);
      return aTcas;
    }
    return (*cit).second;
  }

  CAS* CAS::getView(const icu::UnicodeString & localViewName) {
    SofaID* sid;
    bool deleteSofaID = false;
    if (0 != iv_baseCas->iv_componentInfo) {
      sid = const_cast<SofaID*> (&iv_baseCas->iv_componentInfo->mapToSofaID(localViewName));
    } else {
      sid = new SofaID();
      deleteSofaID = true;
      sid->setSofaId(localViewName);
    }

    // if this resolves to the Initial View, return view(1)...
    // ... as the Sofa for this view may not exist yet
    if (0==sid->getSofaId().compare(CAS::NAME_DEFAULT_SOFA)) {
      if (deleteSofaID) {
        delete sid;
      }
      return getInitialView();
    }

    SofaFS as = getSofa(sid->getSofaId());
    if (!as.isValid()) {
      ErrorMessage errMessage(UIMA_MSG_ID_EXC_SOFA_NAME_NOT_FOUND);
      errMessage.addParam( sid->getSofaId());
      UIMA_EXC_THROW_NEW(DuplicateSofaNameException,
                         UIMA_ERR_RESOURCE_NOT_FOUND,
                         errMessage,
                         UIMA_MSG_ID_NO_MESSAGE_AVAILABLE,
                         ErrorInfo::unrecoverable
                        );
    }
    if (deleteSofaID) {
      delete sid;
    }
    return getView(as);
  }

  CAS* CAS::createView(icu::UnicodeString const & localViewName) {
    // map the input name
    SofaID* sid;
    bool deleteSofaID = false;
    if (0 != iv_baseCas->iv_componentInfo) {
      sid = const_cast<SofaID*> (&iv_baseCas->iv_componentInfo->mapToSofaID(localViewName));
    } else {
      sid = new SofaID();
      sid->setSofaId(localViewName);
      deleteSofaID = true;
    }
    // test if this is the reserved name
    if ( 0 == sid->getSofaId().compare(icu::UnicodeString(CAS::NAME_DEFAULT_SOFA)) ) {
      ErrorMessage errMessage(UIMA_MSG_ID_EXC_SOFA_NAME_ALREADY_EXISTS);
      errMessage.addParam( localViewName );
      UIMA_EXC_THROW_NEW(DuplicateSofaNameException,
                         UIMA_ERR_DUPLICATE_EXISTS,
                         errMessage,
                         UIMA_MSG_ID_EXCON_CREATING_FS,
                         ErrorInfo::unrecoverable
                        );
    }

    SofaFS newSofa = createSofa(sid->getSofaId(), UnicodeStringRef());
    if (deleteSofaID) {
      delete sid;
    }
    return getView(newSofa);
  }

  UnicodeStringRef CAS::getViewName() {
    SofaFS thisSofa = getSofa();
    if (thisSofa.isValid()) {
      return getSofa().getSofaID();
    }
    return UnicodeStringRef();
  }

  void CAS::invalidBaseCasMethod() {
    ErrorMessage errMessage(UIMA_MSG_ID_EXC_INVALID_BASE_CAS_METHOD);
    UIMA_EXC_THROW_NEW(InvalidBaseCasMethod,
                       UIMA_ERR_INVALID_BASE_CAS_METHOD,
                       errMessage,
                       UIMA_MSG_ID_NO_MESSAGE_AVAILABLE,
                       ErrorInfo::unrecoverable
                      );
  }

  // deprecated version
  void CAS::setDocumentText(UChar const * cpDocument, size_t uiLength, bool bCopyToCAS ) {
    if (cpDocument == NULL) {
      assert( uiLength == 0 );
    }
    if (bCopyToCAS && ( cpDocument != NULL ) ) {
      copyDocumentString(UnicodeStringRef(cpDocument, uiLength));
    } else {
      iv_cpDocument = cpDocument;
      iv_uiDocumentLength = uiLength;
    }
    SofaFS thisSofa = getSofa();
    if (!thisSofa.isValid()) {
      thisSofa = createInitialSofa(UnicodeStringRef("text"));
    }
    thisSofa.setLocalSofaData(UnicodeStringRef(iv_cpDocument, iv_uiDocumentLength));
  }

  void CAS::setDocumentText(UnicodeStringRef const text) {
    if (isbaseCas) {
      invalidBaseCasMethod();
    }
    SofaFS thisSofa = getSofa();
    if (!thisSofa.isValid()) {
      thisSofa = createInitialSofa(UnicodeStringRef("text"));
    }
    copyDocumentString(text);
    thisSofa.setLocalSofaData(text);
  }

  // internal use only
  void CAS::setDocTextFromDeserializtion(UnicodeStringRef text) {
    copyDocumentString(text);
    SofaFS thisSofa = getSofa();
    assert( thisSofa.isValid() );
    thisSofa.setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaStringFeature,
                            getHeap()->getTypeSystem()), text);
  }

  void CAS::setSofaDataString(UnicodeStringRef const text, icu::UnicodeString const & mimetype) {
    if (isbaseCas) {
      invalidBaseCasMethod();
    }
    SofaFS thisSofa = getSofa();
    if (!thisSofa.isValid()) {
      thisSofa = createInitialSofa(mimetype);
    }
    setDocumentText(text);
  }

  UnicodeStringRef CAS::getDocumentText()const {
    if (isbaseCas) {
      return UnicodeStringRef();
    }
    return UnicodeStringRef(iv_cpDocument, iv_uiDocumentLength);
  }

  void CAS::createDocumentAnnotation() {
    if (!isbaseCas) {
      assert( EXISTS(iv_heap) );
      if (iv_tyDocumentAnnotation == uima::lowlevel::FSHeap::INVALID_FS) {
        iv_tyDocumentAnnotation = iv_heap->createFS( iv_utDocumentType );
        uima::lowlevel::TypeSystem const & ts = iv_heap->getTypeSystem();
        Language lang;
        int iLangID = (int) lang.asNumber();
        uima::lowlevel::TyFSFeature langFeat = ts.getFeatureByFullName(CAS::FEATURE_FULL_NAME_LANGUAGE);
        assert( ts.isValidFeature(langFeat) );
        int ref = iv_heap->addString( lang.asUnicodeString() );
        iv_heap->setStringValue( iv_tyDocumentAnnotation, langFeat, ref);
        iv_heap->setFSValue(iv_tyDocumentAnnotation, internal::gs_tySofaRefFeature,
                            internal::FSPromoter::demoteFS(getSofa()));
      }
      assert( iv_heap->isValid( iv_tyDocumentAnnotation ) );
      assert( iv_heap->resides( iv_tyDocumentAnnotation ) );
    }
  }

  DocumentFS const CAS::getDocumentAnnotation() const {
    if (isbaseCas || iv_tyDocumentAnnotation == uima::lowlevel::FSHeap::INVALID_FS ) {
      return DocumentFS();
    }
    return(DocumentFS)uima::internal::FSPromoter::promoteFS(iv_tyDocumentAnnotation, *this);
  }

  DocumentFS CAS::getDocumentAnnotation() {
    if (isbaseCas) {
      assertWithMsg(false, "no DocumentAnnotation in Base CAS!");
      return DocumentFS();
    }
    if ( iv_tyDocumentAnnotation == uima::lowlevel::FSHeap::INVALID_FS ) {
      createDocumentAnnotation();
    }
    return(DocumentFS)uima::internal::FSPromoter::promoteFS(iv_tyDocumentAnnotation, *this);
  }

  AnnotationFS CAS::createAnnotation( Type const & type, size_t uiBegin, size_t uiEnd) {
    if (isbaseCas) {
      assertWithMsg(false, "Cannot create an Annotation in the Base CAS!");
      return AnnotationFS();
    }
    assert(EXISTS(iv_heap));
    assert( getTypeSystem().getType(CAS::TYPE_NAME_ANNOTATION).subsumes(type) );
    if (!type.isValid()) {
      UIMA_EXC_THROW_NEW(InvalidFSTypeObjectException,
                         UIMA_ERR_INVALID_FSTYPE_OBJECT,
                         UIMA_MSG_ID_EXC_INVALID_FSTYPE_OBJECT,
                         ErrorMessage(UIMA_MSG_ID_EXCON_CREATING_FS),
                         ErrorInfo::recoverable );
    }
    lowlevel::TyFS tyAn = iv_heap->createFS(internal::FSPromoter::demoteType(type));
    iv_heap->setFSValue(tyAn, internal::gs_tySofaRefFeature,
                        internal::FSPromoter::demoteFS(this->getSofa()));
    iv_heap->setIntValue(tyAn, internal::gs_tyBeginPosFeature, (int)uiBegin );
    iv_heap->setIntValue(tyAn, internal::gs_tyEndPosFeature, (int)uiEnd );
    return(AnnotationFS)internal::FSPromoter::promoteFS(tyAn, *this);
  }

  ANIndex const CAS::getAnnotationIndex(Type const & crType) const {
    if (isbaseCas) {
      assertWithMsg(false, "Annotation Index does not exist in Base CAS!");
      return ANIndex();
    }
    try {
      return(ANIndex)getIndexRepository().getIndex(CAS::INDEXID_ANNOTATION, crType);
    } catch ( InvalidIndexIDException & ) {
      assertWithMsg(false, "Annotation Index does not exist!");
      return ANIndex();
    } catch ( WrongFSTypeForIndexException & ) {
      assertWithMsg(false, "Annotation Index exists with wrong type!");
      return ANIndex();
    }
  }

  ANIndex CAS::getAnnotationIndex(Type const & crType) {
    if (isbaseCas) {
      assertWithMsg(false, "Annotation Index does not exist in Base CAS!");
      return ANIndex();
    }
    return((CAS const *) this)->getAnnotationIndex(crType);
  }

  ANIndex CAS::getAnnotationIndex() {
    if (isbaseCas) {
      assertWithMsg(false, "Annotation Index does not exist in Base CAS!");
      return ANIndex();
    }
    return getAnnotationIndex(iv_heap->getTypeSystem().getType(CAS::TYPE_NAME_ANNOTATION));
  }

  void CAS::setSofaDataArray(FeatureStructure array, icu::UnicodeString const & mime) {
    if (isbaseCas) {
      invalidBaseCasMethod();
    }
    SofaFS thisSofa = getSofa();
    if (!thisSofa.isValid()) {
      thisSofa = createInitialSofa(mime);
    }
    getSofa().setLocalSofaData(array);
  }

  FeatureStructure CAS::getSofaDataArray() {
    if (isbaseCas) {
      assertWithMsg(false, "no Sofa data in Base CAS!");
      return FeatureStructure();
    }
    return getSofa().getLocalFSData();
  }

  void CAS::setSofaDataURI(icu::UnicodeString const & uri, icu::UnicodeString const & mime) {
    if (isbaseCas) {
      invalidBaseCasMethod();
    }
    if (!getSofa().isValid()) {
      createInitialSofa(mime);
    }
    getSofa().setRemoteSofaURI(uri);
  }

  UnicodeStringRef CAS::getSofaDataURI() {
    if (isbaseCas) {
      assertWithMsg(false, "no Sofa data in Base CAS!");
      return UnicodeStringRef();
    }
    return getSofa().getSofaURI();
  }

  SofaDataStream * CAS::getSofaDataStream() {
    if (isbaseCas) {
      invalidBaseCasMethod();
    }
    return getSofa().getSofaDataStream();
  }



  bool CAS::moveToBeginPosition (ANIterator & itOfType, AnnotationFS const & crFsFromAn) {
    /* Find begin position of annotation crToFS */
    size_t uiBegPosFromAn = crFsFromAn.getIntValue(internal::FSPromoter::promoteFeature(internal::gs_tyBeginPosFeature, iv_heap->getTypeSystem() ));

    /* Iterate to the begin position of our given annotation crToFS */
    bool bPosIsValid;
    size_t uiBegPosOfType;
    itOfType.moveToFirst();
    while (itOfType.get().isValid()) {
      uiBegPosOfType = itOfType.get().getIntValue(internal::FSPromoter::promoteFeature(internal::gs_tyBeginPosFeature, iv_heap->getTypeSystem() ));
      if (uiBegPosOfType == uiBegPosFromAn) {
        return bPosIsValid = true;
      }
      itOfType.moveToNext();
      if (uiBegPosOfType > uiBegPosFromAn)
        return bPosIsValid = false;
    }
    return bPosIsValid = false;
  }

  // Drop View from sofaMap
  void CAS::dropView(int sofaNum) {
    map<int, CAS*>::iterator cit = iv_baseCas->iv_sofa2tcasMap.find(sofaNum);
    if (cit != iv_baseCas->iv_sofa2tcasMap.end()) {
      iv_baseCas->iv_sofa2tcasMap.erase(cit);
    }
  }

  /////////////////////////////////////////////////////////////////////////////
  // Sofa utilities
  /*
  public FSIndexRepositoryImpl getSofaIndexRepository(SofaFS aSofa) {
    return (FSIndexRepositoryImpl) sofa2indexMap.get(aSofa);
  }

  public void setSofaIndexRepository(SofaFS aSofa, FSIndexRepositoryImpl index) {
    sofa2indexMap.put(aSofa, index);
  }
  */

  SofaFS CAS::createLocalSofa(const char* sofaName, const char* mimeType) {
    icu::UnicodeString const uName(sofaName, strlen(sofaName), "utf8");
    icu::UnicodeString const uMime(mimeType, strlen(mimeType), "utf8");
    return createSofa(uName, uMime);
  }

  SofaFS CAS::createSofa(const SofaID & sofaName, const char* mimeType) {
    icu::UnicodeString const uMime(mimeType, strlen(mimeType), "utf8");
    return createSofa(sofaName.getSofaId(), uMime);
  }

  SofaFS CAS::createSofa(UnicodeStringRef const sofaName, UnicodeStringRef const mimeType) {
    assert(EXISTS(iv_heap));
    if (iv_baseCas->getSofa(sofaName).isValid()) {
      ErrorMessage errMessage(UIMA_MSG_ID_EXC_SOFA_NAME_ALREADY_EXISTS);
      errMessage.addParam( sofaName );
      UIMA_EXC_THROW_NEW(DuplicateSofaNameException,
                         UIMA_ERR_DUPLICATE_EXISTS,
                         errMessage,
                         UIMA_MSG_ID_EXCON_CREATING_FS,
                         ErrorInfo::unrecoverable
                        );
    }
    Type sofaT = getTypeSystem().getType(CAS::TYPE_NAME_SOFA);
    lowlevel::TyFS tySofa = iv_heap->createFS(internal::FSPromoter::demoteType(sofaT));
    SofaFS newSofa = (SofaFS)internal::FSPromoter::promoteFS(tySofa, *this->iv_baseCas);
    bumpSofaCount();
    newSofa.setIntValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaNumFeature, iv_heap->getTypeSystem()), iv_baseCas->iv_sofaCount);
    newSofa.setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaIDFeature, iv_heap->getTypeSystem()), sofaName);
    if (mimeType.length() > 0) {
      newSofa.setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaMimeFeature, iv_heap->getTypeSystem()), mimeType);
    }
    iv_baseCas->iv_indexRepository->add(tySofa);
    return newSofa;
  }

  SofaFS CAS::getSofa() {
    if (iv_sofaNum > 0) {
      return getSofa(iv_sofaNum);
    }
    return SofaFS(FeatureStructure());
  }

  SofaFS CAS::getSofa(const SofaID & sofaName) {
    return getSofa(sofaName.getSofaId());
  }

  SofaFS CAS::getSofa(char* sofaName) {
    icu::UnicodeString const uName(sofaName, strlen(sofaName), "utf8");
    return getSofa(uName);
  }

  SofaFS CAS::getSofa(UnicodeStringRef sofaName) {
    FSIndex fsIdx = getBaseIndexRepository().getIndex(CAS::INDEXID_SOFA);
    FSIterator fsIt = fsIdx.iterator();
    while (fsIt.isValid()) {
      Feature idFeat =
        getTypeSystem().getFeatureByFullName(CAS::FEATURE_FULL_NAME_SOFAID);
      UnicodeStringRef sofaID = fsIt.get().getStringValue(idFeat);
      if (0 == sofaName.compare(sofaID)) {
        return (SofaFS) fsIt.get();
      }
      fsIt.moveToNext();
    }
    //HOW TO FAIL HERE? Currently returning an INVALID_FS
    return (SofaFS) FeatureStructure();
  }

  FSIterator CAS::getSofaIterator() {
    FSIndex fsIdx = getBaseIndexRepository().getIndex(CAS::INDEXID_SOFA);
    return fsIdx.iterator();
  }

  SofaFS CAS::getSofa(int sofaNum) {
    FSIndex fsIdx = getBaseIndexRepository().getIndex(CAS::INDEXID_SOFA);
    FSIterator fsIt = fsIdx.iterator();
    while (fsIt.isValid()) {
      Feature numFeat =
        getTypeSystem().getFeatureByFullName(CAS::FEATURE_FULL_NAME_SOFANUM);
      if (sofaNum == fsIt.get().getIntValue(numFeat)) {
        return (SofaFS) fsIt.get();
      }
      fsIt.moveToNext();
    }
    //HOW TO FAIL HERE? Currently returning an INVALID_FS
    return (SofaFS) FeatureStructure();
  }

  uima::lowlevel::IndexRepository * CAS::getIndexRepositoryForSofa(SofaFS sofa) {
    return iv_baseCas->iv_sofa2indexMap[iv_heap->getIntValue(internal::FSPromoter::demoteFS(sofa),
                                        internal::gs_tySofaNumFeature)];
  }

  // Record a new sofaFS and reserve space in the index map if necessary
  void CAS::bumpSofaCount() {
    iv_baseCas->iv_sofaCount++;
    if ( (iv_baseCas->iv_sofaCount+1) > (int)iv_baseCas->iv_sofa2indexMap.size()) {
      // enlarge map and set new entry to NULL
      iv_baseCas->iv_sofa2indexMap.resize(iv_baseCas->iv_sofaCount + 1);
      iv_baseCas->iv_sofa2indexMap[iv_baseCas->iv_sofaCount] = NULL;
    }
  }

  void CAS::registerView(SofaFS aSofa ) {
    lowlevel::TyFS tySofa = internal::FSPromoter::demoteFS(aSofa);
    iv_sofaNum = iv_heap->getIntValue(tySofa, internal::gs_tySofaNumFeature);
  }

  void CAS::updateDocumentAnnotation( ) {
    SofaFS thisSofa = getSofa();
    if (thisSofa.isValid()) {
      lowlevel::TyFS tySofa = internal::FSPromoter::demoteFS(thisSofa);
      UnicodeStringRef pDoc = iv_heap->getStringValue(tySofa, internal::gs_tySofaStringFeature);
      if (pDoc.length() > 0) {
        copyDocumentString(pDoc);
        getDocumentAnnotation(); // create DocumentAnnotation if necessary
        iv_heap->setIntValue( iv_tyDocumentAnnotation, uima::internal::gs_tyEndPosFeature,
                              (int) iv_uiDocumentLength);
        // re-index the annotation
        iv_indexRepository->remove(iv_tyDocumentAnnotation);
        iv_indexRepository->add(iv_tyDocumentAnnotation);
      }
    }
  }

  void CAS::pickupDocumentAnnotation( ) {
    // called from CAS binary deserialization
    ANIndex ai = getAnnotationIndex(iv_heap->getTypeSystem().
                                    getType(CAS::TYPE_NAME_DOCUMENT_ANNOTATION));
    ANIterator ait = ai.iterator();
    // Not valid if a non-text or remote sofa
    if ( ! ait.isValid() ) {
      return;
    }
    iv_tyDocumentAnnotation = internal::FSPromoter::demoteFS(ait.get());
    iv_uiDocumentLength = ait.get().getEndPosition();
    uima::lowlevel::TyFS sofaAddr = iv_heap->getFSValue(iv_tyDocumentAnnotation, internal::gs_tySofaRefFeature);
    UnicodeStringRef pDoc = iv_heap->getStringValue(sofaAddr, internal::gs_tySofaStringFeature);
    copyDocumentString(pDoc);
  }

//   void CAS::updateAndIndexDocumentAnnotation() {
//  assert( EXISTS(iv_heap) );
//  if( iv_tyDocumentAnnotation == uima::lowlevel::FSHeap::INVALID_FS ) {
//    createDocumentAnnotation();
//  }
//  assert( iv_heap->resides( iv_tyDocumentAnnotation ) );
//  assert( EXISTS( iv_indexRepository ) );
//  iv_indexRepository->remove(iv_tyDocumentAnnotation);

//  iv_heap->setIntValue( iv_tyDocumentAnnotation, uima::internal::gs_tyEndPosFeature,
//         (int) iv_uiDocumentLength);
//  iv_heap->setIntValue(iv_tyDocumentAnnotation, uima::internal::gs_tySofaRefFeature,
//        (int) this->getSofaNum() );
//  iv_indexRepository->add(iv_tyDocumentAnnotation);
//   }

  void CAS::copyDocumentString(UnicodeStringRef pDoc) {
    // must have a 2nd copy of the document because the copy in the stringHeap will
    // move when the stringHeap grows, unlike the older segmented heap.
    if (pDoc.length() == 0) {
      return;
    }
    if (iv_copyOfDocument)
      delete [] iv_copyOfDocument;
    size_t len = pDoc.length();
    iv_copyOfDocument = new UChar [len + 1];
    memcpy(iv_copyOfDocument, pDoc.getBuffer(), 2*len);
    // The internal document must be 0 terminated!
    iv_copyOfDocument[len] = 0;
    iv_cpDocument = iv_copyOfDocument;
    iv_uiDocumentLength = len;
  }

  void CAS::refreshCachedTypes() {
    assert( EXISTS(iv_heap) );
    iv_utDocumentType =
      iv_heap->getTypeSystem().getTypeByName( uima::CAS::TYPE_NAME_DOCUMENT_ANNOTATION );
    assert( iv_utDocumentType != uima::lowlevel::TypeSystem::INVALID_TYPE );
    iv_utDocumentLangAsStrFeat =
      iv_heap->getTypeSystem().getFeatureByBaseName( iv_utDocumentType,
          uima::CAS::FEATURE_BASE_NAME_LANGUAGE );
    assert( iv_utDocumentLangAsStrFeat != uima::lowlevel::TypeSystem::INVALID_FEATURE );
  }

  // True if CAS contains one Sofa with special name and without SofaURI or SofaFSData set
  bool CAS::isBackwardCompatibleCas() {
    if (iv_sofaCount != 1 || !isInitialSofaCreated())
      return 0;
    Feature idFeat =
      getTypeSystem().getFeatureByFullName(CAS::FEATURE_FULL_NAME_SOFAID);
    SofaFS initSofa = getSofa(1);
    if (initSofa.getLocalFSData().isValid() ||
        initSofa.getSofaURI().length() > 0 ) {
      return 0;
    }
    UnicodeStringRef sofaID = getSofa(1).getStringValue(idFeat);
    if ( 0 == initSofa.getSofaID().compare(NAME_DEFAULT_SOFA) ) {
      return 1;
    }
    return 0;
  }

  void CAS::setCurrentComponentInfo(AnnotatorContext* info) {
    // always store component info in base CAS
    iv_baseCas->iv_componentInfo = info;
  }

  void CAS::registerInitialSofa() {
    iv_baseCas->initialSofaCreated = true;
  }

  bool CAS::isInitialSofaCreated() {
    return iv_baseCas->initialSofaCreated;
  }

  SofaFS CAS::createInitialSofa(UnicodeStringRef const mimeType) {
    if (isInitialSofaCreated()) {
      return getSofa(1);
    }
    Type sofaT = getTypeSystem().getType(CAS::TYPE_NAME_SOFA);
    lowlevel::TyFS tySofa = iv_heap->createFS(internal::FSPromoter::demoteType(sofaT));
    SofaFS newSofa = (SofaFS)internal::FSPromoter::promoteFS(tySofa, *this->iv_baseCas);
    newSofa.setIntValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaNumFeature, iv_heap->getTypeSystem()), 1);
    newSofa.setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaIDFeature, iv_heap->getTypeSystem()), NAME_DEFAULT_SOFA);
    newSofa.setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaMimeFeature, iv_heap->getTypeSystem()), mimeType);
    iv_baseCas->iv_indexRepository->add(tySofa);
    registerInitialSofa();
    return newSofa;
  }

  CAS* CAS::getInitialView() {
    if (iv_baseCas->iv_initialView != 0) {
      return iv_baseCas->iv_initialView;
    }
    // create the initial view, without a Sofa
    CAS* aTcas = (CAS*) new uima::internal::CASImpl(this->iv_baseCas);
    assert ( EXISTS(aTcas) );
    pair<int, CAS*> p1(1, aTcas);
    iv_baseCas->iv_sofa2tcasMap.insert(p1);
    iv_baseCas->iv_sofaCount = 1;
    iv_baseCas->iv_initialView = aTcas;
    return aTcas;
  }

  FSIndexRepository & CAS::getBaseIndexRepository( void ) {
    assert( EXISTS(iv_baseCas->iv_indexRepository) );
    return *iv_baseCas->iv_indexRepository;
  }

  CAS & CAS::getCasForTyFS(lowlevel::TyHeapCell tyCell) {
    lowlevel::TyFS type = getHeap()->getHeap().getHeapValue(tyCell);
    if (type != uima::lowlevel::FSHeap::INVALID_FS &&
        getHeap()->getTypeSystem().subsumes(internal::gs_tyAnnotationType,
                                            internal::FSPromoter::demoteType(internal::FSPromoter::promoteFS(tyCell, *this).getType()))) {
      // an annotation. Check that sofaNum agrees with current CAS
      lowlevel::TyFS annSofaAddr = getHeap()->getFSValue(tyCell, internal::gs_tySofaRefFeature);
      if ( annSofaAddr != internal::FSPromoter::demoteFS(getSofa())) {
        // does not agree. Get appropriate View for annotation Sofa
        int annSofaNum = getHeap()->getIntValue(annSofaAddr, internal::gs_tySofaNumFeature);
        return *getViewBySofaNum(annSofaNum);
      }
    }
    return *this;
  }


  /*****************************************************************************/
  /*  SofaFS                                                             */
  /*****************************************************************************/
  SofaFS::SofaFS(FeatureStructure const & fs)
      : FeatureStructure(fs) {
    assert(sizeof(FeatureStructure) == sizeof(SofaFS)); // no additonal data members
  }

  void SofaFS::setSofaMime(icu::UnicodeString const & aString) {
    //TODO FAIL THIS IF MIME ALREADY SET ???
    lowlevel::TyFS tySofa = internal::FSPromoter::demoteFS(*this);
    this->setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaMimeFeature, iv_cas->getHeap()->getTypeSystem()), aString);
    return;
  }

  void SofaFS::setLocalSofaData(FeatureStructure aFS) {
    //TODO NEED TO FAIL THIS IF DATA, STRING, or URI ALREADY SET !!!
    lowlevel::TyFS tySofa = internal::FSPromoter::demoteFS(*this);
    iv_cas->getHeap()->setFSValue(tySofa, internal::gs_tySofaArrayFeature,
                                  internal::FSPromoter::demoteFS(aFS));
    return;
  }

  void SofaFS::setLocalSofaData(UnicodeStringRef const aString) {
    //TODO NEED TO FAIL THIS IF DATA, STRING, or URI ALREADY SET !!!
    this->setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaStringFeature,
                         iv_cas->getHeap()->getTypeSystem()), aString);
    int sofaNum = this->getIntValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaNumFeature,
                                    iv_cas->getHeap()->getTypeSystem()));
    iv_cas->getViewBySofaNum(sofaNum)->updateDocumentAnnotation();
    return;
  }

  void SofaFS::setRemoteSofaURI(const char* aURI) {
    icu::UnicodeString const ucURI(aURI, strlen(aURI), "utf8");
    return setRemoteSofaURI(ucURI);
  }

  void SofaFS::setRemoteSofaURI(icu::UnicodeString const & aString) {
    //TODO NEED TO FAIL THIS IF DATA, STRING, or URI ALREADY SET !!!
    this->setStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaURIFeature, iv_cas->getHeap()->getTypeSystem()), aString);
    return;
  }

  UnicodeStringRef SofaFS::getSofaMime() {
    return this->getStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaMimeFeature, iv_cas->getHeap()->getTypeSystem()));
  }

  UnicodeStringRef SofaFS::getSofaID() {
    return this->getStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaIDFeature, iv_cas->getHeap()->getTypeSystem()));
  }

  UnicodeStringRef SofaFS::getSofaURI() {
    return this->getStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaURIFeature, iv_cas->getHeap()->getTypeSystem()));
  }

  int SofaFS::getSofaRef() {
    return this->getIntValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaNumFeature, iv_cas->getHeap()->getTypeSystem()));
  }

  FeatureStructure SofaFS::getLocalFSData() {
    return this->getFSValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaArrayFeature, iv_cas->getHeap()->getTypeSystem()));
  }

  UnicodeStringRef SofaFS::getLocalStringData() {
    return this->getStringValue(internal::FSPromoter::promoteFeature(internal::gs_tySofaStringFeature, iv_cas->getHeap()->getTypeSystem()));
  }

  SofaDataStream * SofaFS::getSofaDataStream() {
    Type type = getType();
    Feature uriFeat = type.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_SOFAURI);
    Feature stringFeat = type.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_SOFASTRING);
    Feature arrayFeat = type.getFeatureByBaseName(CAS::FEATURE_BASE_NAME_SOFAARRAY);

    if ( !isUntouchedFSValue(uriFeat) ) {                //remote sofa
      return new RemoteSofaDataStream(*this);
    } else if  ( !isUntouchedFSValue(stringFeat) ) {     //local sofa - data in string
      return new LocalSofaDataStream(*this);
    } else if ( !isUntouchedFSValue(arrayFeat) ) {       //local sofa - data in fs array
      return new LocalSofaDataStream(*this);
    } else return NULL;                                   //no sofa data set
  }

  SofaDataStream * SofaFS::getSofaDataStream(FeatureStructure & fs) {
    return NULL;
  }

  /*****************************************************************************/
  /*  AnnotationFS                                                             */
  /*****************************************************************************/
  AnnotationFS::AnnotationFS(FeatureStructure const & fs)
      : FeatureStructure(fs) {
    assert(sizeof(FeatureStructure) == sizeof(AnnotationFS)); // no additonal data members
    assert(EXISTS(iv_cas));
    assert( iv_cas->getHeap()->getTypeSystem().subsumes(iv_cas->getHeap()->getTypeSystem().getTypeByName(CAS::TYPE_NAME_ANNOTATION),
            iv_cas->getHeap()->getType(internal::FSPromoter::demoteFS(fs)) ) );
  }

  CAS & AnnotationFS::getCAS() {
    checkValidity(UIMA_MSG_ID_EXCON_GETTING_FSTYPE);
    assert(EXISTS(iv_cas));
    return *iv_cas;
  }

  CAS const & AnnotationFS::getCAS() const {
    checkValidity(UIMA_MSG_ID_EXCON_GETTING_FSTYPE);
    assert(EXISTS(iv_cas));
    return *iv_cas;
  }

  CAS * AnnotationFS::getView() {
    assert(EXISTS(iv_cas));
    lowlevel::TyFS annSofaAddr = iv_cas->getHeap()->getFSValue(iv_tyFS, internal::gs_tySofaRefFeature);
    int annSofaNum = iv_cas->getHeap()->getIntValue(annSofaAddr, internal::gs_tySofaNumFeature);
    return iv_cas->getViewBySofaNum(annSofaNum);
  }

  size_t AnnotationFS::getBeginPosition( void ) const {
    assert(EXISTS(iv_cas));
    assert(iv_cas->getHeap()->getIntValue(iv_tyFS, uima::internal::gs_tyBeginPosFeature) >= 0);
    return(size_t)iv_cas->getHeap()->getIntValue(iv_tyFS, uima::internal::gs_tyBeginPosFeature);
  }


  size_t AnnotationFS::getEndPosition( void ) const {
    assert(EXISTS(iv_cas));
    assert(iv_cas->getHeap()->getIntValue(iv_tyFS, uima::internal::gs_tyEndPosFeature) >= 0);
    return(size_t)iv_cas->getHeap()->getIntValue(iv_tyFS, uima::internal::gs_tyEndPosFeature);
  }


  UnicodeStringRef AnnotationFS::getCoveredText( void ) const {
    if (isValid()) {
      AnnotationFS* grr = const_cast<AnnotationFS*>(this);
      CAS * myCas = grr->getView();
      if (myCas->iv_uiDocumentLength > 0) {
        assert( getEndPosition() <= myCas->iv_uiDocumentLength );
        size_t uiBegin = getBeginPosition();
        UChar const * puc = myCas->iv_cpDocument;
        puc += uiBegin;
        return UnicodeStringRef( puc, getEndPosition()-uiBegin );
      }
    }

    UIMA_EXC_THROW_NEW(InvalidFSObjectException,
                       UIMA_ERR_INVALID_FS_OBJECT,
                       UIMA_MSG_ID_EXC_INVALID_FS_OBJECT,
                       ErrorMessage(UIMA_MSG_ID_EXCON_GETTING_FEATURE_VALUE),
                       ErrorInfo::recoverable
                      );
  }

  AnnotationFS AnnotationFS::getFirstCoveringAnnotation( Type ofType ) const {
    if (!(isValid() && ofType.isValid())) {
      return AnnotationFS(); //will be invalid
    }
    assert(EXISTS(iv_cas));
    /* Let's create an Index of Type typeOfType */
    ANIterator itOfType(getCAS().getAnnotationIndex(ofType).iterator());
    /* Declare an object instance for the covering annotation we are looking for
     If we find one, it will be initialized below, if we don't find one,
     we return the invalid (because uninitialized) variable */
    AnnotationFS fsCoveringAn;
    size_t uiBegPosFrom = getBeginPosition();
    size_t uiEndPosFrom = getEndPosition();

    /* Iterate over all annotations in the ofTypeIdx */
    AnnotationFS fsOfTypeAn;
    for (itOfType.moveToFirst(); itOfType.isValid(); itOfType.moveToNext()) {
      fsOfTypeAn = itOfType.get();
      size_t uiBegPosOf   = fsOfTypeAn.getBeginPosition();
      size_t uiEndPosOf   = fsOfTypeAn.getEndPosition();
      if ((uiBegPosOf <= uiBegPosFrom )  &&
          (uiEndPosOf >= uiEndPosFrom)) {
        if (fsOfTypeAn.getType() != getType()) {
          fsCoveringAn = fsOfTypeAn;
        }
      } else {
        if (uiBegPosOf > uiBegPosFrom) {
          return fsCoveringAn;  //shortcut - avoids unecessary iteration
        }
      }
    };
    return fsCoveringAn;
  }

  ANIterator AnnotationFS::subIterator( Type const & crType, EnIteratorAmbiguity enAmbiguous ) const {
    return getCAS().getAnnotationIndex(crType).subIterator(*this, enAmbiguous);
  }


  /*****************************************************************************/
  /*  DocumentFS                                                               */
  /*****************************************************************************/
  DocumentFS::DocumentFS(FeatureStructure const & fs)
      : AnnotationFS(fs) {
    assert( EXISTS(iv_cas) );
    assert( iv_cas->getHeap()->getTypeSystem().subsumes(
              iv_cas->getHeap()->getTypeSystem().getTypeByName(CAS::TYPE_NAME_DOCUMENT_ANNOTATION),
              iv_cas->getHeap()->getType(internal::FSPromoter::demoteFS(fs)) ) );
  }

  Language DocumentFS::getLanguage() const {
    assert(EXISTS(iv_cas));
    assert( iv_cas->getHeap()->isValid(iv_tyFS) );

    if ( iv_cas->getHeap()->getTypeSystem().isValidFeature(getCAS().iv_utDocumentLangAsIntFeat) ) {
      int iLangID = iv_cas->getHeap()->getIntValue(iv_tyFS, getCAS().iv_utDocumentLangAsIntFeat);
      if (iLangID != 0) {
        return Language( iLangID );
      }
    }
    assert( iv_cas->getHeap()->getTypeSystem().isValidFeature(getCAS().iv_utDocumentLangAsStrFeat) );
    UnicodeStringRef ustrrefLang = iv_cas->getHeap()->getStringValue(iv_tyFS, getCAS().iv_utDocumentLangAsStrFeat);
    return Language( ustrrefLang );
  }

  void DocumentFS::setLanguage(Language const & lang) {
    assert(EXISTS(iv_cas));
    assert( iv_cas->getHeap()->isValid(iv_tyFS) );

    if ( iv_cas->getHeap()->getTypeSystem().isValidFeature(getCAS().iv_utDocumentLangAsIntFeat) ) {
      iv_cas->getHeap()->setIntValue(iv_tyFS, getCAS().iv_utDocumentLangAsIntFeat, lang.asNumber());
    }
    assert( iv_cas->getHeap()->getTypeSystem().isValidFeature(getCAS().iv_utDocumentLangAsStrFeat) );
    int ref = iv_cas->getHeap()->addString( lang.asUnicodeString() );
    iv_cas->getHeap()->setStringValue(iv_tyFS, getCAS().iv_utDocumentLangAsStrFeat, ref);
  }


  /*****************************************************************************/
  /*  SubIterator                                                              */
  /*****************************************************************************/

  namespace lowlevel {

    class SubIterator : public IndexIterator {
    protected:
      uima::lowlevel::FSHeap * iv_heap;
      IndexIterator* iv_pIterator;
      size_t iv_uiBegPos;
      size_t iv_uiEndPos;
      TyFS   iv_tyMoveToFirstFS;
    public:
      SubIterator(uima::lowlevel::FSHeap & heap, size_t uiBeginPos, size_t uiEndPos, IndexIterator* pIterator):
          iv_heap(&heap),
          iv_pIterator(pIterator),
          iv_uiBegPos(uiBeginPos),
          iv_uiEndPos(uiEndPos),
          iv_tyMoveToFirstFS(0) {
        assert( EXISTS(iv_heap) );
        TyFSType    tyTAN  = iv_heap->getTypeSystem().getTypeByName(CAS::TYPE_NAME_ANNOTATION);
        // create the longest possible AN starting at uiBeginPos (must be first of all starting there)
        iv_tyMoveToFirstFS = iv_heap->createFS(tyTAN);
        iv_heap->setIntValue(iv_tyMoveToFirstFS, uima::internal::gs_tyBeginPosFeature, (int)iv_uiBegPos );
        iv_heap->setIntValue(iv_tyMoveToFirstFS, uima::internal::gs_tyEndPosFeature, INT_MAX );
      }

      SubIterator(uima::lowlevel::FSHeap & heap, TyFS tyAn, IndexIterator* pIterator):
          iv_heap(&heap),
          iv_pIterator(pIterator),
          iv_uiBegPos(iv_heap->getIntValue(tyAn, uima::internal::gs_tyBeginPosFeature)),
          iv_uiEndPos(iv_heap->getIntValue(tyAn, uima::internal::gs_tyEndPosFeature)),
          iv_tyMoveToFirstFS(tyAn) {}

      virtual ~SubIterator() {
        assert( EXISTS(iv_pIterator) );
        assert( EXISTS(iv_heap) );
        delete iv_pIterator;
      }

      void moveToFirst() {
        UIMA_TPRINT("lowlevel::SubIterator::moveToFirst() entered");
        assert( EXISTS(iv_pIterator) );
        assert( EXISTS(iv_heap) );
        iv_pIterator->moveTo( iv_tyMoveToFirstFS );
        if (isValid()) {
          if (iv_pIterator->get() == iv_tyMoveToFirstFS) {
            iv_pIterator->moveToNext();
          }
        }
      }

      void moveToNext() {
        UIMA_TPRINT("lowlevel::SubIterator::moveToNext() entered");
        assert( isValid() );
        iv_pIterator->moveToNext();
        if (isValid()) {
          if (iv_pIterator->get() == iv_tyMoveToFirstFS) {
            iv_pIterator->moveToNext();
          }
        }

      }

      void moveToPrevious() {
        assert( isValid() );
        iv_pIterator->moveToPrevious();
        if (isValid()) {
          if (iv_pIterator->get() == iv_tyMoveToFirstFS) {
            iv_pIterator->moveToPrevious();
          }
        }
      }

      void moveToLast() {
        UIMA_TPRINT("moveToLast() entered");
        moveToFirst();
        if (!isValid()) {
          return;
        }
        assert( isValid() );
        uima::lowlevel::TyFS lastValidFS = uima::lowlevel::FSHeap::INVALID_FS;
        while (isValid()) {
          lastValidFS = get();
          moveToNext();
        }
        assert( ! isValid() );
        assert(lastValidFS != uima::lowlevel::FSHeap::INVALID_FS);

        moveTo(lastValidFS);
        assert( isValid() );

        if (isValid()) {
          if (iv_pIterator->get() == iv_tyMoveToFirstFS) {
            iv_pIterator->moveToPrevious();
          }
        }


#ifdef DEBUG_VERBOSE
        UIMA_TPRINT("last FS passed over: ");
        iv_pFSSystem->getLowlevelFSHeap().printFS(cerr, lastValidFS);
        UIMA_TPRINT("last FS: ");
        iv_pFSSystem->getLowlevelFSHeap().printFS(cerr, get());
#endif
      }

      TyFS get() const {
          assert( isValid() );
          return iv_pIterator->get();
        }


      TyFSType getTyFSType() const {
        assert( isValid() );
        return iv_pIterator->getTyFSType();
      }

      bool isValid() const {
        assert( EXISTS(iv_heap) );
        assert( EXISTS(iv_pIterator) );
        if (!iv_pIterator->isValid()) {
          return false;
        }
        TyFS fsCurrent = iv_pIterator->get();
        size_t uiCurrBegPos = iv_heap->getIntValue(fsCurrent, uima::internal::gs_tyBeginPosFeature);
        // true if current begin is between begin and end pos of our span
        return(uiCurrBegPos >= iv_uiBegPos && uiCurrBegPos < iv_uiEndPos);
      }

      IndexIterator* clone() const {
        UIMA_TPRINT("lowlevel::SubIterator::clone() entered");
        assert( EXISTS(iv_heap) );
        assert( EXISTS(iv_pIterator) );
        // don't call 4-arg constructor here! Pass on the FS to be moved to
        IndexIterator * pResult = new SubIterator(*iv_heap, iv_tyMoveToFirstFS, iv_pIterator->clone());
        assert( EXISTS(pResult) );

        assert( isValid() == pResult->isValid() );
#ifndef NDEBUG
        if (isValid()) {
          assert( get() == pResult->get() );
        }
#endif
        return pResult;
      }

      bool moveTo(TyFS fs) {
        assert( EXISTS(iv_heap) );
        assert( EXISTS(iv_pIterator) );
        return iv_pIterator->moveTo(fs);
      }

    }
    ; // class SubIterator


    class UnAmbiguousSubIterator : public SubIterator {
    private:
    public:
      UnAmbiguousSubIterator(uima::lowlevel::FSHeap & heap, size_t uiBeginPos, size_t uiEndPos, IndexIterator* pIterator):
          SubIterator(heap, uiBeginPos, uiEndPos, pIterator) {}

      UnAmbiguousSubIterator(uima::lowlevel::FSHeap & heap, TyFS tyAn, IndexIterator* pIterator):
          SubIterator(heap, tyAn, pIterator) {}

      void moveToNext() {
        /*
        assert( isValid() );
        size_t uiLastEndPos = (size_t)iv_pFSSystem->getLowlevelFSHeap().getIntValue(SubIterator::get(), uima::internal::gs_tyEndPosFeature);
        size_t uiCurrBeginPos;
        do {
           SubIterator::moveToNext();
           if (!isValid()) {
              return;
           }
           uiCurrBeginPos = iv_pFSSystem->getLowlevelFSHeap().getIntValue(SubIterator::get(), uima::internal::gs_tyBeginPosFeature);
        } while (uiCurrBeginPos < uiLastEndPos);
        */
        assert( EXISTS(iv_heap) );
        assert( isValid() );

        size_t uiLastEndPos = (size_t)iv_heap->getIntValue(iv_pIterator->get(), uima::internal::gs_tyEndPosFeature);
        size_t uiCurrBeginPos;
        do {
          iv_pIterator->moveToNext();
          if (!isValid()) {
            return;
          }
          uiCurrBeginPos = iv_heap->getIntValue(iv_pIterator->get(), uima::internal::gs_tyBeginPosFeature);
        } while (uiCurrBeginPos < uiLastEndPos);

      }

      IndexIterator* clone() const {
        assert( EXISTS(iv_heap) );
        assert( EXISTS(iv_pIterator) );
        return new UnAmbiguousSubIterator(*iv_heap, iv_tyMoveToFirstFS, iv_pIterator->clone());
      }

    }
    ; // class UnAmbiguousSubIterator

    class UnambiguousIterator : public IndexIterator {
    protected:
      uima::lowlevel::FSHeap* iv_heap;
      IndexIterator* iv_pIterator;
    public:
      UnambiguousIterator(uima::lowlevel::FSHeap & heap, IndexIterator* pIterator):
          iv_heap(&heap),
          iv_pIterator(pIterator) {
        assert( EXISTS(iv_heap) );
      }

      virtual ~UnambiguousIterator() {
        assert( EXISTS(iv_pIterator) );
        assert( EXISTS(iv_heap) );
        delete iv_pIterator;
      }

      void moveToFirst() {
        assert( EXISTS(iv_pIterator) );
        assert( EXISTS(iv_heap) );
        iv_pIterator->moveToFirst();
      }

      void moveToNext() {
        assert( isValid() );
        size_t uiLastEndPos = (size_t)iv_heap->getIntValue(iv_pIterator->get(), uima::internal::gs_tyEndPosFeature);
        size_t uiCurrBeginPos;
        do {
          iv_pIterator->moveToNext();
          if (!isValid()) {
            return;
          }
          uiCurrBeginPos = iv_heap->getIntValue(iv_pIterator->get(), uima::internal::gs_tyBeginPosFeature);
        } while (uiCurrBeginPos < uiLastEndPos);
      }

      void moveToPrevious() {
        assertWithMsg(false, "Not implemented yet!");
        UIMA_EXC_THROW_NEW(NotYetImplementedException,
                           UIMA_ERR_NOT_YET_IMPLEMENTED,
                           UIMA_MSG_ID_EXC_NOT_YET_IMPLEMENTED,
                           ErrorMessage(UIMA_MSG_ID_EXCON_UNKNOWN_CONTEXT),
                           ErrorInfo::unrecoverable
                          );
      }

      void moveToLast() {
        assertWithMsg(false, "Not implemented yet!");
        UIMA_EXC_THROW_NEW(NotYetImplementedException,
                           UIMA_ERR_NOT_YET_IMPLEMENTED,
                           UIMA_MSG_ID_EXC_NOT_YET_IMPLEMENTED,
                           ErrorMessage(UIMA_MSG_ID_EXCON_UNKNOWN_CONTEXT),
                           ErrorInfo::unrecoverable
                          );
      }

      TyFS get() const {
          assert( isValid() );
          return iv_pIterator->get();
        }

      TyFSType getTyFSType() const {
        assert( isValid() );
        return iv_pIterator->getTyFSType();
      }

      bool isValid() const {
        assert( EXISTS(iv_heap) );
        assert( EXISTS(iv_pIterator) );
        if (!iv_pIterator->isValid()) {
          return false;
        }
        return true;
      }

      IndexIterator* clone() const {
        assert( EXISTS(iv_heap) );
        assert( EXISTS(iv_pIterator) );
        return new UnambiguousIterator(*iv_heap, iv_pIterator->clone());
      }

      bool moveTo(TyFS fs) {
        assert( EXISTS(iv_heap) );
        assert( EXISTS(iv_pIterator) );
        return iv_pIterator->moveTo(fs);
      }

    }
    ; // class UnambiguousIterator
  } // namespace lowlevel


  ANIterator ANIndex::subIterator( AnnotationFS const & an, EnIteratorAmbiguity enAmbiguous ) const {
    checkValidity();
    lowlevel::IndexIterator* pitBase = iv_pIndex->createIterator();
    assert( EXISTS(pitBase) );

    lowlevel::IndexIterator* pitSub;
    if (enAmbiguous == enUnambiguous) {
      pitSub = new lowlevel::UnAmbiguousSubIterator( iv_indexRepository->getFSHeap(), internal::FSPromoter::demoteFS(an), pitBase);
    } else {
      assert(enAmbiguous == enAmbiguous);
      pitSub = new lowlevel::SubIterator(iv_indexRepository->getFSHeap(), internal::FSPromoter::demoteFS(an), pitBase);
    }
    assert( EXISTS(pitSub) );

    return ANIterator(pitSub, &iv_indexRepository->getCas());
  }

  ANIterator ANIndex::unambiguousIterator() const {
    checkValidity();
    lowlevel::IndexIterator* pitBase = iv_pIndex->createIterator();
    assert( EXISTS(pitBase) );

    lowlevel::IndexIterator* pitSub;
    pitSub = new lowlevel::UnambiguousIterator(iv_indexRepository->getFSHeap(), pitBase);
    assert( EXISTS(pitSub) );

    return ANIterator(pitSub, &iv_indexRepository->getCas());
  }

}

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





