/** \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"

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(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) {
    UnicodeString const uName(sofaName, strlen(sofaName), "utf8");
    UnicodeString const uMime(mimeType, strlen(mimeType), "utf8");
    return createSofa(uName, uMime);
  }

  SofaFS CAS::createSofa(const SofaID & sofaName, const char* mimeType) {
    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) {
    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) {
    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());
  }

}

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





