/** \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(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());
  }

}

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





