- Open-close not implemented yet.

  Easy to add:
  1. create the cacheFiles using buffer.
     open(obj){
        OpenFile of = new OpenFile(fh++, oid);
        openFiles.put(of.getFh(), of);
       while(!endoffile){
         call the codaInterface.read() // will block if miss
       }
     }
     return fh;
  2. close(){
       OpenFile of = openFiles.get(fh);
       if(of == null){
         throw...
       }
       if of.hasDirtyBit(),
       codaInterface.write(of.getBuffer());
     }

  3. read/write 
     OpenFile of = openFiles.get(fh);
     if(of == null){
         throw...
     }
     of.read/write -->see FakePRACTIFSLocalInterface.java


- write:

  LocalInterface.writeMulti(writeEntry[]) for maxHop seems not clean.
  Ideally, it should have the maxHop parameter in this level instead of 
  inside the array.

  return value:
    need to expose AcceptStamp instead long
    need to rethink what to expose for LocalInterface.

  current solution: only add preWrite(objId, offset, length, buffer, bound, maxBoundHops)
  to return the PreciseInval.

  tbd: clean the LocalInterface and Core -- remove all redundant read/write method 
       with different parameters
   

- read
  
  add timeout to read
  
  defer add timeout to DataStore:: 
  public synchronized BodyMsg
  read(ObjId objId, long offset, long length, 
       boolean blockInvalid, boolean blockImprecise, boolean exactOffset, 
       long maxTE,
       Controller controller)

  need to minus the time spending in waiting for the TE available.

- move DataStore unittest to junit

- make server write/read
  by invoking callbacks when server has informLocalWrite

  that's all need to add.


-- OverlogNodeId and PRACTINodeID
   it is very confusing. Some nodeid will become overlognode id when inserting to p2
   but some do not for example the one with AcceptStamp.

   make consistent change s.t. all nodeId will be overlogNodeId in p2 and convert back to
  nodeId when inserting back from P2 to practi
