ROOT logo
// @(#)root/io:$Id: TKey.cxx 39697 2011-06-13 21:43:43Z pcanal $
// Author: Rene Brun   28/12/94

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  The TKey class includes functions to book space in a file,          //
//   to create I/O buffers, to fill these buffers,                      //
//   to compress/uncompress data buffers.                               //
//                                                                      //
//  Before saving (making persistent) an object in a file, a key must   //
//  be created. The key structure contains all the information to       //
//  uniquely identify a persistent object in a file.                    //
//     fNbytes    = Number of bytes for the compressed object+key       //
//     fObjlen    = Length of uncompressed object                       //
//     fDatime    = Date/Time when the object was written               //
//     fKeylen    = Number of bytes for the key structure               //
//     fCycle     = Cycle number of the object                          //
//     fSeekKey   = Address of the object on file (points to fNbytes)   //
//                  This is a redundant information used to cross-check //
//                  the data base integrity.                            //
//     fSeekPdir  = Pointer to the directory supporting this object     //
//     fClassName = Object class name                                   //
//     fName      = Name of the object                                  //
//     fTitle     = Title of the object                                 //
//                                                                      //
//  In the 16 highest bits of fSeekPdir is encoded a pid offset.  This  //
//  offset is to be added to the pid index stored in the TRef object    //
//  and the referenced TObject.                                         //
//                                                                      //
//  The TKey class is used by ROOT to:                                  //
//    - to write an object in the current directory                     //
//    - to write a new ntuple buffer                                    //
//                                                                      //
//  The structure of a file is shown in TFile::TFile.                   //
//  The structure of a directory is shown in TDirectoryFile ctor.       //
//  The TKey class is used by the TBasket class.                        //
//  See also TTree.                                                     //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "Riostream.h"
#include "TROOT.h"
#include "TClass.h"
#include "TDirectoryFile.h"
#include "TFile.h"
#include "TKey.h"
#include "TBufferFile.h"
#include "TFree.h"
#include "TBrowser.h"
#include "Bytes.h"
#include "TInterpreter.h"
#include "TError.h"
#include "TVirtualStreamerInfo.h"
#include "TSchemaRuleSet.h"

extern "C" void R__zipMultipleAlgorithm(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep, int compressionAlgorithm);
extern "C" void R__unzip(Int_t *nin, UChar_t *bufin, Int_t *lout, char *bufout, Int_t *nout);
extern "C" int R__unzip_header(Int_t *nin, UChar_t *bufin, Int_t *lout);
const Int_t kMAXBUF = 0xffffff;
const Int_t kTitleMax = 32000;
#if 0
const Int_t kMAXFILEBUFFER = 262144;
#endif

#if !defined(_MSC_VER) || (_MSC_VER>1300)
const ULong64_t kPidOffsetMask = 0xffffffffffffULL;
#else
const ULong64_t kPidOffsetMask = 0xffffffffffffUL;
#endif
const UChar_t kPidOffsetShift = 48;

UInt_t keyAbsNumber = 0;

ClassImp(TKey)

//______________________________________________________________________________
TKey::TKey() : TNamed(), fDatime((UInt_t)0)
{
   // TKey default constructor.

   Build(0, "", 0);

   fKeylen     = Sizeof();

   keyAbsNumber++; SetUniqueID(keyAbsNumber);
}

//______________________________________________________________________________
TKey::TKey(TDirectory* motherDir) : TNamed(), fDatime((UInt_t)0)
{
   // TKey default constructor.

   Build(motherDir, "", 0);

   fKeylen     = Sizeof();

   keyAbsNumber++; SetUniqueID(keyAbsNumber);
}

//______________________________________________________________________________
TKey::TKey(Long64_t pointer, Int_t nbytes, TDirectory* motherDir) : TNamed()
{
   // Create a TKey object to read keys.
   // Constructor called by TDirectoryFile::ReadKeys and by TFile::TFile.
   // A TKey object is created to read the keys structure itself.

   Build(motherDir, "", pointer);

   fSeekKey    = pointer;
   fNbytes     = nbytes;
   fBuffer     = new char[nbytes];
   keyAbsNumber++; SetUniqueID(keyAbsNumber);
}

//______________________________________________________________________________
TKey::TKey(const char *name, const char *title, const TClass *cl, Int_t nbytes, TDirectory* motherDir)
      : TNamed(name,title)
{
   // Create a TKey object with the specified name, title for the given class.
   //
   //  WARNING: in name avoid special characters like '^','$','.' that are used 
   //  by the regular expression parser (see TRegexp).

   Build(motherDir, cl->GetName(), -1);

   fKeylen     = Sizeof();
   fObjlen     = nbytes;
   Create(nbytes);
}

//______________________________________________________________________________
TKey::TKey(const TString &name, const TString &title, const TClass *cl, Int_t nbytes, TDirectory* motherDir)
      : TNamed(name,title)
{
   // Create a TKey object with the specified name, title for the given class.
   //
   //  WARNING: in name avoid special characters like '^','$','.' that are used 
   //  by the regular expression parser (see TRegexp).

   Build(motherDir, cl->GetName(), -1);

   fKeylen     = Sizeof();
   fObjlen     = nbytes;
   Create(nbytes);
}

//______________________________________________________________________________
TKey::TKey(const TObject *obj, const char *name, Int_t bufsize, TDirectory* motherDir)
     : TNamed(name, obj->GetTitle())
{
   // Create a TKey object for a TObject* and fill output buffer
   //
   //  WARNING: in name avoid special characters like '^','$','.' that are used 
   //  by the regular expression parser (see TRegexp).

   R__ASSERT(obj);

   if (!obj->IsA()->HasDefaultConstructor()) {
      Warning("TKey", "since %s has no public constructor\n"
              "\twhich can be called without argument, objects of this class\n"
              "\tcan not be read with the current library. You will need to\n"
              "\tadd a default constructor before attempting to read it.",
              obj->ClassName());
   }

   Build(motherDir, obj->ClassName(), -1);

   Int_t lbuf, nout, noutot, bufmax, nzip;
   fBufferRef = new TBufferFile(TBuffer::kWrite, bufsize);
   fBufferRef->SetParent(GetFile());
   fCycle     = fMotherDir->AppendKey(this);

   Streamer(*fBufferRef);         //write key itself
   fKeylen    = fBufferRef->Length();
   fBufferRef->MapObject(obj);    //register obj in map in case of self reference
   ((TObject*)obj)->Streamer(*fBufferRef);    //write object
   lbuf       = fBufferRef->Length();
   fObjlen    = lbuf - fKeylen;

   Int_t cxlevel = GetFile() ? GetFile()->GetCompressionLevel() : 0;
   Int_t cxAlgorithm = GetFile() ? GetFile()->GetCompressionAlgorithm() : 0;
   if (cxlevel > 0 && fObjlen > 256) {
      Int_t nbuffers = 1 + (fObjlen - 1)/kMAXBUF;
      Int_t buflen = TMath::Max(512,fKeylen + fObjlen + 9*nbuffers + 28); //add 28 bytes in case object is placed in a deleted gap
      fBuffer = new char[buflen];
      char *objbuf = fBufferRef->Buffer() + fKeylen;
      char *bufcur = &fBuffer[fKeylen];
      noutot = 0;
      nzip   = 0;
      for (Int_t i = 0; i < nbuffers; ++i) {
         if (i == nbuffers - 1) bufmax = fObjlen - nzip;
         else               bufmax = kMAXBUF;
         R__zipMultipleAlgorithm(cxlevel, &bufmax, objbuf, &bufmax, bufcur, &nout, cxAlgorithm);
         if (nout == 0 || nout >= fObjlen) { //this happens when the buffer cannot be compressed
            fBuffer = fBufferRef->Buffer();
            Create(fObjlen);
            fBufferRef->SetBufferOffset(0);
            Streamer(*fBufferRef);         //write key itself again
            return;
         }
         bufcur += nout;
         noutot += nout;
         objbuf += kMAXBUF;
         nzip   += kMAXBUF;
      }
      Create(noutot);
      fBufferRef->SetBufferOffset(0);
      Streamer(*fBufferRef);         //write key itself again
      memcpy(fBuffer,fBufferRef->Buffer(),fKeylen);
      delete fBufferRef; fBufferRef = 0;
   } else {
      fBuffer = fBufferRef->Buffer();
      Create(fObjlen);
      fBufferRef->SetBufferOffset(0);
      Streamer(*fBufferRef);         //write key itself again
   }
}

//______________________________________________________________________________
TKey::TKey(const void *obj, const TClass *cl, const char *name, Int_t bufsize, TDirectory* motherDir)
     : TNamed(name, "object title")
{
   // Create a TKey object for any object obj of class cl d and fill
   // output buffer.
   //
   //  WARNING: in name avoid special characters like '^','$','.' that are used 
   //  by the regular expression parser (see TRegexp).

   R__ASSERT(obj && cl);

   if (!cl->HasDefaultConstructor()) {
      Warning("TKey", "since %s has no public constructor\n"
              "\twhich can be called without argument, objects of this class\n"
              "\tcan not be read with the current library. You will need to\n"
              "\tadd a default constructor before attempting to read it.",
              cl->GetName());
   }

   TClass *clActual = cl->GetActualClass(obj);
   const void* actualStart;
   if (clActual) {
      const char *temp = (const char*) obj;
      // clActual->GetStreamerInfo();
      Int_t offset = (cl != clActual) ?
                     clActual->GetBaseClassOffset(cl) : 0;
      temp -= offset;
      actualStart = temp;
   } else {
      // We could not determine the real type of this object,
      // let's assume it is the one given by the caller.
      clActual = const_cast<TClass*>(cl);
      actualStart = obj;
   }

   Build(motherDir, clActual->GetName(), -1);

   fBufferRef = new TBufferFile(TBuffer::kWrite, bufsize);
   fBufferRef->SetParent(GetFile());
   fCycle     = fMotherDir->AppendKey(this);

   Streamer(*fBufferRef);         //write key itself
   fKeylen    = fBufferRef->Length();

   Int_t lbuf, nout, noutot, bufmax, nzip;

   fBufferRef->MapObject(actualStart,clActual);         //register obj in map in case of self reference
   clActual->Streamer((void*)actualStart, *fBufferRef); //write object
   lbuf       = fBufferRef->Length();
   fObjlen    = lbuf - fKeylen;

   Int_t cxlevel = GetFile() ? GetFile()->GetCompressionLevel() : 0;
   Int_t cxAlgorithm = GetFile() ? GetFile()->GetCompressionAlgorithm() : 0;
   if (cxlevel > 0 && fObjlen > 256) {
      Int_t nbuffers = 1 + (fObjlen - 1)/kMAXBUF;
      Int_t buflen = TMath::Max(512,fKeylen + fObjlen + 9*nbuffers + 28); //add 28 bytes in case object is placed in a deleted gap
      fBuffer = new char[buflen];
      char *objbuf = fBufferRef->Buffer() + fKeylen;
      char *bufcur = &fBuffer[fKeylen];
      noutot = 0;
      nzip   = 0;
      for (Int_t i = 0; i < nbuffers; ++i) {
         if (i == nbuffers - 1) bufmax = fObjlen - nzip;
         else               bufmax = kMAXBUF;
         R__zipMultipleAlgorithm(cxlevel, &bufmax, objbuf, &bufmax, bufcur, &nout, cxAlgorithm);
         if (nout == 0 || nout >= fObjlen) { //this happens when the buffer cannot be compressed
            fBuffer = fBufferRef->Buffer();
            Create(fObjlen);
            fBufferRef->SetBufferOffset(0);
            Streamer(*fBufferRef);         //write key itself again
            return;
         }
         bufcur += nout;
         noutot += nout;
         objbuf += kMAXBUF;
         nzip   += kMAXBUF;
      }
      Create(noutot);
      fBufferRef->SetBufferOffset(0);
      Streamer(*fBufferRef);         //write key itself again
      memcpy(fBuffer,fBufferRef->Buffer(),fKeylen);
      delete fBufferRef; fBufferRef = 0;
   } else {
      fBuffer = fBufferRef->Buffer();
      Create(fObjlen);
      fBufferRef->SetBufferOffset(0);
      Streamer(*fBufferRef);         //write key itself again
   }
}

//______________________________________________________________________________
void TKey::Build(TDirectory* motherDir, const char* classname, Long64_t filepos)
{
   // method used in all TKey constructor to initialize basic data fields
   // filepos is used to calculate correct version number of key
   // if filepos==-1, end of file position is used

   fMotherDir = motherDir;

   fPidOffset  = 0;
   fNbytes     = 0;
   fBuffer     = 0;
   fKeylen     = 0;
   fObjlen     = 0;
   fBufferRef  = 0;
   fCycle      = 0;
   fSeekPdir   = 0;
   fSeekKey    = 0;
   fLeft       = 0;

   fClassName = classname;
   //the following test required for forward and backward compatibility
   if (fClassName == "TDirectoryFile") fClassName = "TDirectory";

   fVersion = TKey::Class_Version();

   if ((filepos==-1) && GetFile()) filepos = GetFile()->GetEND();
   if (filepos > TFile::kStartBigFile) fVersion += 1000;

   if (fTitle.Length() > kTitleMax) fTitle.Resize(kTitleMax);
}

//______________________________________________________________________________
void TKey::Browse(TBrowser *b)
{
   // Read object from disk and call its Browse() method.
   // If object with same name already exist in memory delete it (like
   // TDirectoryFile::Get() is doing), except when the key references a
   // folder in which case we don't want to re-read the folder object
   // since it might contain new objects not yet saved.

   if (fMotherDir==0) return;

   TClass *objcl = TClass::GetClass(GetClassName());

   void* obj = fMotherDir->GetList()->FindObject(GetName());
   if (obj && objcl->InheritsFrom(TObject::Class())) {
      TObject *tobj = (TObject*)obj;
      if (!tobj->IsFolder()) {
         if (tobj->InheritsFrom(TCollection::Class()))
            tobj->Delete();   // delete also collection elements
         delete tobj;
         obj = 0;
      }
   } 

   if (!obj)
      obj = ReadObj();

   if (b && obj) {
      objcl->Browse(obj,b);
      b->SetRefreshFlag(kTRUE);
   }
}

//______________________________________________________________________________
void TKey::Create(Int_t nbytes, TFile* externFile)
{
   // Create a TKey object of specified size
   // if externFile!=0, key will be allocated in specified file,
   // otherwise file of mother directory will be used

   keyAbsNumber++; SetUniqueID(keyAbsNumber);

   TFile *f = externFile;
   if (!f) f = GetFile();
   if (!f) {
      Error("Create","Cannot create key without file");
      return;
   }

   Int_t nsize      = nbytes + fKeylen;
   TList *lfree     = f->GetListOfFree();
   TFree *f1        = (TFree*)lfree->First();
//*-*-------------------find free segment
//*-*                    =================
   TFree *bestfree  = f1->GetBestFree(lfree,nsize);
   if (bestfree == 0) {
      Error("Create","Cannot allocate %d bytes for ID = %s Title = %s",
            nsize,GetName(),GetTitle());
      return;
   }
   fDatime.Set();
   fSeekKey  = bestfree->GetFirst();
//*-*----------------- Case Add at the end of the file
   if (fSeekKey >= f->GetEND()) {
      f->SetEND(fSeekKey+nsize);
      bestfree->SetFirst(fSeekKey+nsize);
      fLeft   = -1;
      if (!fBuffer) fBuffer = new char[nsize];
   } else {
      fLeft = Int_t(bestfree->GetLast() - fSeekKey - nsize + 1);
   }
//*-*----------------- Case where new object fills exactly a deleted gap
   fNbytes = nsize;
   if (fLeft == 0) {
      if (!fBuffer) {
         fBuffer = new char[nsize];
      }
      lfree->Remove(bestfree);
      delete bestfree;
   }
//*-*----------------- Case where new object is placed in a deleted gap larger than itself
   if (fLeft > 0) {    // found a bigger segment
      if (!fBuffer) {
         fBuffer = new char[nsize+sizeof(Int_t)];
      }
      char *buffer  = fBuffer+nsize;
      Int_t nbytesleft = -fLeft;  // set header of remaining record
      tobuf(buffer, nbytesleft);
      bestfree->SetFirst(fSeekKey+nsize);
   }

   fSeekPdir = externFile ? externFile->GetSeekDir() : fMotherDir->GetSeekDir();
}

//______________________________________________________________________________
TKey::~TKey()
{
   // TKey default destructor.

   //   delete [] fBuffer; fBuffer = 0;
   //   delete fBufferRef; fBufferRef = 0;

   DeleteBuffer();
}

//______________________________________________________________________________
void TKey::Delete(Option_t *option)
{
   // Delete an object from the file.
   // Note: the key is not deleted. You still have to call "delete key".
   // This is different from the behaviour of TObject::Delete()!

   if (option && option[0] == 'v') printf("Deleting key: %s at address %lld, nbytes = %d\n",GetName(),fSeekKey,fNbytes);
   Long64_t first = fSeekKey;
   Long64_t last  = fSeekKey + fNbytes -1;
   if (GetFile()) GetFile()->MakeFree(first, last);  // release space used by this key
   fMotherDir->GetListOfKeys()->Remove(this);
}

//______________________________________________________________________________
void TKey::DeleteBuffer()
{
   // Delete key buffer(s).

   if (fBufferRef) {
      delete fBufferRef;
      fBufferRef = 0;
   } else {
      // We only need to delete fBuffer if fBufferRef is zero because
      // if fBufferRef exists, we delegate ownership of fBuffer to fBufferRef.
      if (fBuffer) {
         delete [] fBuffer;
      }
   }
   fBuffer = 0;
}

//______________________________________________________________________________
Short_t TKey::GetCycle() const
{
   // Return cycle number associated to this key.

   return ((fCycle >0) ? fCycle : -fCycle);
}

//______________________________________________________________________________
TFile *TKey::GetFile() const
{
   // Returns file to which key belong

   return fMotherDir!=0 ? fMotherDir->GetFile() : gFile;
}

//______________________________________________________________________________
Short_t TKey::GetKeep() const
{
   // Returns the "KEEP" status.

   return ((fCycle >0) ? 0 : 1);
}

//______________________________________________________________________________
void TKey::FillBuffer(char *&buffer)
{
   // Encode key header into output buffer.

   tobuf(buffer, fNbytes);
   Version_t version = fVersion;
   tobuf(buffer, version);

   tobuf(buffer, fObjlen);
   fDatime.FillBuffer(buffer);
   tobuf(buffer, fKeylen);
   tobuf(buffer, fCycle);
   if (fVersion > 1000) {
      tobuf(buffer, fSeekKey);

      // We currently store in the 16 highest bit of fSeekPdir the value of
      // fPidOffset.  This offset is used when a key (or basket) is transfered from one
      // file to the other.  In this case the TRef and TObject might have stored a
      // pid index (to retrieve TProcessIDs) which refered to their order on the original
      // file, the fPidOffset is to be added to those values to correctly find the
      // TProcessID.  This fPidOffset needs to be increment if the key/basket is copied
      // and need to be zero for new key/basket.
      Long64_t pdir = (((Long64_t)fPidOffset)<<kPidOffsetShift) | (kPidOffsetMask & fSeekPdir);
      tobuf(buffer, pdir);
   } else {
      tobuf(buffer, (Int_t)fSeekKey);
      tobuf(buffer, (Int_t)fSeekPdir);
   }
   fClassName.FillBuffer(buffer);
   fName.FillBuffer(buffer);
   fTitle.FillBuffer(buffer);
}

//______________________________________________________________________________
ULong_t TKey::Hash() const
{
   // This Hash function should redefine the default from TNamed.

   return TNamed::Hash();
}

//______________________________________________________________________________
void TKey::IncrementPidOffset(UShort_t offset)
{
   // Increment fPidOffset by 'offset'.
   // This offset is used when a key (or basket) is transfered from one file to
   // the other.  In this case the TRef and TObject might have stored a pid
   // index (to retrieve TProcessIDs) which refered to their order on the
   // original file, the fPidOffset is to be added to those values to correctly
   // find the TProcessID.  This fPidOffset needs to be increment if the
   // key/basket is copied and need to be zero for new key/basket.

   fPidOffset += offset;
   if (fPidOffset) {
      // We currently store fPidOffset in the 16 highest bit of fSeekPdir, which
      // need to be store as a 64 bit integer.  So we require this key to be
      // a 'large file' key.
      if (fVersion<1000) fVersion += 1000;
   }
}

//______________________________________________________________________________
Bool_t TKey::IsFolder() const
{
   // Check if object referenced by the key is a folder.

   Bool_t ret = kFALSE;

   TClass *classPtr = TClass::GetClass((const char *) fClassName);
   if (classPtr && classPtr->GetClassInfo() && classPtr->InheritsFrom(TObject::Class())) {
      TObject *obj = (TObject *) classPtr->New(TClass::kDummyNew);
      if (obj) {
         ret = obj->IsFolder();
         delete obj;
      }
   }

   return ret;
}

//______________________________________________________________________________
void TKey::Keep()
{
   // Set the "KEEP" status.
   // When the KEEP flag is set to 1 the object cannot be purged.

   if (fCycle >0)  fCycle = -fCycle;
}

//______________________________________________________________________________
void TKey::ls(Option_t *) const
{
   // List Key contents.

   TROOT::IndentLevel();
   cout <<"KEY: "<<fClassName<<"\t"<<GetName()<<";"<<GetCycle()<<"\t"<<GetTitle()<<endl;
}

//______________________________________________________________________________
void TKey::Print(Option_t *) const
{
   // Print key contents.

   printf("TKey Name = %s, Title = %s, Cycle = %d\n",GetName(),GetTitle(),GetCycle());
}

//______________________________________________________________________________
TObject *TKey::ReadObj()
{
   // To read a TObject* from the file.
   //
   //  The object associated to this key is read from the file into memory
   //  Once the key structure is read (via Streamer) the class identifier
   //  of the object is known.
   //  Using the class identifier we find the TClass object for this class.
   //  A TClass object contains a full description (i.e. dictionary) of the
   //  associated class. In particular the TClass object can create a new
   //  object of the class type it describes. This new object now calls its
   //  Streamer function to rebuilt itself.
   //
   //  see TKey::ReadObjectAny to read any object non-derived from TObject
   //
   //  NOTE:
   //  In case the class of this object derives from TObject but not
   //  as a first inheritance, one must cast the return value twice.
   //  Example1: Normal case:
   //      class MyClass : public TObject, public AnotherClass
   //   then on return, one can do:
   //    MyClass *obj = (MyClass*)key->ReadObj();
   //
   //  Example2: Special case:
   //      class MyClass : public AnotherClass, public TObject
   //   then on return, one must do:
   //    MyClass *obj = dynamic_cast<MyClass*>(key->ReadObj());
   //
   //  Of course, dynamic_cast<> can also be used in the example 1.

   TClass *cl = TClass::GetClass(fClassName.Data());
   if (!cl) {
      Error("ReadObj", "Unknown class %s", fClassName.Data());
      return 0;
   }
   if (!cl->InheritsFrom(TObject::Class())) {
      // in principle user should call TKey::ReadObjectAny!
      return (TObject*)ReadObjectAny(0);
   }

   fBufferRef = new TBufferFile(TBuffer::kRead, fObjlen+fKeylen);
   if (!fBufferRef) {
      Error("ReadObj", "Cannot allocate buffer: fObjlen = %d", fObjlen);
      return 0;
   }
   if (GetFile()==0) return 0;
   fBufferRef->SetParent(GetFile());
   fBufferRef->SetPidOffset(fPidOffset);

   if (fObjlen > fNbytes-fKeylen) {
      fBuffer = new char[fNbytes];
      if( !ReadFile() )                    //Read object structure from file
      {
        delete fBufferRef;
        delete [] fBuffer;
        fBufferRef = 0;
        fBuffer = 0;
        return 0;
      }
      memcpy(fBufferRef->Buffer(),fBuffer,fKeylen);
   } else {
      fBuffer = fBufferRef->Buffer();
      if( !ReadFile() ) {                   //Read object structure from file
         delete fBufferRef;
         fBufferRef = 0;
         fBuffer = 0;
         return 0;
      }
   }

   // get version of key
   fBufferRef->SetBufferOffset(sizeof(fNbytes));
   Version_t kvers = fBufferRef->ReadVersion();

   fBufferRef->SetBufferOffset(fKeylen);
   TObject *tobj = 0;
   // Create an instance of this class

   char *pobj = (char*)cl->New();
   Int_t baseOffset = cl->GetBaseClassOffset(TObject::Class());
   if (baseOffset==-1) {
      // cl does not inherit from TObject.
      // Since this is not possible yet, the only reason we could reach this code
      // is because something is screw up in the ROOT code.
      Fatal("ReadObj","Incorrect detection of the inheritance from TObject for class %s.\n",
            fClassName.Data());
   }
   tobj = (TObject*)(pobj+baseOffset);
   if (!pobj) {
      Error("ReadObj", "Cannot create new object of class %s", fClassName.Data());
      return 0;
   }
   if (kvers > 1)
      fBufferRef->MapObject(pobj,cl);  //register obj in map to handle self reference

   if (fObjlen > fNbytes-fKeylen) {
      char *objbuf = fBufferRef->Buffer() + fKeylen;
      UChar_t *bufcur = (UChar_t *)&fBuffer[fKeylen];
      Int_t nin, nout, nbuf;
      Int_t noutot = 0;
      while (1) {
         Int_t hc = R__unzip_header(&nin, bufcur, &nbuf);
         if (hc!=0) break;
         R__unzip(&nin, bufcur, &nbuf, objbuf, &nout);
         if (!nout) break;
         noutot += nout;
         if (noutot >= fObjlen) break;
         bufcur += nin;
         objbuf += nout;
      }
      if (nout) {
         tobj->Streamer(*fBufferRef); //does not work with example 2 above
         delete [] fBuffer;
      } else {
         delete [] fBuffer;
         delete pobj;
         pobj = 0;
         tobj = 0;
         goto CLEAR;
      }
   } else {
      tobj->Streamer(*fBufferRef);
   }

   if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();

   if (cl->InheritsFrom(TDirectoryFile::Class())) {
      TDirectory *dir = static_cast<TDirectoryFile*>(tobj);
      dir->SetName(GetName());
      dir->SetTitle(GetTitle());
      dir->SetMother(fMotherDir);
      fMotherDir->Append(dir);
   }

   // Append the object to the directory if requested:
   { 
      ROOT::DirAutoAdd_t addfunc = cl->GetDirectoryAutoAdd();
      if (addfunc) {
         addfunc(pobj, fMotherDir);
      }
   }

CLEAR:
   delete fBufferRef;
   fBufferRef = 0;
   fBuffer    = 0;

   return tobj;
}

//______________________________________________________________________________
TObject *TKey::ReadObjWithBuffer(char *bufferRead)
{
   // To read a TObject* from bufferRead.
   // This function is identical to TKey::ReadObj, but it reads directly
   // from bufferRead instead of reading from a file.
   //  The object associated to this key is read from the buffer into memory
   //  Using the class identifier we find the TClass object for this class.
   //  A TClass object contains a full description (i.e. dictionary) of the
   //  associated class. In particular the TClass object can create a new
   //  object of the class type it describes. This new object now calls its
   //  Streamer function to rebuilt itself.
   //
   //  NOTE :
   //  This function is called only internally by ROOT classes.
   //  Although being public it is not supposed to be used outside ROOT.
   //  If used, you must make sure that the bufferRead is large enough to
   //  accomodate the object being read.
   

   TClass *cl = TClass::GetClass(fClassName.Data());
   if (!cl) {
      Error("ReadObjWithBuffer", "Unknown class %s", fClassName.Data());
      return 0;
   }
   if (!cl->InheritsFrom(TObject::Class())) {
      // in principle user should call TKey::ReadObjectAny!
      return (TObject*)ReadObjectAny(0);
   }

   fBufferRef = new TBufferFile(TBuffer::kRead, fObjlen+fKeylen);
   if (!fBufferRef) {
      Error("ReadObjWithBuffer", "Cannot allocate buffer: fObjlen = %d", fObjlen);
      return 0;
   }
   if (GetFile()==0) return 0;
   fBufferRef->SetParent(GetFile());
   fBufferRef->SetPidOffset(fPidOffset);

   if (fObjlen > fNbytes-fKeylen) {
      fBuffer = bufferRead;
      memcpy(fBufferRef->Buffer(),fBuffer,fKeylen);
   } else {
      fBuffer = fBufferRef->Buffer();
      ReadFile();                    //Read object structure from file
   }

   // get version of key
   fBufferRef->SetBufferOffset(sizeof(fNbytes));
   Version_t kvers = fBufferRef->ReadVersion();

   fBufferRef->SetBufferOffset(fKeylen);
   TObject *tobj = 0;
   // Create an instance of this class

   char *pobj = (char*)cl->New();
   Int_t baseOffset = cl->GetBaseClassOffset(TObject::Class());
   if (baseOffset==-1) {
      // cl does not inherit from TObject.
      // Since this is not possible yet, the only reason we could reach this code
      // is because something is screw up in the ROOT code.
      Fatal("ReadObjWithBuffer","Incorrect detection of the inheritance from TObject for class %s.\n",
            fClassName.Data());
   }
   tobj = (TObject*)(pobj+baseOffset);
   if (!pobj) {
      Error("ReadObjWithBuffer", "Cannot create new object of class %s", fClassName.Data());
      return 0;
   }
   if (kvers > 1)
      fBufferRef->MapObject(pobj,cl);  //register obj in map to handle self reference

   if (fObjlen > fNbytes-fKeylen) {
      char *objbuf = fBufferRef->Buffer() + fKeylen;
      UChar_t *bufcur = (UChar_t *)&fBuffer[fKeylen];
      Int_t nin, nout, nbuf;
      Int_t noutot = 0;
      while (1) {
         Int_t hc = R__unzip_header(&nin, bufcur, &nbuf);
         if (hc!=0) break;
         R__unzip(&nin, bufcur, &nbuf, objbuf, &nout);
         if (!nout) break;
         noutot += nout;
         if (noutot >= fObjlen) break;
         bufcur += nin;
         objbuf += nout;
      }
      if (nout) {
         tobj->Streamer(*fBufferRef); //does not work with example 2 above
      } else {
         delete pobj;
         pobj = 0;
         tobj = 0;
         goto CLEAR;
      }
   } else {
      tobj->Streamer(*fBufferRef);
   }

   if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();

   if (cl->InheritsFrom(TDirectoryFile::Class())) {
      TDirectory *dir = static_cast<TDirectoryFile*>(tobj);
      dir->SetName(GetName());
      dir->SetTitle(GetTitle());
      dir->SetMother(fMotherDir);
      fMotherDir->Append(dir);
   }

   // Append the object to the directory if requested:
   { 
      ROOT::DirAutoAdd_t addfunc = cl->GetDirectoryAutoAdd();
      if (addfunc) {
         addfunc(pobj, fMotherDir);
      }
   }

CLEAR:
   delete fBufferRef;
   fBufferRef = 0;
   fBuffer    = 0;

   return tobj;
}

//______________________________________________________________________________
void *TKey::ReadObjectAny(const TClass* expectedClass)
{
   //  To read an object (non deriving from TObject) from the file.
   //
   //  If expectedClass is not null, we checked that that actual class of
   //  the object stored is suitable to be stored in a pointer pointing
   //  to an object of class 'expectedClass'.  We also adjust the value
   //  of the returned address so that it is suitable to be cast (C-Style)
   //  a  a pointer pointing to an object of class 'expectedClass'.
   //
   //  So for example if the class Bottom inherits from Top and the object
   //  stored is of type Bottom you can safely do:
   //
   //     TClass *TopClass = TClass::GetClass("Top");
   //     Top *ptr = (Top*) key->ReadObjectAny( TopClass );
   //     if (ptr==0) printError("the object stored in the key is not of the expected type\n");
   //
   //  The object associated to this key is read from the file into memory
   //  Once the key structure is read (via Streamer) the class identifier
   //  of the object is known.
   //  Using the class identifier we find the TClass object for this class.
   //  A TClass object contains a full description (i.e. dictionary) of the
   //  associated class. In particular the TClass object can create a new
   //  object of the class type it describes. This new object now calls its
   //  Streamer function to rebuilt itself.

   fBufferRef = new TBufferFile(TBuffer::kRead, fObjlen+fKeylen);
   if (!fBufferRef) {
      Error("ReadObj", "Cannot allocate buffer: fObjlen = %d", fObjlen);
      return 0;
   }
   if (GetFile()==0) return 0;
   fBufferRef->SetParent(GetFile());
   fBufferRef->SetPidOffset(fPidOffset);

   if (fObjlen > fNbytes-fKeylen) {
      fBuffer = new char[fNbytes];
      ReadFile();                    //Read object structure from file
      memcpy(fBufferRef->Buffer(),fBuffer,fKeylen);
   } else {
      fBuffer = fBufferRef->Buffer();
      ReadFile();                    //Read object structure from file
   }

   // get version of key
   fBufferRef->SetBufferOffset(sizeof(fNbytes));
   Version_t kvers = fBufferRef->ReadVersion();

   fBufferRef->SetBufferOffset(fKeylen);
   TClass *cl = TClass::GetClass(fClassName.Data());
   TClass *clOnfile = 0;
   if (!cl) {
      Error("ReadObjectAny", "Unknown class %s", fClassName.Data());
      return 0;
   }
   Int_t baseOffset = 0;
   if (expectedClass) {
       // baseOffset will be -1 if cl does not inherit from expectedClass
      baseOffset = cl->GetBaseClassOffset(expectedClass);
      if (baseOffset == -1) {
         // The 2 classes are unrelated, maybe there is a converter between the 2.  

         if (!expectedClass->GetSchemaRules() || 
             !expectedClass->GetSchemaRules()->HasRuleWithSourceClass(cl->GetName())) 
         {
            // There is no converter
            return 0;
         }
         baseOffset = 0; // For now we do not support requesting from a class that is the base of one of the class for which there is transformation to ....
         clOnfile = cl;
         cl = const_cast<TClass*>(expectedClass);
         Info("ReadObjectAny","Using Converter StreamerInfo from %s to %s",clOnfile->GetName(),expectedClass->GetName());
      }
      if (cl->GetClassInfo() && !expectedClass->GetClassInfo()) {
         //we cannot mix a compiled class with an emulated class in the inheritance
         Warning("ReadObjectAny",
                 "Trying to read an emulated class (%s) to store in a compiled pointer (%s)",
                 cl->GetName(),expectedClass->GetName());
      }
   }
   // Create an instance of this class

   void *pobj = cl->New();
   if (!pobj) {
      Error("ReadObjectAny", "Cannot create new object of class %s", fClassName.Data());
      return 0;
   }

   if (kvers > 1)
      fBufferRef->MapObject(pobj,cl);  //register obj in map to handle self reference

   if (fObjlen > fNbytes-fKeylen) {
      char *objbuf = fBufferRef->Buffer() + fKeylen;
      UChar_t *bufcur = (UChar_t *)&fBuffer[fKeylen];
      Int_t nin, nout, nbuf;
      Int_t noutot = 0;
      while (1) {
         Int_t hc = R__unzip_header(&nin, bufcur, &nbuf);
         if (hc!=0) break;
         R__unzip(&nin, bufcur, &nbuf, objbuf, &nout);
         if (!nout) break;
         noutot += nout;
         if (noutot >= fObjlen) break;
         bufcur += nin;
         objbuf += nout;
      }
      if (nout) {
         cl->Streamer((void*)pobj, *fBufferRef, clOnfile);    //read object
         delete [] fBuffer;
      } else {
         delete [] fBuffer;
         cl->Destructor(pobj);
         pobj = 0;
         goto CLEAR;
      }
   } else {
      cl->Streamer((void*)pobj, *fBufferRef, clOnfile);    //read object
   }

   if (cl->InheritsFrom(TObject::Class())) {
      baseOffset = cl->GetBaseClassOffset(TObject::Class());
      if (baseOffset==-1) {
         Fatal("ReadObj","Incorrect detection of the inheritance from TObject for class %s.\n",
            fClassName.Data());
      }
      TObject *tobj = (TObject*)( ((char*)pobj) +baseOffset);

      // See similar adjustments in ReadObj
      if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();

      if (cl->InheritsFrom(TDirectoryFile::Class())) {
         TDirectory *dir = static_cast<TDirectoryFile*>(tobj);
         dir->SetName(GetName());
         dir->SetTitle(GetTitle());
         dir->SetMother(fMotherDir);
         fMotherDir->Append(dir);
      }
   }

   {
      // Append the object to the directory if requested:
      ROOT::DirAutoAdd_t addfunc = cl->GetDirectoryAutoAdd();
      if (addfunc) {
         addfunc(pobj, fMotherDir);
      }
   }

   CLEAR:
   delete fBufferRef;
   fBufferRef = 0;
   fBuffer    = 0;

   return ( ((char*)pobj) + baseOffset );
}

//______________________________________________________________________________
Int_t TKey::Read(TObject *obj)
{
   // To read an object from the file.
   // The object associated to this key is read from the file into memory.
   // Before invoking this function, obj has been created via the
   // default constructor.

   if (!obj || (GetFile()==0)) return 0;

   fBufferRef = new TBufferFile(TBuffer::kRead, fObjlen+fKeylen);
   fBufferRef->SetParent(GetFile());
   fBufferRef->SetPidOffset(fPidOffset);

   if (fVersion > 1)
      fBufferRef->MapObject(obj);  //register obj in map to handle self reference

   if (fObjlen > fNbytes-fKeylen) {
      fBuffer = new char[fNbytes];
      ReadFile();                    //Read object structure from file
      memcpy(fBufferRef->Buffer(),fBuffer,fKeylen);
   } else {
      fBuffer = fBufferRef->Buffer();
      ReadFile();                    //Read object structure from file
   }
   fBufferRef->SetBufferOffset(fKeylen);
   if (fObjlen > fNbytes-fKeylen) {
      char *objbuf = fBufferRef->Buffer() + fKeylen;
      UChar_t *bufcur = (UChar_t *)&fBuffer[fKeylen];
      Int_t nin, nout, nbuf;
      Int_t noutot = 0;
      while (1) {
         Int_t hc = R__unzip_header(&nin, bufcur, &nbuf);
         if (hc!=0) break;
         R__unzip(&nin, bufcur, &nbuf, objbuf, &nout);
         if (!nout) break;
         noutot += nout;
         if (noutot >= fObjlen) break;
         bufcur += nin;
         objbuf += nout;
      }
      if (nout) obj->Streamer(*fBufferRef);
      delete [] fBuffer;
   } else {
      obj->Streamer(*fBufferRef);
   }

   // Append the object to the directory if requested:
   { 
      ROOT::DirAutoAdd_t addfunc = obj->IsA()->GetDirectoryAutoAdd();
      if (addfunc) {
         addfunc(obj, fMotherDir);
      }
   }

   delete fBufferRef;
   fBufferRef = 0;
   fBuffer    = 0;
   return fNbytes;
}

//______________________________________________________________________________
void TKey::ReadBuffer(char *&buffer)
{
   // Decode input buffer.
   // In some situation will add key to gDirectory ???

   ReadKeyBuffer(buffer);

   if (!gROOT->ReadingObject() && gDirectory) {
      if (fSeekPdir != gDirectory->GetSeekDir()) gDirectory->AppendKey(this);
   }
}

//______________________________________________________________________________
void TKey::ReadKeyBuffer(char *&buffer)
{
   // Decode input buffer.

   frombuf(buffer, &fNbytes);
   Version_t version;
   frombuf(buffer,&version);
   fVersion = (Int_t)version;
   frombuf(buffer, &fObjlen);
   fDatime.ReadBuffer(buffer);
   frombuf(buffer, &fKeylen);
   frombuf(buffer, &fCycle);
   if (fVersion > 1000) {
      frombuf(buffer, &fSeekKey);

      // We currently store in the 16 highest bit of fSeekPdir the value of
      // fPidOffset.  This offset is used when a key (or basket) is transfered from one
      // file to the other.  In this case the TRef and TObject might have stored a
      // pid index (to retrieve TProcessIDs) which refered to their order on the original
      // file, the fPidOffset is to be added to those values to correctly find the
      // TProcessID.  This fPidOffset needs to be increment if the key/basket is copied
      // and need to be zero for new key/basket.
      Long64_t pdir;
      frombuf(buffer, &pdir);
      fPidOffset = pdir >> kPidOffsetShift;
      fSeekPdir = pdir & kPidOffsetMask;
   } else {
      Int_t seekkey,seekdir;
      frombuf(buffer, &seekkey); fSeekKey = (Long64_t)seekkey;
      frombuf(buffer, &seekdir); fSeekPdir= (Long64_t)seekdir;
   }
   fClassName.ReadBuffer(buffer);
   //the following test required for forward and backward compatibility
   if (fClassName == "TDirectory") fClassName = "TDirectoryFile";

   fName.ReadBuffer(buffer);
   fTitle.ReadBuffer(buffer);
}

//______________________________________________________________________________
Bool_t TKey::ReadFile()
{
   // Read the key structure from the file

   TFile* f = GetFile();
   if (f==0) return kFALSE;

   Int_t nsize = fNbytes;
   f->Seek(fSeekKey);
#if 0
   for (Int_t i = 0; i < nsize; i += kMAXFILEBUFFER) {
      int nb = kMAXFILEBUFFER;
      if (i+nb > nsize) nb = nsize - i;
      f->ReadBuffer(fBuffer+i,nb);
   }
#else
   if( f->ReadBuffer(fBuffer,nsize) )
   {
      Error("ReadFile", "Failed to read data.");
      return kFALSE;
   }
#endif
   if (gDebug) {
      cout << "TKey Reading "<<nsize<< " bytes at address "<<fSeekKey<<endl;
   }
   return kTRUE;
}

//______________________________________________________________________________
void TKey::SetParent(const TObject *parent)
{
   // Set parent in key buffer.

   if (fBufferRef) fBufferRef->SetParent((TObject*)parent);
}

//______________________________________________________________________________
void TKey::Reset()
{
   // Reset the key as it had not been 'filled' yet.
   
   fPidOffset  = 0;
   fNbytes     = 0;
   fBuffer     = 0;
   fObjlen     = 0;
   fCycle      = 0;
   fSeekPdir   = 0;
   fSeekKey    = 0;
   fLeft       = 0;
   fDatime     = (UInt_t)0;

   // fBufferRef and fKeylen intentionally not reset/changed
   
   keyAbsNumber++; SetUniqueID(keyAbsNumber);   
}

//______________________________________________________________________________
Int_t TKey::Sizeof() const
{
   // Return the size in bytes of the key header structure.
   // Int_t nbytes = sizeof fNbytes;      4
   //             += sizeof(Version_t);   2
   //             += sizeof fObjlen;      4
   //             += sizeof fKeylen;      2
   //             += sizeof fCycle;       2
   //             += sizeof fSeekKey;     4 or 8
   //             += sizeof fSeekPdir;    4 or 8
   //              =                     22

   Int_t nbytes = 22; if (fVersion > 1000) nbytes += 8;
   nbytes      += fDatime.Sizeof();
   nbytes      += fClassName.Sizeof();
   nbytes      += fName.Sizeof();
   nbytes      += fTitle.Sizeof();
   return nbytes;
}

//_______________________________________________________________________
void TKey::Streamer(TBuffer &b)
{
   // Stream a class object.

   Version_t version;
   if (b.IsReading()) {
      b >> fNbytes;
      b >> version; fVersion = (Int_t)version;
      b >> fObjlen;
      fDatime.Streamer(b);
      b >> fKeylen;
      b >> fCycle;
      if (fVersion > 1000) {
         b >> fSeekKey;

         // We currently store in the 16 highest bit of fSeekPdir the value of
         // fPidOffset.  This offset is used when a key (or basket) is transfered from one
         // file to the other.  In this case the TRef and TObject might have stored a
         // pid index (to retrieve TProcessIDs) which refered to their order on the original
         // file, the fPidOffset is to be added to those values to correctly find the
         // TProcessID.  This fPidOffset needs to be increment if the key/basket is copied
         // and need to be zero for new key/basket.
         Long64_t pdir;
         b >> pdir;
         fPidOffset = pdir >> kPidOffsetShift;
         fSeekPdir = pdir & kPidOffsetMask;
      } else {
         Int_t seekkey, seekdir;
         b >> seekkey; fSeekKey = (Long64_t)seekkey;
         b >> seekdir; fSeekPdir= (Long64_t)seekdir;
      }
      fClassName.Streamer(b);
      fName.Streamer(b);
      fTitle.Streamer(b);
      if (fKeylen < 0) {
         Error("Streamer","The value of fKeylen is incorrect (%d) ; trying to recover by setting it to zero",fKeylen);
         MakeZombie();
         fKeylen = 0;
      }
      if (fObjlen < 0) {
         Error("Streamer","The value of fObjlen is incorrect (%d) ; trying to recover by setting it to zero",fObjlen);
         MakeZombie();
         fObjlen = 0;
      }
      if (fNbytes < 0) {
         Error("Streamer","The value of fNbytes is incorrect (%d) ; trying to recover by setting it to zero",fNbytes);
         MakeZombie();
         fNbytes = 0;
      }
      
         
   } else {
      b << fNbytes;
      version = (Version_t)fVersion;
      b << version;
      b << fObjlen;
      if (fDatime.Get() == 0) fDatime.Set();
      fDatime.Streamer(b);
      b << fKeylen;
      b << fCycle;
      if (fVersion > 1000) {
         b << fSeekKey;

         // We currently store in the 16 highest bit of fSeekPdir the value of
         // fPidOffset.  This offset is used when a key (or basket) is transfered from one
         // file to the other.  In this case the TRef and TObject might have stored a
         // pid index (to retrieve TProcessIDs) which refered to their order on the original
         // file, the fPidOffset is to be added to those values to correctly find the
         // TProcessID.  This fPidOffset needs to be increment if the key/basket is copied
         // and need to be zero for new key/basket.
         Long64_t pdir = (((Long64_t)fPidOffset)<<kPidOffsetShift) | (kPidOffsetMask & fSeekPdir);
         b << pdir;
      } else {
         b << (Int_t)fSeekKey;
         b << (Int_t)fSeekPdir;
      }
      fClassName.Streamer(b);
      fName.Streamer(b);
      fTitle.Streamer(b);
   }
}

//______________________________________________________________________________
Int_t TKey::WriteFile(Int_t cycle, TFile* f)
{
   // Write the encoded object supported by this key.
   // The function returns the number of bytes committed to the file.
   // If a write error occurs, the number of bytes returned is -1.

   if (!f) f = GetFile();
   if (!f) return -1;

   Int_t nsize  = fNbytes;
   char *buffer = fBuffer;
   if (cycle) {
      fCycle = cycle;
      FillBuffer(buffer);
      buffer = fBuffer;
   }

   if (fLeft > 0) nsize += sizeof(Int_t);
   f->Seek(fSeekKey);
#if 0
   for (Int_t i=0;i<nsize;i+=kMAXFILEBUFFER) {
      Int_t nb = kMAXFILEBUFFER;
      if (i+nb > nsize) nb = nsize - i;
      f->WriteBuffer(buffer,nb);
      buffer += nb;
   }
#else
   Bool_t result = f->WriteBuffer(buffer,nsize);
#endif
   //f->Flush(); Flushing takes too much time.
   //            Let user flush the file when he wants.
   if (gDebug) {
      cout <<"   TKey Writing "<<nsize<< " bytes at address "<<fSeekKey
           <<" for ID= " <<GetName()<<" Title= "<<GetTitle()<<endl;
   }

   DeleteBuffer();
   return result==kTRUE ? -1 : nsize;
}

//______________________________________________________________________________
Int_t TKey::WriteFileKeepBuffer(TFile *f)
{
   // Write the encoded object supported by this key.
   // The function returns the number of bytes committed to the file.
   // If a write error occurs, the number of bytes returned is -1.
   
   if (!f) f = GetFile();
   if (!f) return -1;
   
   Int_t nsize  = fNbytes;
   char *buffer = fBuffer;
   
   if (fLeft > 0) nsize += sizeof(Int_t);
   f->Seek(fSeekKey);
#if 0
   for (Int_t i=0;i<nsize;i+=kMAXFILEBUFFER) {
      Int_t nb = kMAXFILEBUFFER;
      if (i+nb > nsize) nb = nsize - i;
      f->WriteBuffer(buffer,nb);
      buffer += nb;
   }
#else
   Bool_t result = f->WriteBuffer(buffer,nsize);
#endif
   //f->Flush(); Flushing takes too much time.
   //            Let user flush the file when he wants.
   if (gDebug) {
      cout <<"   TKey Writing "<<nsize<< " bytes at address "<<fSeekKey
      <<" for ID= " <<GetName()<<" Title= "<<GetTitle()<<endl;
   }
   
   return result==kTRUE ? -1 : nsize;
}

//______________________________________________________________________________
const char *TKey::GetIconName() const
{
   // Title can keep 32x32 xpm thumbnail/icon of the parent object.

   return (!fTitle.IsNull() && fTitle.BeginsWith("/* ") ?  fTitle.Data() : 0);
}

//______________________________________________________________________________
const char *TKey::GetTitle() const
{
   // Returns title (title can contain 32x32 xpm thumbnail/icon).

   if (!fTitle.IsNull() && fTitle.BeginsWith("/* ")) { // title contains xpm thumbnail
      static TString ret;
      int start = fTitle.Index("/*") + 3;
      int stop = fTitle.Index("*/") - 1;
      ret = fTitle(start, stop - start);
      return ret.Data();
   }
   return fTitle.Data();
}
 TKey.cxx:1
 TKey.cxx:2
 TKey.cxx:3
 TKey.cxx:4
 TKey.cxx:5
 TKey.cxx:6
 TKey.cxx:7
 TKey.cxx:8
 TKey.cxx:9
 TKey.cxx:10
 TKey.cxx:11
 TKey.cxx:12
 TKey.cxx:13
 TKey.cxx:14
 TKey.cxx:15
 TKey.cxx:16
 TKey.cxx:17
 TKey.cxx:18
 TKey.cxx:19
 TKey.cxx:20
 TKey.cxx:21
 TKey.cxx:22
 TKey.cxx:23
 TKey.cxx:24
 TKey.cxx:25
 TKey.cxx:26
 TKey.cxx:27
 TKey.cxx:28
 TKey.cxx:29
 TKey.cxx:30
 TKey.cxx:31
 TKey.cxx:32
 TKey.cxx:33
 TKey.cxx:34
 TKey.cxx:35
 TKey.cxx:36
 TKey.cxx:37
 TKey.cxx:38
 TKey.cxx:39
 TKey.cxx:40
 TKey.cxx:41
 TKey.cxx:42
 TKey.cxx:43
 TKey.cxx:44
 TKey.cxx:45
 TKey.cxx:46
 TKey.cxx:47
 TKey.cxx:48
 TKey.cxx:49
 TKey.cxx:50
 TKey.cxx:51
 TKey.cxx:52
 TKey.cxx:53
 TKey.cxx:54
 TKey.cxx:55
 TKey.cxx:56
 TKey.cxx:57
 TKey.cxx:58
 TKey.cxx:59
 TKey.cxx:60
 TKey.cxx:61
 TKey.cxx:62
 TKey.cxx:63
 TKey.cxx:64
 TKey.cxx:65
 TKey.cxx:66
 TKey.cxx:67
 TKey.cxx:68
 TKey.cxx:69
 TKey.cxx:70
 TKey.cxx:71
 TKey.cxx:72
 TKey.cxx:73
 TKey.cxx:74
 TKey.cxx:75
 TKey.cxx:76
 TKey.cxx:77
 TKey.cxx:78
 TKey.cxx:79
 TKey.cxx:80
 TKey.cxx:81
 TKey.cxx:82
 TKey.cxx:83
 TKey.cxx:84
 TKey.cxx:85
 TKey.cxx:86
 TKey.cxx:87
 TKey.cxx:88
 TKey.cxx:89
 TKey.cxx:90
 TKey.cxx:91
 TKey.cxx:92
 TKey.cxx:93
 TKey.cxx:94
 TKey.cxx:95
 TKey.cxx:96
 TKey.cxx:97
 TKey.cxx:98
 TKey.cxx:99
 TKey.cxx:100
 TKey.cxx:101
 TKey.cxx:102
 TKey.cxx:103
 TKey.cxx:104
 TKey.cxx:105
 TKey.cxx:106
 TKey.cxx:107
 TKey.cxx:108
 TKey.cxx:109
 TKey.cxx:110
 TKey.cxx:111
 TKey.cxx:112
 TKey.cxx:113
 TKey.cxx:114
 TKey.cxx:115
 TKey.cxx:116
 TKey.cxx:117
 TKey.cxx:118
 TKey.cxx:119
 TKey.cxx:120
 TKey.cxx:121
 TKey.cxx:122
 TKey.cxx:123
 TKey.cxx:124
 TKey.cxx:125
 TKey.cxx:126
 TKey.cxx:127
 TKey.cxx:128
 TKey.cxx:129
 TKey.cxx:130
 TKey.cxx:131
 TKey.cxx:132
 TKey.cxx:133
 TKey.cxx:134
 TKey.cxx:135
 TKey.cxx:136
 TKey.cxx:137
 TKey.cxx:138
 TKey.cxx:139
 TKey.cxx:140
 TKey.cxx:141
 TKey.cxx:142
 TKey.cxx:143
 TKey.cxx:144
 TKey.cxx:145
 TKey.cxx:146
 TKey.cxx:147
 TKey.cxx:148
 TKey.cxx:149
 TKey.cxx:150
 TKey.cxx:151
 TKey.cxx:152
 TKey.cxx:153
 TKey.cxx:154
 TKey.cxx:155
 TKey.cxx:156
 TKey.cxx:157
 TKey.cxx:158
 TKey.cxx:159
 TKey.cxx:160
 TKey.cxx:161
 TKey.cxx:162
 TKey.cxx:163
 TKey.cxx:164
 TKey.cxx:165
 TKey.cxx:166
 TKey.cxx:167
 TKey.cxx:168
 TKey.cxx:169
 TKey.cxx:170
 TKey.cxx:171
 TKey.cxx:172
 TKey.cxx:173
 TKey.cxx:174
 TKey.cxx:175
 TKey.cxx:176
 TKey.cxx:177
 TKey.cxx:178
 TKey.cxx:179
 TKey.cxx:180
 TKey.cxx:181
 TKey.cxx:182
 TKey.cxx:183
 TKey.cxx:184
 TKey.cxx:185
 TKey.cxx:186
 TKey.cxx:187
 TKey.cxx:188
 TKey.cxx:189
 TKey.cxx:190
 TKey.cxx:191
 TKey.cxx:192
 TKey.cxx:193
 TKey.cxx:194
 TKey.cxx:195
 TKey.cxx:196
 TKey.cxx:197
 TKey.cxx:198
 TKey.cxx:199
 TKey.cxx:200
 TKey.cxx:201
 TKey.cxx:202
 TKey.cxx:203
 TKey.cxx:204
 TKey.cxx:205
 TKey.cxx:206
 TKey.cxx:207
 TKey.cxx:208
 TKey.cxx:209
 TKey.cxx:210
 TKey.cxx:211
 TKey.cxx:212
 TKey.cxx:213
 TKey.cxx:214
 TKey.cxx:215
 TKey.cxx:216
 TKey.cxx:217
 TKey.cxx:218
 TKey.cxx:219
 TKey.cxx:220
 TKey.cxx:221
 TKey.cxx:222
 TKey.cxx:223
 TKey.cxx:224
 TKey.cxx:225
 TKey.cxx:226
 TKey.cxx:227
 TKey.cxx:228
 TKey.cxx:229
 TKey.cxx:230
 TKey.cxx:231
 TKey.cxx:232
 TKey.cxx:233
 TKey.cxx:234
 TKey.cxx:235
 TKey.cxx:236
 TKey.cxx:237
 TKey.cxx:238
 TKey.cxx:239
 TKey.cxx:240
 TKey.cxx:241
 TKey.cxx:242
 TKey.cxx:243
 TKey.cxx:244
 TKey.cxx:245
 TKey.cxx:246
 TKey.cxx:247
 TKey.cxx:248
 TKey.cxx:249
 TKey.cxx:250
 TKey.cxx:251
 TKey.cxx:252
 TKey.cxx:253
 TKey.cxx:254
 TKey.cxx:255
 TKey.cxx:256
 TKey.cxx:257
 TKey.cxx:258
 TKey.cxx:259
 TKey.cxx:260
 TKey.cxx:261
 TKey.cxx:262
 TKey.cxx:263
 TKey.cxx:264
 TKey.cxx:265
 TKey.cxx:266
 TKey.cxx:267
 TKey.cxx:268
 TKey.cxx:269
 TKey.cxx:270
 TKey.cxx:271
 TKey.cxx:272
 TKey.cxx:273
 TKey.cxx:274
 TKey.cxx:275
 TKey.cxx:276
 TKey.cxx:277
 TKey.cxx:278
 TKey.cxx:279
 TKey.cxx:280
 TKey.cxx:281
 TKey.cxx:282
 TKey.cxx:283
 TKey.cxx:284
 TKey.cxx:285
 TKey.cxx:286
 TKey.cxx:287
 TKey.cxx:288
 TKey.cxx:289
 TKey.cxx:290
 TKey.cxx:291
 TKey.cxx:292
 TKey.cxx:293
 TKey.cxx:294
 TKey.cxx:295
 TKey.cxx:296
 TKey.cxx:297
 TKey.cxx:298
 TKey.cxx:299
 TKey.cxx:300
 TKey.cxx:301
 TKey.cxx:302
 TKey.cxx:303
 TKey.cxx:304
 TKey.cxx:305
 TKey.cxx:306
 TKey.cxx:307
 TKey.cxx:308
 TKey.cxx:309
 TKey.cxx:310
 TKey.cxx:311
 TKey.cxx:312
 TKey.cxx:313
 TKey.cxx:314
 TKey.cxx:315
 TKey.cxx:316
 TKey.cxx:317
 TKey.cxx:318
 TKey.cxx:319
 TKey.cxx:320
 TKey.cxx:321
 TKey.cxx:322
 TKey.cxx:323
 TKey.cxx:324
 TKey.cxx:325
 TKey.cxx:326
 TKey.cxx:327
 TKey.cxx:328
 TKey.cxx:329
 TKey.cxx:330
 TKey.cxx:331
 TKey.cxx:332
 TKey.cxx:333
 TKey.cxx:334
 TKey.cxx:335
 TKey.cxx:336
 TKey.cxx:337
 TKey.cxx:338
 TKey.cxx:339
 TKey.cxx:340
 TKey.cxx:341
 TKey.cxx:342
 TKey.cxx:343
 TKey.cxx:344
 TKey.cxx:345
 TKey.cxx:346
 TKey.cxx:347
 TKey.cxx:348
 TKey.cxx:349
 TKey.cxx:350
 TKey.cxx:351
 TKey.cxx:352
 TKey.cxx:353
 TKey.cxx:354
 TKey.cxx:355
 TKey.cxx:356
 TKey.cxx:357
 TKey.cxx:358
 TKey.cxx:359
 TKey.cxx:360
 TKey.cxx:361
 TKey.cxx:362
 TKey.cxx:363
 TKey.cxx:364
 TKey.cxx:365
 TKey.cxx:366
 TKey.cxx:367
 TKey.cxx:368
 TKey.cxx:369
 TKey.cxx:370
 TKey.cxx:371
 TKey.cxx:372
 TKey.cxx:373
 TKey.cxx:374
 TKey.cxx:375
 TKey.cxx:376
 TKey.cxx:377
 TKey.cxx:378
 TKey.cxx:379
 TKey.cxx:380
 TKey.cxx:381
 TKey.cxx:382
 TKey.cxx:383
 TKey.cxx:384
 TKey.cxx:385
 TKey.cxx:386
 TKey.cxx:387
 TKey.cxx:388
 TKey.cxx:389
 TKey.cxx:390
 TKey.cxx:391
 TKey.cxx:392
 TKey.cxx:393
 TKey.cxx:394
 TKey.cxx:395
 TKey.cxx:396
 TKey.cxx:397
 TKey.cxx:398
 TKey.cxx:399
 TKey.cxx:400
 TKey.cxx:401
 TKey.cxx:402
 TKey.cxx:403
 TKey.cxx:404
 TKey.cxx:405
 TKey.cxx:406
 TKey.cxx:407
 TKey.cxx:408
 TKey.cxx:409
 TKey.cxx:410
 TKey.cxx:411
 TKey.cxx:412
 TKey.cxx:413
 TKey.cxx:414
 TKey.cxx:415
 TKey.cxx:416
 TKey.cxx:417
 TKey.cxx:418
 TKey.cxx:419
 TKey.cxx:420
 TKey.cxx:421
 TKey.cxx:422
 TKey.cxx:423
 TKey.cxx:424
 TKey.cxx:425
 TKey.cxx:426
 TKey.cxx:427
 TKey.cxx:428
 TKey.cxx:429
 TKey.cxx:430
 TKey.cxx:431
 TKey.cxx:432
 TKey.cxx:433
 TKey.cxx:434
 TKey.cxx:435
 TKey.cxx:436
 TKey.cxx:437
 TKey.cxx:438
 TKey.cxx:439
 TKey.cxx:440
 TKey.cxx:441
 TKey.cxx:442
 TKey.cxx:443
 TKey.cxx:444
 TKey.cxx:445
 TKey.cxx:446
 TKey.cxx:447
 TKey.cxx:448
 TKey.cxx:449
 TKey.cxx:450
 TKey.cxx:451
 TKey.cxx:452
 TKey.cxx:453
 TKey.cxx:454
 TKey.cxx:455
 TKey.cxx:456
 TKey.cxx:457
 TKey.cxx:458
 TKey.cxx:459
 TKey.cxx:460
 TKey.cxx:461
 TKey.cxx:462
 TKey.cxx:463
 TKey.cxx:464
 TKey.cxx:465
 TKey.cxx:466
 TKey.cxx:467
 TKey.cxx:468
 TKey.cxx:469
 TKey.cxx:470
 TKey.cxx:471
 TKey.cxx:472
 TKey.cxx:473
 TKey.cxx:474
 TKey.cxx:475
 TKey.cxx:476
 TKey.cxx:477
 TKey.cxx:478
 TKey.cxx:479
 TKey.cxx:480
 TKey.cxx:481
 TKey.cxx:482
 TKey.cxx:483
 TKey.cxx:484
 TKey.cxx:485
 TKey.cxx:486
 TKey.cxx:487
 TKey.cxx:488
 TKey.cxx:489
 TKey.cxx:490
 TKey.cxx:491
 TKey.cxx:492
 TKey.cxx:493
 TKey.cxx:494
 TKey.cxx:495
 TKey.cxx:496
 TKey.cxx:497
 TKey.cxx:498
 TKey.cxx:499
 TKey.cxx:500
 TKey.cxx:501
 TKey.cxx:502
 TKey.cxx:503
 TKey.cxx:504
 TKey.cxx:505
 TKey.cxx:506
 TKey.cxx:507
 TKey.cxx:508
 TKey.cxx:509
 TKey.cxx:510
 TKey.cxx:511
 TKey.cxx:512
 TKey.cxx:513
 TKey.cxx:514
 TKey.cxx:515
 TKey.cxx:516
 TKey.cxx:517
 TKey.cxx:518
 TKey.cxx:519
 TKey.cxx:520
 TKey.cxx:521
 TKey.cxx:522
 TKey.cxx:523
 TKey.cxx:524
 TKey.cxx:525
 TKey.cxx:526
 TKey.cxx:527
 TKey.cxx:528
 TKey.cxx:529
 TKey.cxx:530
 TKey.cxx:531
 TKey.cxx:532
 TKey.cxx:533
 TKey.cxx:534
 TKey.cxx:535
 TKey.cxx:536
 TKey.cxx:537
 TKey.cxx:538
 TKey.cxx:539
 TKey.cxx:540
 TKey.cxx:541
 TKey.cxx:542
 TKey.cxx:543
 TKey.cxx:544
 TKey.cxx:545
 TKey.cxx:546
 TKey.cxx:547
 TKey.cxx:548
 TKey.cxx:549
 TKey.cxx:550
 TKey.cxx:551
 TKey.cxx:552
 TKey.cxx:553
 TKey.cxx:554
 TKey.cxx:555
 TKey.cxx:556
 TKey.cxx:557
 TKey.cxx:558
 TKey.cxx:559
 TKey.cxx:560
 TKey.cxx:561
 TKey.cxx:562
 TKey.cxx:563
 TKey.cxx:564
 TKey.cxx:565
 TKey.cxx:566
 TKey.cxx:567
 TKey.cxx:568
 TKey.cxx:569
 TKey.cxx:570
 TKey.cxx:571
 TKey.cxx:572
 TKey.cxx:573
 TKey.cxx:574
 TKey.cxx:575
 TKey.cxx:576
 TKey.cxx:577
 TKey.cxx:578
 TKey.cxx:579
 TKey.cxx:580
 TKey.cxx:581
 TKey.cxx:582
 TKey.cxx:583
 TKey.cxx:584
 TKey.cxx:585
 TKey.cxx:586
 TKey.cxx:587
 TKey.cxx:588
 TKey.cxx:589
 TKey.cxx:590
 TKey.cxx:591
 TKey.cxx:592
 TKey.cxx:593
 TKey.cxx:594
 TKey.cxx:595
 TKey.cxx:596
 TKey.cxx:597
 TKey.cxx:598
 TKey.cxx:599
 TKey.cxx:600
 TKey.cxx:601
 TKey.cxx:602
 TKey.cxx:603
 TKey.cxx:604
 TKey.cxx:605
 TKey.cxx:606
 TKey.cxx:607
 TKey.cxx:608
 TKey.cxx:609
 TKey.cxx:610
 TKey.cxx:611
 TKey.cxx:612
 TKey.cxx:613
 TKey.cxx:614
 TKey.cxx:615
 TKey.cxx:616
 TKey.cxx:617
 TKey.cxx:618
 TKey.cxx:619
 TKey.cxx:620
 TKey.cxx:621
 TKey.cxx:622
 TKey.cxx:623
 TKey.cxx:624
 TKey.cxx:625
 TKey.cxx:626
 TKey.cxx:627
 TKey.cxx:628
 TKey.cxx:629
 TKey.cxx:630
 TKey.cxx:631
 TKey.cxx:632
 TKey.cxx:633
 TKey.cxx:634
 TKey.cxx:635
 TKey.cxx:636
 TKey.cxx:637
 TKey.cxx:638
 TKey.cxx:639
 TKey.cxx:640
 TKey.cxx:641
 TKey.cxx:642
 TKey.cxx:643
 TKey.cxx:644
 TKey.cxx:645
 TKey.cxx:646
 TKey.cxx:647
 TKey.cxx:648
 TKey.cxx:649
 TKey.cxx:650
 TKey.cxx:651
 TKey.cxx:652
 TKey.cxx:653
 TKey.cxx:654
 TKey.cxx:655
 TKey.cxx:656
 TKey.cxx:657
 TKey.cxx:658
 TKey.cxx:659
 TKey.cxx:660
 TKey.cxx:661
 TKey.cxx:662
 TKey.cxx:663
 TKey.cxx:664
 TKey.cxx:665
 TKey.cxx:666
 TKey.cxx:667
 TKey.cxx:668
 TKey.cxx:669
 TKey.cxx:670
 TKey.cxx:671
 TKey.cxx:672
 TKey.cxx:673
 TKey.cxx:674
 TKey.cxx:675
 TKey.cxx:676
 TKey.cxx:677
 TKey.cxx:678
 TKey.cxx:679
 TKey.cxx:680
 TKey.cxx:681
 TKey.cxx:682
 TKey.cxx:683
 TKey.cxx:684
 TKey.cxx:685
 TKey.cxx:686
 TKey.cxx:687
 TKey.cxx:688
 TKey.cxx:689
 TKey.cxx:690
 TKey.cxx:691
 TKey.cxx:692
 TKey.cxx:693
 TKey.cxx:694
 TKey.cxx:695
 TKey.cxx:696
 TKey.cxx:697
 TKey.cxx:698
 TKey.cxx:699
 TKey.cxx:700
 TKey.cxx:701
 TKey.cxx:702
 TKey.cxx:703
 TKey.cxx:704
 TKey.cxx:705
 TKey.cxx:706
 TKey.cxx:707
 TKey.cxx:708
 TKey.cxx:709
 TKey.cxx:710
 TKey.cxx:711
 TKey.cxx:712
 TKey.cxx:713
 TKey.cxx:714
 TKey.cxx:715
 TKey.cxx:716
 TKey.cxx:717
 TKey.cxx:718
 TKey.cxx:719
 TKey.cxx:720
 TKey.cxx:721
 TKey.cxx:722
 TKey.cxx:723
 TKey.cxx:724
 TKey.cxx:725
 TKey.cxx:726
 TKey.cxx:727
 TKey.cxx:728
 TKey.cxx:729
 TKey.cxx:730
 TKey.cxx:731
 TKey.cxx:732
 TKey.cxx:733
 TKey.cxx:734
 TKey.cxx:735
 TKey.cxx:736
 TKey.cxx:737
 TKey.cxx:738
 TKey.cxx:739
 TKey.cxx:740
 TKey.cxx:741
 TKey.cxx:742
 TKey.cxx:743
 TKey.cxx:744
 TKey.cxx:745
 TKey.cxx:746
 TKey.cxx:747
 TKey.cxx:748
 TKey.cxx:749
 TKey.cxx:750
 TKey.cxx:751
 TKey.cxx:752
 TKey.cxx:753
 TKey.cxx:754
 TKey.cxx:755
 TKey.cxx:756
 TKey.cxx:757
 TKey.cxx:758
 TKey.cxx:759
 TKey.cxx:760
 TKey.cxx:761
 TKey.cxx:762
 TKey.cxx:763
 TKey.cxx:764
 TKey.cxx:765
 TKey.cxx:766
 TKey.cxx:767
 TKey.cxx:768
 TKey.cxx:769
 TKey.cxx:770
 TKey.cxx:771
 TKey.cxx:772
 TKey.cxx:773
 TKey.cxx:774
 TKey.cxx:775
 TKey.cxx:776
 TKey.cxx:777
 TKey.cxx:778
 TKey.cxx:779
 TKey.cxx:780
 TKey.cxx:781
 TKey.cxx:782
 TKey.cxx:783
 TKey.cxx:784
 TKey.cxx:785
 TKey.cxx:786
 TKey.cxx:787
 TKey.cxx:788
 TKey.cxx:789
 TKey.cxx:790
 TKey.cxx:791
 TKey.cxx:792
 TKey.cxx:793
 TKey.cxx:794
 TKey.cxx:795
 TKey.cxx:796
 TKey.cxx:797
 TKey.cxx:798
 TKey.cxx:799
 TKey.cxx:800
 TKey.cxx:801
 TKey.cxx:802
 TKey.cxx:803
 TKey.cxx:804
 TKey.cxx:805
 TKey.cxx:806
 TKey.cxx:807
 TKey.cxx:808
 TKey.cxx:809
 TKey.cxx:810
 TKey.cxx:811
 TKey.cxx:812
 TKey.cxx:813
 TKey.cxx:814
 TKey.cxx:815
 TKey.cxx:816
 TKey.cxx:817
 TKey.cxx:818
 TKey.cxx:819
 TKey.cxx:820
 TKey.cxx:821
 TKey.cxx:822
 TKey.cxx:823
 TKey.cxx:824
 TKey.cxx:825
 TKey.cxx:826
 TKey.cxx:827
 TKey.cxx:828
 TKey.cxx:829
 TKey.cxx:830
 TKey.cxx:831
 TKey.cxx:832
 TKey.cxx:833
 TKey.cxx:834
 TKey.cxx:835
 TKey.cxx:836
 TKey.cxx:837
 TKey.cxx:838
 TKey.cxx:839
 TKey.cxx:840
 TKey.cxx:841
 TKey.cxx:842
 TKey.cxx:843
 TKey.cxx:844
 TKey.cxx:845
 TKey.cxx:846
 TKey.cxx:847
 TKey.cxx:848
 TKey.cxx:849
 TKey.cxx:850
 TKey.cxx:851
 TKey.cxx:852
 TKey.cxx:853
 TKey.cxx:854
 TKey.cxx:855
 TKey.cxx:856
 TKey.cxx:857
 TKey.cxx:858
 TKey.cxx:859
 TKey.cxx:860
 TKey.cxx:861
 TKey.cxx:862
 TKey.cxx:863
 TKey.cxx:864
 TKey.cxx:865
 TKey.cxx:866
 TKey.cxx:867
 TKey.cxx:868
 TKey.cxx:869
 TKey.cxx:870
 TKey.cxx:871
 TKey.cxx:872
 TKey.cxx:873
 TKey.cxx:874
 TKey.cxx:875
 TKey.cxx:876
 TKey.cxx:877
 TKey.cxx:878
 TKey.cxx:879
 TKey.cxx:880
 TKey.cxx:881
 TKey.cxx:882
 TKey.cxx:883
 TKey.cxx:884
 TKey.cxx:885
 TKey.cxx:886
 TKey.cxx:887
 TKey.cxx:888
 TKey.cxx:889
 TKey.cxx:890
 TKey.cxx:891
 TKey.cxx:892
 TKey.cxx:893
 TKey.cxx:894
 TKey.cxx:895
 TKey.cxx:896
 TKey.cxx:897
 TKey.cxx:898
 TKey.cxx:899
 TKey.cxx:900
 TKey.cxx:901
 TKey.cxx:902
 TKey.cxx:903
 TKey.cxx:904
 TKey.cxx:905
 TKey.cxx:906
 TKey.cxx:907
 TKey.cxx:908
 TKey.cxx:909
 TKey.cxx:910
 TKey.cxx:911
 TKey.cxx:912
 TKey.cxx:913
 TKey.cxx:914
 TKey.cxx:915
 TKey.cxx:916
 TKey.cxx:917
 TKey.cxx:918
 TKey.cxx:919
 TKey.cxx:920
 TKey.cxx:921
 TKey.cxx:922
 TKey.cxx:923
 TKey.cxx:924
 TKey.cxx:925
 TKey.cxx:926
 TKey.cxx:927
 TKey.cxx:928
 TKey.cxx:929
 TKey.cxx:930
 TKey.cxx:931
 TKey.cxx:932
 TKey.cxx:933
 TKey.cxx:934
 TKey.cxx:935
 TKey.cxx:936
 TKey.cxx:937
 TKey.cxx:938
 TKey.cxx:939
 TKey.cxx:940
 TKey.cxx:941
 TKey.cxx:942
 TKey.cxx:943
 TKey.cxx:944
 TKey.cxx:945
 TKey.cxx:946
 TKey.cxx:947
 TKey.cxx:948
 TKey.cxx:949
 TKey.cxx:950
 TKey.cxx:951
 TKey.cxx:952
 TKey.cxx:953
 TKey.cxx:954
 TKey.cxx:955
 TKey.cxx:956
 TKey.cxx:957
 TKey.cxx:958
 TKey.cxx:959
 TKey.cxx:960
 TKey.cxx:961
 TKey.cxx:962
 TKey.cxx:963
 TKey.cxx:964
 TKey.cxx:965
 TKey.cxx:966
 TKey.cxx:967
 TKey.cxx:968
 TKey.cxx:969
 TKey.cxx:970
 TKey.cxx:971
 TKey.cxx:972
 TKey.cxx:973
 TKey.cxx:974
 TKey.cxx:975
 TKey.cxx:976
 TKey.cxx:977
 TKey.cxx:978
 TKey.cxx:979
 TKey.cxx:980
 TKey.cxx:981
 TKey.cxx:982
 TKey.cxx:983
 TKey.cxx:984
 TKey.cxx:985
 TKey.cxx:986
 TKey.cxx:987
 TKey.cxx:988
 TKey.cxx:989
 TKey.cxx:990
 TKey.cxx:991
 TKey.cxx:992
 TKey.cxx:993
 TKey.cxx:994
 TKey.cxx:995
 TKey.cxx:996
 TKey.cxx:997
 TKey.cxx:998
 TKey.cxx:999
 TKey.cxx:1000
 TKey.cxx:1001
 TKey.cxx:1002
 TKey.cxx:1003
 TKey.cxx:1004
 TKey.cxx:1005
 TKey.cxx:1006
 TKey.cxx:1007
 TKey.cxx:1008
 TKey.cxx:1009
 TKey.cxx:1010
 TKey.cxx:1011
 TKey.cxx:1012
 TKey.cxx:1013
 TKey.cxx:1014
 TKey.cxx:1015
 TKey.cxx:1016
 TKey.cxx:1017
 TKey.cxx:1018
 TKey.cxx:1019
 TKey.cxx:1020
 TKey.cxx:1021
 TKey.cxx:1022
 TKey.cxx:1023
 TKey.cxx:1024
 TKey.cxx:1025
 TKey.cxx:1026
 TKey.cxx:1027
 TKey.cxx:1028
 TKey.cxx:1029
 TKey.cxx:1030
 TKey.cxx:1031
 TKey.cxx:1032
 TKey.cxx:1033
 TKey.cxx:1034
 TKey.cxx:1035
 TKey.cxx:1036
 TKey.cxx:1037
 TKey.cxx:1038
 TKey.cxx:1039
 TKey.cxx:1040
 TKey.cxx:1041
 TKey.cxx:1042
 TKey.cxx:1043
 TKey.cxx:1044
 TKey.cxx:1045
 TKey.cxx:1046
 TKey.cxx:1047
 TKey.cxx:1048
 TKey.cxx:1049
 TKey.cxx:1050
 TKey.cxx:1051
 TKey.cxx:1052
 TKey.cxx:1053
 TKey.cxx:1054
 TKey.cxx:1055
 TKey.cxx:1056
 TKey.cxx:1057
 TKey.cxx:1058
 TKey.cxx:1059
 TKey.cxx:1060
 TKey.cxx:1061
 TKey.cxx:1062
 TKey.cxx:1063
 TKey.cxx:1064
 TKey.cxx:1065
 TKey.cxx:1066
 TKey.cxx:1067
 TKey.cxx:1068
 TKey.cxx:1069
 TKey.cxx:1070
 TKey.cxx:1071
 TKey.cxx:1072
 TKey.cxx:1073
 TKey.cxx:1074
 TKey.cxx:1075
 TKey.cxx:1076
 TKey.cxx:1077
 TKey.cxx:1078
 TKey.cxx:1079
 TKey.cxx:1080
 TKey.cxx:1081
 TKey.cxx:1082
 TKey.cxx:1083
 TKey.cxx:1084
 TKey.cxx:1085
 TKey.cxx:1086
 TKey.cxx:1087
 TKey.cxx:1088
 TKey.cxx:1089
 TKey.cxx:1090
 TKey.cxx:1091
 TKey.cxx:1092
 TKey.cxx:1093
 TKey.cxx:1094
 TKey.cxx:1095
 TKey.cxx:1096
 TKey.cxx:1097
 TKey.cxx:1098
 TKey.cxx:1099
 TKey.cxx:1100
 TKey.cxx:1101
 TKey.cxx:1102
 TKey.cxx:1103
 TKey.cxx:1104
 TKey.cxx:1105
 TKey.cxx:1106
 TKey.cxx:1107
 TKey.cxx:1108
 TKey.cxx:1109
 TKey.cxx:1110
 TKey.cxx:1111
 TKey.cxx:1112
 TKey.cxx:1113
 TKey.cxx:1114
 TKey.cxx:1115
 TKey.cxx:1116
 TKey.cxx:1117
 TKey.cxx:1118
 TKey.cxx:1119
 TKey.cxx:1120
 TKey.cxx:1121
 TKey.cxx:1122
 TKey.cxx:1123
 TKey.cxx:1124
 TKey.cxx:1125
 TKey.cxx:1126
 TKey.cxx:1127
 TKey.cxx:1128
 TKey.cxx:1129
 TKey.cxx:1130
 TKey.cxx:1131
 TKey.cxx:1132
 TKey.cxx:1133
 TKey.cxx:1134
 TKey.cxx:1135
 TKey.cxx:1136
 TKey.cxx:1137
 TKey.cxx:1138
 TKey.cxx:1139
 TKey.cxx:1140
 TKey.cxx:1141
 TKey.cxx:1142
 TKey.cxx:1143
 TKey.cxx:1144
 TKey.cxx:1145
 TKey.cxx:1146
 TKey.cxx:1147
 TKey.cxx:1148
 TKey.cxx:1149
 TKey.cxx:1150
 TKey.cxx:1151
 TKey.cxx:1152
 TKey.cxx:1153
 TKey.cxx:1154
 TKey.cxx:1155
 TKey.cxx:1156
 TKey.cxx:1157
 TKey.cxx:1158
 TKey.cxx:1159
 TKey.cxx:1160
 TKey.cxx:1161
 TKey.cxx:1162
 TKey.cxx:1163
 TKey.cxx:1164
 TKey.cxx:1165
 TKey.cxx:1166
 TKey.cxx:1167
 TKey.cxx:1168
 TKey.cxx:1169
 TKey.cxx:1170
 TKey.cxx:1171
 TKey.cxx:1172
 TKey.cxx:1173
 TKey.cxx:1174
 TKey.cxx:1175
 TKey.cxx:1176
 TKey.cxx:1177
 TKey.cxx:1178
 TKey.cxx:1179
 TKey.cxx:1180
 TKey.cxx:1181
 TKey.cxx:1182
 TKey.cxx:1183
 TKey.cxx:1184
 TKey.cxx:1185
 TKey.cxx:1186
 TKey.cxx:1187
 TKey.cxx:1188
 TKey.cxx:1189
 TKey.cxx:1190
 TKey.cxx:1191
 TKey.cxx:1192
 TKey.cxx:1193
 TKey.cxx:1194
 TKey.cxx:1195
 TKey.cxx:1196
 TKey.cxx:1197
 TKey.cxx:1198
 TKey.cxx:1199
 TKey.cxx:1200
 TKey.cxx:1201
 TKey.cxx:1202
 TKey.cxx:1203
 TKey.cxx:1204
 TKey.cxx:1205
 TKey.cxx:1206
 TKey.cxx:1207
 TKey.cxx:1208
 TKey.cxx:1209
 TKey.cxx:1210
 TKey.cxx:1211
 TKey.cxx:1212
 TKey.cxx:1213
 TKey.cxx:1214
 TKey.cxx:1215
 TKey.cxx:1216
 TKey.cxx:1217
 TKey.cxx:1218
 TKey.cxx:1219
 TKey.cxx:1220
 TKey.cxx:1221
 TKey.cxx:1222
 TKey.cxx:1223
 TKey.cxx:1224
 TKey.cxx:1225
 TKey.cxx:1226
 TKey.cxx:1227
 TKey.cxx:1228
 TKey.cxx:1229
 TKey.cxx:1230
 TKey.cxx:1231
 TKey.cxx:1232
 TKey.cxx:1233
 TKey.cxx:1234
 TKey.cxx:1235
 TKey.cxx:1236
 TKey.cxx:1237
 TKey.cxx:1238
 TKey.cxx:1239
 TKey.cxx:1240
 TKey.cxx:1241
 TKey.cxx:1242
 TKey.cxx:1243
 TKey.cxx:1244
 TKey.cxx:1245
 TKey.cxx:1246
 TKey.cxx:1247
 TKey.cxx:1248
 TKey.cxx:1249
 TKey.cxx:1250
 TKey.cxx:1251
 TKey.cxx:1252
 TKey.cxx:1253
 TKey.cxx:1254
 TKey.cxx:1255
 TKey.cxx:1256
 TKey.cxx:1257
 TKey.cxx:1258
 TKey.cxx:1259
 TKey.cxx:1260
 TKey.cxx:1261
 TKey.cxx:1262
 TKey.cxx:1263
 TKey.cxx:1264
 TKey.cxx:1265
 TKey.cxx:1266
 TKey.cxx:1267
 TKey.cxx:1268
 TKey.cxx:1269
 TKey.cxx:1270
 TKey.cxx:1271
 TKey.cxx:1272
 TKey.cxx:1273
 TKey.cxx:1274
 TKey.cxx:1275
 TKey.cxx:1276
 TKey.cxx:1277
 TKey.cxx:1278
 TKey.cxx:1279
 TKey.cxx:1280
 TKey.cxx:1281
 TKey.cxx:1282
 TKey.cxx:1283
 TKey.cxx:1284
 TKey.cxx:1285
 TKey.cxx:1286
 TKey.cxx:1287
 TKey.cxx:1288
 TKey.cxx:1289
 TKey.cxx:1290
 TKey.cxx:1291
 TKey.cxx:1292
 TKey.cxx:1293
 TKey.cxx:1294
 TKey.cxx:1295
 TKey.cxx:1296
 TKey.cxx:1297
 TKey.cxx:1298
 TKey.cxx:1299
 TKey.cxx:1300
 TKey.cxx:1301
 TKey.cxx:1302
 TKey.cxx:1303
 TKey.cxx:1304
 TKey.cxx:1305
 TKey.cxx:1306
 TKey.cxx:1307
 TKey.cxx:1308
 TKey.cxx:1309
 TKey.cxx:1310
 TKey.cxx:1311
 TKey.cxx:1312
 TKey.cxx:1313
 TKey.cxx:1314
 TKey.cxx:1315
 TKey.cxx:1316
 TKey.cxx:1317
 TKey.cxx:1318
 TKey.cxx:1319
 TKey.cxx:1320
 TKey.cxx:1321
 TKey.cxx:1322
 TKey.cxx:1323
 TKey.cxx:1324
 TKey.cxx:1325
 TKey.cxx:1326
 TKey.cxx:1327
 TKey.cxx:1328
 TKey.cxx:1329
 TKey.cxx:1330
 TKey.cxx:1331
 TKey.cxx:1332
 TKey.cxx:1333
 TKey.cxx:1334
 TKey.cxx:1335
 TKey.cxx:1336
 TKey.cxx:1337
 TKey.cxx:1338
 TKey.cxx:1339
 TKey.cxx:1340
 TKey.cxx:1341
 TKey.cxx:1342
 TKey.cxx:1343
 TKey.cxx:1344
 TKey.cxx:1345
 TKey.cxx:1346
 TKey.cxx:1347
 TKey.cxx:1348
 TKey.cxx:1349
 TKey.cxx:1350
 TKey.cxx:1351
 TKey.cxx:1352
 TKey.cxx:1353
 TKey.cxx:1354
 TKey.cxx:1355
 TKey.cxx:1356
 TKey.cxx:1357
 TKey.cxx:1358
 TKey.cxx:1359
 TKey.cxx:1360
 TKey.cxx:1361
 TKey.cxx:1362
 TKey.cxx:1363
 TKey.cxx:1364
 TKey.cxx:1365
 TKey.cxx:1366
 TKey.cxx:1367
 TKey.cxx:1368
 TKey.cxx:1369
 TKey.cxx:1370
 TKey.cxx:1371
 TKey.cxx:1372
 TKey.cxx:1373
 TKey.cxx:1374
 TKey.cxx:1375
 TKey.cxx:1376
 TKey.cxx:1377
 TKey.cxx:1378
 TKey.cxx:1379
 TKey.cxx:1380
 TKey.cxx:1381
 TKey.cxx:1382
 TKey.cxx:1383
 TKey.cxx:1384
 TKey.cxx:1385
 TKey.cxx:1386
 TKey.cxx:1387
 TKey.cxx:1388
 TKey.cxx:1389
 TKey.cxx:1390
 TKey.cxx:1391
 TKey.cxx:1392
 TKey.cxx:1393
 TKey.cxx:1394
 TKey.cxx:1395
 TKey.cxx:1396
 TKey.cxx:1397
 TKey.cxx:1398
 TKey.cxx:1399
 TKey.cxx:1400
 TKey.cxx:1401
 TKey.cxx:1402
 TKey.cxx:1403
 TKey.cxx:1404
 TKey.cxx:1405
 TKey.cxx:1406
 TKey.cxx:1407
 TKey.cxx:1408
 TKey.cxx:1409
 TKey.cxx:1410
 TKey.cxx:1411
 TKey.cxx:1412
 TKey.cxx:1413
 TKey.cxx:1414
 TKey.cxx:1415
 TKey.cxx:1416
 TKey.cxx:1417
 TKey.cxx:1418
 TKey.cxx:1419
 TKey.cxx:1420
 TKey.cxx:1421
 TKey.cxx:1422