/** \file internal_casserializer.cpp .
-----------------------------------------------------------------------------


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

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

   Description:

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


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


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

//#define DEBUG_VERBOSE
#include "uima/pragmas.hpp"

#include "uima/macros.h"
#include "uima/internal_casserializer.hpp"
#include "uima/internal_casimpl.hpp"
#include "uima/lowlevel_fsheap.hpp"
#include "uima/lowlevel_indexiterator.hpp"
#include "uima/result_specification.hpp"
#include "uima/casdefinition.hpp"

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

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

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

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


namespace uima {
  namespace internal {


    void CASSerializer::serializeResultSpec(ResultSpecification const & resultSpec,
                                            vector<SerializedCAS::TyNum>& resultSpecTypes,
                                            vector<SerializedCAS::TyNum>& resultSpecFeatures) {
      ResultSpecification::TyTypeOrFeatureSTLSet const & tofSet = resultSpec.getTypeOrFeatureSTLSet();
      ResultSpecification::TyTypeOrFeatureSTLSet::const_iterator cit;
      for (cit = tofSet.begin(); cit != tofSet.end(); ++cit) {
        TypeOrFeature const & tof = *cit;
        if (tof.isType()) {
          Type t = tof.getType();
          assert( t.isValid() );
          resultSpecTypes.push_back( uima::internal::FSPromoter::demoteType(t) );
        } else {
          Feature f = tof.getFeature();
          assert( f.isValid() );
          resultSpecFeatures.push_back( uima::internal::FSPromoter::demoteFeature(f) );
        }
      }
    }


    bool isInterval(uima::lowlevel::TyFSType first, uima::lowlevel::TyFSType last, vector<uima::lowlevel::TyFSType> const & vec) {
      size_t i;
      for (i=0; i<vec.size(); ++i) {
        if (vec[i] != first + i) {
          return false;
        }
      }
      return true;
    }

    CASSerializer::CASSerializer(bool bCopyStrings)
        : iv_bCopyStrings(bCopyStrings) {}

    CASSerializer::~CASSerializer() {}

    UnicodeStringRef CASSerializer::createString(UChar const * cpBuf, size_t uiLen, uima::internal::SerializedCAS & rSerializedCAS) {
      UnicodeStringRef ref(cpBuf, uiLen);
      if (iv_bCopyStrings) {
        return rSerializedCAS.addString(ref);
      }
      return ref;
    }


    void CASSerializer::serializeTypeSystem(uima::internal::CASDefinition const & casDef, uima::internal::SerializedCAS & rSerializedCAS) {
      uima::lowlevel::TypeSystem const & crTypeSystem = casDef.getTypeSystem();
      UnicodeStringRef invalidUSP(rSerializedCAS.iv_emptyString.getBuffer(), rSerializedCAS.iv_emptyString.length());
      assert( invalidUSP.getBuffer() != NULL );
      assert( invalidUSP.length() == 0);

      // 1. inheritance vector
      rSerializedCAS.iv_vecTypeInheritanceTable.clear();
      size_t uiTypeNum = crTypeSystem.getNumberOfTypes() + 1;
      rSerializedCAS.iv_vecTypeInheritanceTable.resize(uiTypeNum, 0);

#ifndef NDEBUG
      vector<uima::lowlevel::TyFSType> vecTypes;
      crTypeSystem.getAllTypes(vecTypes);
      assert( isInterval(1, uiTypeNum, vecTypes) );
      assert( uiTypeNum == vecTypes.size() + 1);
#endif

      size_t i;
      assert( 0 == uima::lowlevel::TypeSystem::INVALID_TYPE );
      assert( 1 == crTypeSystem.getTopType() );
      for (i=2; i<uiTypeNum; ++i) {
        uima::lowlevel::TyFSType tyChild = (uima::lowlevel::TyFSType) i;
        uima::lowlevel::TyFSType tyParent = crTypeSystem.getParentType( tyChild );
        assert( tyParent <rSerializedCAS.iv_vecTypeInheritanceTable.size() );
        rSerializedCAS.iv_vecTypeInheritanceTable[tyChild] =  tyParent;
      }

      // 2. feature intro vector
      rSerializedCAS.iv_vecFeatureDefinitionTable.clear();
      size_t uiFeatureNum = crTypeSystem.getNumberOfFeatures() + 1;

      // leave the first three cells empty
      rSerializedCAS.iv_vecFeatureDefinitionTable.resize(3,0);

#ifndef NDEBUG
      vector<uima::lowlevel::TyFSFeature> vecFeatures;
      crTypeSystem.getAllFeatures(vecFeatures);
      assert( isInterval(1, uiFeatureNum, vecFeatures) );
      assert( uiFeatureNum == vecFeatures.size() + 1);
#endif

      assert( 0 == uima::lowlevel::TypeSystem::INVALID_FEATURE );
      for (i=1; i<uiFeatureNum; ++i) {
        uima::lowlevel::TyFSFeature tyFeat = (uima::lowlevel::TyFSFeature) i;
        UIMA_TPRINT("Adding feature with ID: " << tyFeat );
        UIMA_TPRINT("Adding feature: " << crTypeSystem.getFeatureName(tyFeat) );
        uima::lowlevel::TyFSType tyIntroType = crTypeSystem.getIntroType(tyFeat);
        uima::lowlevel::TyFSType tyRangeType = crTypeSystem.getRangeType(tyFeat);
		int tyMultiRefs = crTypeSystem.isMultipleReferencesAllowed(tyFeat) ? 1 : 0;
        rSerializedCAS.iv_vecFeatureDefinitionTable.push_back( tyIntroType );
        rSerializedCAS.iv_vecFeatureDefinitionTable.push_back( tyRangeType );
        rSerializedCAS.iv_vecFeatureDefinitionTable.push_back( tyMultiRefs );
      }

#ifndef NDEBUG
      for (i=1; i<vecFeatures.size(); ++i) {
        uima::lowlevel::TyFSFeature tyFeat = vecFeatures[i];
        uima::lowlevel::TyFSType tyIntroType = crTypeSystem.getIntroType(tyFeat);
        uima::lowlevel::TyFSType tyRangeType = crTypeSystem.getRangeType(tyFeat);
		int tyMultiRefs = crTypeSystem.isMultipleReferencesAllowed(tyFeat) ? 1 : 0;
        assert( (tyFeat*2) <rSerializedCAS.iv_vecFeatureDefinitionTable.size() );
        assert( (tyFeat*2+1) <rSerializedCAS.iv_vecFeatureDefinitionTable.size() );
        assert( rSerializedCAS.iv_vecFeatureDefinitionTable[tyFeat*3] == tyIntroType );
        assert( rSerializedCAS.iv_vecFeatureDefinitionTable[tyFeat*3+1] == tyRangeType );
        assert( rSerializedCAS.iv_vecFeatureDefinitionTable[tyFeat*3+2] == tyMultiRefs );
      }
#endif


      // 3. type string table
      rSerializedCAS.iv_vecTypeSymbolTable.resize(uiTypeNum);
      assert( rSerializedCAS.iv_vecTypeSymbolTable.size() == uiTypeNum );
      rSerializedCAS.iv_vecTypeSymbolTable[0] = invalidUSP;
      for (i=1; i<uiTypeNum; ++i) {
        icu::UnicodeString const & crTypeName = crTypeSystem.getTypeName(i);
        UnicodeStringRef pus = createString( crTypeName.getBuffer(), crTypeName.length(), rSerializedCAS);
        rSerializedCAS.iv_vecTypeSymbolTable[i] = pus;
      }

      // 4. feature string and feature offset table
      rSerializedCAS.iv_vecFeatureSymbolTable.resize(uiFeatureNum);
      assert( rSerializedCAS.iv_vecFeatureSymbolTable.size() == uiFeatureNum );
      rSerializedCAS.iv_vecFeatureOffsetTable.resize(uiFeatureNum);
      assert( rSerializedCAS.iv_vecFeatureOffsetTable.size() == uiFeatureNum );
      rSerializedCAS.iv_vecFeatureSymbolTable[0] = invalidUSP;
      rSerializedCAS.iv_vecFeatureOffsetTable[0] = 0;
      for (i=1; i<uiFeatureNum; ++i) {
        uima::lowlevel::TyFSFeature tyFeat = i;
        // string
        icu::UnicodeString const & crFeatureName = crTypeSystem.getFeatureBaseName(tyFeat);
        UnicodeStringRef pus = createString( crFeatureName.getBuffer(), crFeatureName.length(), rSerializedCAS);
        rSerializedCAS.iv_vecFeatureSymbolTable[i] = pus;

        // offset
        rSerializedCAS.iv_vecFeatureOffsetTable[i] = crTypeSystem.getFeatureOffset(tyFeat);
      }

      // 5. type priorities
      rSerializedCAS.iv_vecTypePriorityTable.resize(uiTypeNum-1);
      for (i=1; i<uiTypeNum; ++i) {
        size_t num = crTypeSystem.getTypePriorityNumber((uima::lowlevel::TyFSType) i);
        rSerializedCAS.iv_vecTypePriorityTable[num] = i;
      }

      // 6. string sub types
      vector<uima::lowlevel::TyFSType> stringSubTypes;
      crTypeSystem.getDirectSubTypes( uima::internal::gs_tyStringType,
                                      stringSubTypes );

      rSerializedCAS.iv_stringSubTypes.clear();
      for (i=0; i<stringSubTypes.size(); ++i) {
        rSerializedCAS.iv_stringSubTypes.push_back(stringSubTypes[i]);
      }
      rSerializedCAS.iv_stringSubTypeValues.clear();
      rSerializedCAS.iv_stringSubTypeValuePos.clear();
      for (i=0; i<rSerializedCAS.iv_stringSubTypes.size(); ++i) {
        size_t n = rSerializedCAS.iv_stringSubTypeValues.size();
        rSerializedCAS.iv_stringSubTypeValuePos.push_back(n);

        vector<icu::UnicodeString> const & stringValues = crTypeSystem.getStringsForStringSubtype(rSerializedCAS.iv_stringSubTypes[i]);
        size_t j;
        for (j=0; j<stringValues.size(); ++j) {
          UnicodeStringRef ref(stringValues[j]);
          rSerializedCAS.iv_stringSubTypeValues.push_back( ref );
        }
      }
      assert( rSerializedCAS.iv_stringSubTypes.size() == rSerializedCAS.iv_stringSubTypeValuePos.size() );
    }


#if defined( _MSC_VER )
// locally disable warning about conversion from 'uima::internal::SerializedCAS::TyNum' to 'const int', possible loss of data
#  pragma warning( disable: 4244 )
#endif
    void CASSerializer::serializeIndexDefinition(uima::internal::CASDefinition const & casdef, uima::internal::SerializedCAS & rSerializedCAS) {
      uima::lowlevel::IndexDefinition const & indexDef = casdef.getIndexDefinition();

      vector<uima::lowlevel::IndexDefinition::TyIndexID> vecIndexIDs;

      indexDef.getAllIndexIDs(vecIndexIDs);
      size_t uiIndexNum = vecIndexIDs.size();
      rSerializedCAS.iv_vecIndexIDTable.resize(uiIndexNum);
      rSerializedCAS.iv_vecComparatorStartTable.resize(uiIndexNum);
      rSerializedCAS.iv_vecIndexKindTable.resize(uiIndexNum);
      rSerializedCAS.iv_vecComparatorDefinitionTable.clear();

      size_t i;
      for (i=0; i<uiIndexNum; ++i) {
        uima::lowlevel::IndexDefinition::TyIndexID const & crIndexID = vecIndexIDs[i];
        rSerializedCAS.iv_vecIndexIDTable[i] = createString( crIndexID.getBuffer(),
                                               crIndexID.length(), rSerializedCAS);
        rSerializedCAS.iv_vecIndexKindTable[i] = indexDef.getIndexKind( crIndexID );
        UIMA_TPRINT("Index ID: " << crIndexID );
        // start of the next comparator definition
        // is at the end of rSerializedCAS.iv_vecComparatorDefinitionTable
        rSerializedCAS.iv_vecComparatorStartTable[i] = rSerializedCAS.iv_vecComparatorDefinitionTable.size();

        // add type of the index
        uima::lowlevel::TyFSType indexType = indexDef.getTypeForIndex(crIndexID);
        // add type of the comparator (even if the index has none)
        rSerializedCAS.iv_vecComparatorDefinitionTable.push_back( indexType );

        uima::lowlevel::IndexComparator const * pComparator = indexDef.getComparator( crIndexID );
        if ( pComparator != NULL ) {
          UIMA_TPRINT(" Index has comparator!");
          assert( pComparator->getType() == indexType );
          // serialize comparator
          vector<uima::lowlevel::TyFSFeature> const & crKeyFeatures = pComparator->getKeyFeatures();
          vector<uima::lowlevel::IndexComparator::EnKeyFeatureComp> const & crCompOps = pComparator->getComparisonOps();
          assert( crKeyFeatures.size() == crCompOps.size() );
          // add all key features
          size_t j;
          for (j=0; j<crKeyFeatures.size(); ++j) {
            rSerializedCAS.iv_vecComparatorDefinitionTable.push_back( (SerializedCAS::TyNum) crKeyFeatures[j] );
            rSerializedCAS.iv_vecComparatorDefinitionTable.push_back( (SerializedCAS::TyNum) crCompOps[j] );
          }
        }
      }
    }

#ifdef BYEBYEPTRS
    SerializedCAS::TyNum CASSerializer::adjustString(uima::lowlevel::TyHeapCell tyFeatureCell,
        TyStringMap & stringMap,
        uima::internal::SerializedCAS & rSerializedCAS) {
      UIMA_TPRINT("adjustString() entered");
      UChar* * pPointerStringRefHeap = (UChar * *) tyFeatureCell;
      UChar * puc = *pPointerStringRefHeap;
      if (puc == NULL) {
        return 0;
      }
      assert( puc != NULL);
      assert( EXISTS(puc) );
      assert( EXISTS(pPointerStringRefHeap+1) );

      SerializedCAS::TyNum iStrLen = (SerializedCAS::TyNum) * (pPointerStringRefHeap+1);

      ptrdiff_t iStringIndex = 0;

      // try to find the string
      TyStringMap::iterator it = stringMap.lower_bound( puc );
      // if not found
      if (  (it == stringMap.end()) || ( (*it).first != puc ) ) {
        iStringIndex = stringMap.size() + 1;
        // insert new one
        TyStringMap::value_type vt(puc, iStringIndex);
        stringMap.insert(it, vt);
        UIMA_TPRINT("  iStringIndex: " << iStringIndex << ", StringSymblTableSize: " << rSerializedCAS.iv_vecStringSymbolTable.size());
        assert( iStringIndex == rSerializedCAS.iv_vecStringSymbolTable.size() );
        UnicodeStringRef ustrp = createString(puc, iStrLen, rSerializedCAS);
        rSerializedCAS.iv_vecStringSymbolTable.push_back(ustrp);
      } else {
        iStringIndex = (*it).second;
      }

      return iStringIndex;
    }
#endif

    void CASSerializer::serializeFSHeapAndStringHeap(uima::CAS const & crCAS, uima::internal::SerializedCAS & rSerializedCAS) {
      uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(crCAS);
      uima::lowlevel::FSHeap const & crHeap = crCASImpl.getHeap();
      uima::lowlevel::FSHeap::TyFSHeap const & tyTempHeap = crHeap.iv_clTemporaryHeap;

      // copy the FSHeap as is (all offsets and values)
      size_t uiSegmentLength = tyTempHeap.getTopOfHeap();
      uima::lowlevel::TyHeapCell* daHeap = tyTempHeap.getHeapStart();
      rSerializedCAS.iv_vecFSHeapArray.resize(uiSegmentLength);
      // copy the heap (better way to do this?)
      for (size_t i=0; i<uiSegmentLength; i++) {
        rSerializedCAS.iv_vecFSHeapArray[i] = daHeap[i];
      }

      // fill the vector of strings from the StringRefHeap
      uima::lowlevel::FSHeap::TyStringHeap const & tyStringHeap = crHeap.iv_clTemporaryStringHeap;
      uima::lowlevel::FSHeap::TyStringRefHeap const & tyStringRefHeap = crHeap.iv_clTemporaryStringRefHeap;
      int uiStringRefLength = tyStringRefHeap.getTopOfHeap();
      int j = 1; // point at the first entry
      rSerializedCAS.iv_vecStringSymbolTable.resize(1);
      while (j < uiStringRefLength) {
        UnicodeStringRef ustrp = UnicodeStringRef( tyStringHeap.getHeapStart()+
                                 tyStringRefHeap.getHeapValue(j),
                                 (size_t) tyStringRefHeap.getHeapValue(j+1));
        rSerializedCAS.iv_vecStringSymbolTable.push_back(ustrp);
        j += 2;
      }
    }



    void CASSerializer::serializeHeaps(uima::CAS const & crCAS, uima::internal::SerializedCAS & rSerializedCAS) {

      //serialize the fs heap and string heap
      serializeFSHeapAndStringHeap(crCAS, rSerializedCAS);

      uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(crCAS);
      uima::lowlevel::FSHeap const & crHeap = crCASImpl.getHeap();

      //8 bit heap
      uima::lowlevel::FSHeap::Ty8BitHeap const & ty8BitHeap = crHeap.iv_clTemporary8BitHeap;
      size_t uiSegmentLength = ty8BitHeap.getTopOfHeap();
      char* byteHeap = ty8BitHeap.getHeapStart();
      rSerializedCAS.iv_vecByteHeapArray.resize(uiSegmentLength);
      for (size_t i=0; i<uiSegmentLength; i++) {
        rSerializedCAS.iv_vecByteHeapArray[i] = byteHeap[i];
      }

      //16 bit heap
      uima::lowlevel::FSHeap::Ty16BitHeap const & ty16BitHeap = crHeap.iv_clTemporary16BitHeap;
      uiSegmentLength = ty16BitHeap.getTopOfHeap();
      short* shortHeap = ty16BitHeap.getHeapStart();
      rSerializedCAS.iv_vecShortHeapArray.resize(uiSegmentLength);
      for (size_t i=0; i<uiSegmentLength; i++) {
        rSerializedCAS.iv_vecShortHeapArray[i] = shortHeap[i];
      }

      //64 bit heap
      uima::lowlevel::FSHeap::Ty64BitHeap const & ty64BitHeap = crHeap.iv_clTemporary64BitHeap;
      uiSegmentLength = ty64BitHeap.getTopOfHeap();
      INT64* longHeap = ty64BitHeap.getHeapStart();
      rSerializedCAS.iv_vecLongHeapArray.resize(uiSegmentLength);
      for (size_t i=0; i<uiSegmentLength; i++) {
        rSerializedCAS.iv_vecLongHeapArray[i] = longHeap[i];
      }



    }






    //---------------------------------------------------------------------
    // Indexed FS Format
    //
    // Element Size     Number of     Description
    //   (bytes)        Elements
    // ------------     ---------     --------------------------------
    //      4               1         Number of Views in this CAS
    //      4               1         Number of Sofas in base Index Repository = nBase
    //      4             nBase       TyFS array
    //
    //   For each View:
    //      4               1         Number of FS in sofa Index Repository = nFS
    //      4             nFS         TyFS array
    //
    //---------------------------------------------------------------------


    void CASSerializer::serializeIndexedFSs(uima::CAS & crCAS,
                                            vector<uima::internal::SerializedCAS::TyNum> & iv_vecIndexedFSs) {

      uima::internal::CASImpl & crCASImpl = uima::internal::CASImpl::promoteCAS(crCAS);

      int numViews = crCAS.getBaseCas()->iv_sofaCount;
      iv_vecIndexedFSs.clear();
      iv_vecIndexedFSs.push_back(numViews);

      uima::lowlevel::IndexRepository * crIndexRep =
        (uima::lowlevel::IndexRepository*)&crCASImpl.getBaseIndexRepository();

      for (int view=0; view<=numViews; view++) {
        vector<SerializedCAS::TyNum> perLoopIndexedFSs;
        vector<uima::lowlevel::TyFSType> vecAllTypes;
        perLoopIndexedFSs.clear();
        if (view==0) {
          // First time through is for base CAS index
          // FS returned should only be for SofaFS!
          crIndexRep->getUsedIndexes(vecAllTypes);
        } else {
          // for all views found in the CAS, get new IndexRepository
          crIndexRep = crCASImpl.iv_baseCas->iv_sofa2indexMap[view];
          if (crIndexRep == 0) {
            // no indexed FS for this View, move on
            iv_vecIndexedFSs.push_back(0);
            continue;
          }
          crIndexRep->getUsedIndexes(vecAllTypes);

          //serialize the undefined index FSs
          for (size_t i=0;i < crIndexRep->iv_undefinedindex.size(); i++ ) {
            SerializedCAS::TyNum tyFSHeapIndex = (SerializedCAS::TyNum) crIndexRep->iv_undefinedindex[i];
            perLoopIndexedFSs.push_back(tyFSHeapIndex);
          }
        }

        // serialize index per type
        if ( 0 == vecAllTypes.size() && 0 == perLoopIndexedFSs.size() ) {
          // no indexed FS for this View, move on
          iv_vecIndexedFSs.push_back(0);
          continue;
        }
        for (size_t i=0; i<vecAllTypes.size(); ++i) {
          vector<uima::lowlevel::internal::SingleIndex*> const & crSingleIndexes =
            crIndexRep->getAllSingleIndexesForType(vecAllTypes[i]);
          for (size_t j=0; j<crSingleIndexes.size(); ++j) {
            auto_ptr<uima::lowlevel::IndexIterator> apIt(crSingleIndexes[j]->createIterator());
            for (apIt->moveToFirst(); apIt->isValid(); apIt->moveToNext()) {
              uima::lowlevel::TyHeapCell pHeapCell = (uima::lowlevel::TyHeapCell) apIt->get();
              SerializedCAS::TyNum tyFSHeapIndex =  (SerializedCAS::TyNum) pHeapCell;
              perLoopIndexedFSs.push_back( tyFSHeapIndex );
            }
          }
        }

        // eliminate duplicates
        sort(perLoopIndexedFSs.begin(), perLoopIndexedFSs.end());
        vector<SerializedCAS::TyNum>::iterator end = unique(perLoopIndexedFSs.begin(), perLoopIndexedFSs.end());
        // append indexedFSs from this loop
        iv_vecIndexedFSs.push_back(end - perLoopIndexedFSs.begin());
        iv_vecIndexedFSs.insert(iv_vecIndexedFSs.end(),
                                perLoopIndexedFSs.begin(),
                                end);
      }
    }


    /* no more document in de CAS
          void CASSerializer::serializeDocument(uima::TCAS const & crCAS, uima::internal::SerializedCAS & rSerializedCAS) {
             uima::internal::TCASImpl const & crTCASImpl = uima::internal::TCASImpl::promoteCAS(crCAS);
             rSerializedCAS.iv_ulstrDocument = crTCASImpl.getDocumentText();
          }
    */

    void CASSerializer::serializeDefinitions(uima::internal::CASDefinition const & casDef, uima::internal::SerializedCAS & rSerializedCAS) {
      serializeTypeSystem(casDef, rSerializedCAS);
      serializeIndexDefinition(casDef, rSerializedCAS);
    }


#ifdef UIMA_ENABLE_SERIALIZATION_TIMING
#define UIMA_SERIALIZATION_TIMING(x) x
#else
#define UIMA_SERIALIZATION_TIMING(x)
#endif

    void CASSerializer::serializeData(uima::CAS & crCAS, uima::internal::SerializedCAS & rSerializedCAS) {
//         serializeDocument(crCAS, rSerializedCAS);
      // serialize indexed FSs first so that the docAnnot can be created if necessary
      UIMA_TPRINT("Serializing indexed FSs");
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.reset() );
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.start() );
      serializeIndexedFSs(*crCAS.getBaseCas(), rSerializedCAS.iv_vecIndexedFSs);
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.stop() );
      UIMA_TPRINT("indexed FSs serialized");

      UIMA_TPRINT("serializing all heaps");
      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.reset() );
      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.start() );
      //serializeFSHeapAndStringHeap(*crCAS.getBaseCas(), rSerializedCAS);
      serializeHeaps(*crCAS.getBaseCas(), rSerializedCAS);
      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.stop() );
      UIMA_TPRINT("FS heap serialized");
    }

    //---------------------------------------------------------------------
    // Blob Format
    //
    // Element Size     Number of     Description
    //   (bytes)        Elements
    // ------------     ---------     --------------------------------
    //      4               1         Blob key = "UIMA" in utf-8
    //      4               1         Version (currently = 1)
    //      4               1         size of 32-bit FS Heap array = s32H
    //      4             s32H        32-bit FS heap array
    //      4               1         size of 16-bit string Heap array = sSH
    //      2              sSH        16-bit string heap array
    //      4               1         size of string Ref Heap array = sSRH
    //      4             2*sSRH      string ref offsets and lengths
    //      4               1         size of FS index array = sFSI
    //      4             sFSI        FS index array
    //      4               1         size of 8-bit Heap array = s8H
    //      1              s8H        8-bit Heap array
    //      4               1         size of 16-bit Heap array = s16H
    //      2             s16H        16-bit Heap array
    //      4               1         size of 64-bit Heap array = s64H
    //      8             s64H        64-bit Heap array
    //---------------------------------------------------------------------


    // estimate total size of serialized CAS data
    size_t CASSerializer::getBlobSize(uima::CAS & crCAS) {

      // create STL vector of indexed FS so that we can size the output
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.reset() );
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.start() );
      serializeIndexedFSs(*crCAS.getBaseCas(), iv_vecIndexedFSs);
      UIMA_SERIALIZATION_TIMING( iv_timerIndexedFSs.stop() );

      // get a heap of references
      uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(crCAS);
      uima::lowlevel::FSHeap const & crHeap = crCASImpl.getHeap();
      uima::lowlevel::FSHeap::TyFSHeap const & tyTempHeap = crHeap.iv_clTemporaryHeap;
      uima::lowlevel::FSHeap::TyStringHeap const & tyStringHeap = crHeap.iv_clTemporaryStringHeap;
      uima::lowlevel::FSHeap::TyStringRefHeap const & tyStringRefHeap = crHeap.iv_clTemporaryStringRefHeap;
      uima::lowlevel::FSHeap::Ty8BitHeap const & ty8BitHeap = crHeap.iv_clTemporary8BitHeap;
      uima::lowlevel::FSHeap::Ty16BitHeap const & ty16BitHeap = crHeap.iv_clTemporary16BitHeap;
      uima::lowlevel::FSHeap::Ty64BitHeap const & ty64BitHeap = crHeap.iv_clTemporary64BitHeap;

      size_t uiFSHeapLength = tyTempHeap.getTopOfHeap();
      size_t uiStringHeapLength = tyStringHeap.getTopOfHeap();
      size_t uialignedStrLen = 2 * ((uiStringHeapLength + 1)/2);
      size_t uiRefHeapLength = tyStringRefHeap.getTopOfHeap();
      size_t uiIndexedFSLength = iv_vecIndexedFSs.size();
      size_t ui8BitHeapLength = ty8BitHeap.getTopOfHeap();
      size_t uialigned8BitHeapLength = 4 * ((ui8BitHeapLength+3)/4);
      size_t ui16BitHeapLength = ty16BitHeap.getTopOfHeap();
      size_t uialigned16BitHeapLength = 2 * ((ui16BitHeapLength+1)/2);
      size_t ui64BitHeapLength = ty64BitHeap.getTopOfHeap();



      size_t blobSize = 2*4               // key and version
                        + (1 + uiFSHeapLength) * 4        // FSHeap length and data
                        + 1*4 + (uialignedStrLen * 2)  // StringHeap length and data
                        + (1 + uiRefHeapLength) * 4     // StringRefheap length and data
                        + (1 + uiIndexedFSLength) * 4    // Indexed FS length and data
                        + (1*4 + uialigned8BitHeapLength)  // 8 Bit Heap length and data
                        + (1*4 + uialigned16BitHeapLength*2 ) //16 Bit Heap length and data
                        + (1*4 + ui64BitHeapLength*8 );        //64 Bit Heap length and data
      return blobSize;
    }

    // serialize CAS data into single blob format
    size_t CASSerializer::getBlob(uima::CAS & crCAS, void * buffer, size_t maxSize) {

      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.reset() );
      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.start() );

      // get a heap of references
      uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(crCAS);
      uima::lowlevel::FSHeap const & crHeap = crCASImpl.getHeap();
      uima::lowlevel::FSHeap::TyFSHeap const & tyTempHeap = crHeap.iv_clTemporaryHeap;
      uima::lowlevel::FSHeap::TyStringHeap const & tyStringHeap = crHeap.iv_clTemporaryStringHeap;
      uima::lowlevel::FSHeap::TyStringRefHeap const & tyStringRefHeap = crHeap.iv_clTemporaryStringRefHeap;
      uima::lowlevel::FSHeap::Ty8BitHeap const & ty8BitHeap = crHeap.iv_clTemporary8BitHeap;
      uima::lowlevel::FSHeap::Ty16BitHeap const & ty16BitHeap = crHeap.iv_clTemporary16BitHeap;
      uima::lowlevel::FSHeap::Ty64BitHeap const & ty64BitHeap = crHeap.iv_clTemporary64BitHeap;

      size_t uiFSHeapLength = tyTempHeap.getTopOfHeap();
      size_t uiStringHeapLength = tyStringHeap.getTopOfHeap();
      size_t uialignedStrLen = 2 * ((uiStringHeapLength + 1)/2);
      size_t uiRefHeapLength = tyStringRefHeap.getTopOfHeap();
      size_t uiIndexedFSLength = iv_vecIndexedFSs.size();

      size_t ui8BitHeapLength = ty8BitHeap.getTopOfHeap();
      size_t uialigned8BitHeapLength = 4 * ((ui8BitHeapLength+3)/4);
      size_t ui16BitHeapLength = ty16BitHeap.getTopOfHeap();
      size_t uialigned16BitHeapLength = 2 * ((ui16BitHeapLength+1)/2);
      size_t ui64BitHeapLength = ty64BitHeap.getTopOfHeap();

      size_t blobSize = 2*4               // key and version
                        + (1 + uiFSHeapLength) * 4        // FSHeap length and data
                        + 1*4 + (uialignedStrLen * 2)  // StringHeap length and data
                        + (1 + uiRefHeapLength) * 4     // StringRefheap length and data
                        + (1 + uiIndexedFSLength) * 4    // Indexed FS length and data
                        + (1*4 + uialigned8BitHeapLength)  // 8 Bit Heap length and data
                        + (1*4 + uialigned16BitHeapLength*2 ) //16 Bit Heap length and data
                        + (1*4 + ui64BitHeapLength*8 );        //64 Bit Heap length and data


      if (blobSize > maxSize) {
        return 0;             // can't serialize into given buffer
      }

      // copy all data into the blob buffer
      int* intPtr = (int*) buffer;

#if defined(WORDS_BIGENDIAN)
      char key[] = "UIMA";
#else
      char key[] = "AMIU";
#endif
      int version = 1;
      intPtr[0] = ((int*)key)[0];
      intPtr[1] = version;
      intPtr[2] = uiFSHeapLength;
      assert (blobSize > (size_t)((intPtr + 3 + uiFSHeapLength) - (int*)buffer));
      memcpy(intPtr+3, tyTempHeap.getHeapStart(), 4*uiFSHeapLength);
      intPtr += 3 + uiFSHeapLength;

      intPtr[0] = uialignedStrLen;
      assert (blobSize > (size_t)((intPtr + 1 + uiStringHeapLength/2) - (int*)buffer));
      memcpy(intPtr+1, tyStringHeap.getHeapStart(), 2*uiStringHeapLength);
      intPtr += 1 + uialignedStrLen/2;

      intPtr[0] = uiRefHeapLength;
      assert (blobSize > (size_t)((intPtr + 1 + uiRefHeapLength) - (int*)buffer));
      memcpy(intPtr+1, tyStringRefHeap.getHeapStart(), 4*uiRefHeapLength);
      intPtr += 1 + uiRefHeapLength;

      intPtr[0] = uiIndexedFSLength;
      assert (blobSize >= (size_t)((intPtr + 1 + uiIndexedFSLength) - (int*)buffer));
      memcpy(intPtr+1, &iv_vecIndexedFSs[0], 4*uiIndexedFSLength);
      intPtr += 1 + uiIndexedFSLength;

      intPtr[0] = uialigned8BitHeapLength;
      assert (blobSize > (size_t)((intPtr + 1 + uialigned8BitHeapLength/4) - (int*)buffer));
      memcpy(intPtr+1, ty8BitHeap.getHeapStart(), ui8BitHeapLength);
      intPtr += 1 + uialigned8BitHeapLength/4;

      intPtr[0] = uialigned16BitHeapLength;
      assert (blobSize > (size_t)((intPtr + 1 + ui16BitHeapLength/2) - (int*)buffer));
      memcpy(intPtr+1, ty16BitHeap.getHeapStart(), 2*ui16BitHeapLength);
      intPtr += 1 + uialigned16BitHeapLength/2;

      intPtr[0] = ui64BitHeapLength;
      assert (blobSize > (size_t)((intPtr + 1 + ui64BitHeapLength*2) - (int*)buffer));
      memcpy(intPtr+1, ty64BitHeap.getHeapStart(), 8*ui64BitHeapLength);

      UIMA_SERIALIZATION_TIMING( iv_timerFSHeap.stop() );
      return blobSize;
    }




  }

}


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



