void CASDeserializer::deserializeData(uima::internal::SerializedCAS const & crSerializedCAS,
                                          uima::CAS & rCAS) {
      uima::CAS * baseCAS = rCAS.getBaseCas();
      baseCAS->reset();
      deserializeHeapsAndStringTable( crSerializedCAS, *baseCAS );
      deserializeIndexedFSs(CONST_CAST(vector<SerializedCAS::TyNum>&,crSerializedCAS.iv_vecIndexedFSs), *baseCAS);
//         deserializeDocument(crSerializedCAS, rCAS); // do this last because only here is the document annotation created
    }
// for blob deserialization
    void CASDeserializer::deserializeBlob(void * buffer, uima::CAS & rCAS) {
      vector<SerializedCAS::TyNum> iv_vecIndexedFSs;

      // check blob "key" and version
      int* intPtr = (int*) buffer;

      // Check if blob needs byteswap
#if defined(WORDS_BIGENDIAN)
      char key[] = "UIMA";
      char yek[] = "AMIU";
#else
      char key[] = "AMIU";
      char yek[] = "UIMA";
#endif
      if (intPtr[0] == ((int*)yek)[0]) {
        swapBlob(buffer);
      }

      CHECK(intPtr[0] == ((int*)key)[0]);
      CHECK(intPtr[1] == 1);

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



      // deserialize FSHeap
      tyTempHeap.reset();
      size_t uiFSHeapLength = intPtr[2];
      if (uiFSHeapLength > 1) {
        CHECK(intPtr[3] == 0);
        tyTempHeap.increaseHeap(uiFSHeapLength-1);
        memcpy(tyTempHeap.getHeapStart(), intPtr+3, 4*uiFSHeapLength);
      }
      intPtr += 3 + uiFSHeapLength;

      // deserialize StringTable
      tyStringHeap.reset();
      size_t uiStringHeapLength = intPtr[0];
      size_t uialignedStrLen = 2 * ((uiStringHeapLength + 1)/2);
      if (uiStringHeapLength > 1) {
        CHECK(((short*)intPtr)[2] == 0); // check the first short after the length
        tyStringHeap.increaseHeap(uiStringHeapLength-1);
        memcpy(tyStringHeap.getHeapStart(), intPtr+1, 2*uiStringHeapLength);
      }
      intPtr += 1 + uialignedStrLen/2;

      // deserialize StringRef
      tyStringRefHeap.reset();
      size_t uiRefHeapLength = intPtr[0];
      if (uiRefHeapLength > 1) {
        CHECK(intPtr[1] == 0);
        tyStringRefHeap.increaseHeap(uiRefHeapLength-1);
        memcpy(tyStringRefHeap.getHeapStart(), intPtr+1, 4*uiRefHeapLength);
      }
      intPtr += 1 + uiRefHeapLength;

      // create FS indexes
      size_t uiIndexedFSLength = intPtr[0];
      if (uiIndexedFSLength > 0) {
        uima::CAS * baseCAS = rCAS.getBaseCas();
        iv_vecIndexedFSs.resize(uiIndexedFSLength);
        memcpy(&iv_vecIndexedFSs[0], intPtr+1, 4*uiIndexedFSLength);
        deserializeIndexedFSs(iv_vecIndexedFSs, *baseCAS);
      }
      intPtr += 1 + uiIndexedFSLength;

      //8bit heap
      ty8BitHeap.reset();
      size_t ui8BitHeapLength = intPtr[0];
      size_t uialigned8BitHeapLen = 4 * ((ui8BitHeapLength + 3)/4);

      if (ui8BitHeapLength > 1) {
        //CHECK(((char*)intPtr)[1] == 0);
        ty8BitHeap.increaseHeap(ui8BitHeapLength-1);
        memcpy(ty8BitHeap.getHeapStart(), intPtr+1, ui8BitHeapLength);
      }
      intPtr += 1 + uialigned8BitHeapLen/4;

      //16 bit heap
      ty16BitHeap.reset();
      size_t ui16BitHeapLength = intPtr[0];
      size_t uialigned16BitHeapLen = 2 * ((ui16BitHeapLength + 1)/2);
      if (ui16BitHeapLength > 1) {
        //CHECK(((short*)intPtr)[2] == 0);
        ty16BitHeap.increaseHeap(ui16BitHeapLength-1);
        memcpy(ty16BitHeap.getHeapStart(), intPtr+1, 2*ui16BitHeapLength);
      }
      intPtr += 1 + uialigned16BitHeapLen/2;
      //64 bit heap
      ty64BitHeap.reset();
      size_t ui64BitHeapLength = intPtr[0];
      if (ui64BitHeapLength > 0) {
        //CHECK(intPtr[1] == 0);
        ty64BitHeap.increaseHeap(ui64BitHeapLength-1);
        memcpy(ty64BitHeap.getHeapStart(), intPtr+1, 8*ui64BitHeapLength);
      }



    }
    void CASDeserializer::deserializeIndexedFSs(vector<SerializedCAS::TyNum> & crIndexFSs,
        uima::CAS & rCAS) {

      uima::internal::CASImpl & rCASImpl = uima::internal::CASImpl::promoteCAS(rCAS);
      uima::lowlevel::FSHeap & crHeap = rCASImpl.getHeap();
      uima::lowlevel::IndexRepository * crIndexRep = &rCASImpl.getIndexRepository();
      uima::lowlevel::FSHeap::TyFSHeap const & rTempFSHeap = crHeap.iv_clTemporaryHeap;
      SerializedCAS::TyNum iMaxOffset = rTempFSHeap.getTopOfHeap();

      vector<SerializedCAS::TyNum>::const_iterator cit, loopit;
      vector<SerializedCAS::TyNum> perLoopIndexedFSs;
      cit = crIndexFSs.begin();
      int numViews = *cit++;
      int loopSize = *cit;

      crIndexRep->reset();

      // deserialize base CAS
      if (loopSize > 0) {
        lastSegmentUsed = 0;
        perLoopIndexedFSs.insert(perLoopIndexedFSs.end(), cit+1, cit+1+loopSize);
        cit += loopSize + 1;

        for (loopit = perLoopIndexedFSs.begin(); loopit != perLoopIndexedFSs.end(); ++loopit) {
          assert( *loopit < iMaxOffset );
          crIndexRep->add( *loopit );
        }
      }

      // book keeping for all Sofas
      rCAS.getBaseCas()->iv_sofaCount = 1; // reserve for initial view
      FSIndex fsIdx = crIndexRep->getIndex(CAS::INDEXID_SOFA);
      FSIterator fsIt = fsIdx.iterator();
      while (fsIt.isValid()) {
        SofaFS aSofa = (SofaFS) fsIt.get();
        if ( 0 == aSofa.getSofaID().compare(UnicodeString(CAS::NAME_DEFAULT_SOFA)) ) {
          rCAS.registerInitialSofa();
        } else {
          // only bump sofa count if not initial View
          rCAS.bumpSofaCount();
        }
        rCAS.getView(aSofa)->registerView(aSofa);
        fsIt.moveToNext();
      }

      for (int view = 1; view <= numViews; view++) {

        // Check if sofa's index has anything in it
        loopSize = *cit;
        if (0 == loopSize) {
          cit++;
          continue;
        }

        CAS* tcas = rCAS.getViewBySofaNum(view);
        uima::internal::CASImpl & crTCASImpl = uima::internal::CASImpl::promoteCAS(*tcas);
        crIndexRep = &crTCASImpl.getIndexRepository();
        crIndexRep->reset();

        perLoopIndexedFSs.clear();
        perLoopIndexedFSs.insert(perLoopIndexedFSs.end(), cit+1, cit+1+loopSize);
        cit += loopSize + 1;

        for (loopit = perLoopIndexedFSs.begin(); loopit != perLoopIndexedFSs.end(); ++loopit) {
          assert( *loopit < iMaxOffset );
          crIndexRep->add( *loopit );
        }
        tcas->pickupDocumentAnnotation();
      }

    }