                  LogExtentList Manipulator Routines Interfaces
                  ---------------------------------------------

     The LogExtentList manipulator routines HeadOf(), HeadXOf(), TailOf(), and
TailXOf() allow the user to fill in a LogExtentList with a copy of all or a 
portion of another LogExtentList (including itself).  Each of the methods
has an identical interface:

void HeadOf(const LogExtentList& list,const UINT32 offset,Error& err)
void HeadXOf(const LogExtentList& list,const UINT32 offset,Error& err)
void TailOf(const LogExtentList& list,const UINT32 offset,Error& err)
void TailXOf(const LogExtentList& list,const UINT32 offset,Error& err)

     If we have two lists, newList and oldList, and perform the following
operation:

     newList.HeadOf(oldList,offset,err);

newList will be cleared (any LogExtents previously stored in it will be
freed), and filled in with the head of oldList up to and including the block
containing the byte offset.  A list can take the *Of() of itself as well:

     newList.TailOf(newList,offset,err);

This call will chop out all of the blocks in the list up to but not including
the sector containing the byte offset.  

NOTE:  

     If a list takes the *Of() of an empty list, the list will be cleared
to be empty as well!

ERRORS:

     Any of the *Of() routines can return errors values from the following 
functions:

LogExtent::reinit()
LogExtentList::remove()
LogExtentList::append()

                   LogExtentList Manipulator Routines Relations
                   --------------------------------------------

bs =     blocksize
offset = argument offset (in bytes) given to Head() et al.; offset >= 0
len =    List.infoLen()

Logically, the following relations are true:

if offset < len
    List1.HeadXOf(List,offset,err) + List2.TailOf(List,offset,err) = List

if (offset % bs) == 0
    List1.HeadOf(List,offset,err) + List2.TailXOf(List,offset,err) = List

if offset < len
    List1.HeadOf(List,offset,err);
    List1.infoLen() = offset

if bs < offset < len
    List1.HeadXOf(List,offset,err);
    List1.infoLen() = offset - bs

if offset < len
    List1.TailOf(List,offset,err);
    List1.infoLen() = len - (offset/bs) * bs

if bs < offset < len
    List1.TailXOf(List,offset,err);
    List1.InfoLen() = len - ((offset/bs) + 1) * bs

OTHER NOTES OF INTEREST:

To extract a sub-region of a file given by an (offset,length) pair, we must
perform roughly the following operation:

        newList.TailOf(List,offset,err);
        newList.HeadOf(newList,length,err);

This sequence will yield an extent list describing the following sub-region
of the file:

        ( (offset / bs) * bs, length )

Clearly, if offset is not a multiple of bs (blocksize), the sub-region will
be "shifted" left by (offset % bs) bytes from the desired sub-region.

As a result, to read the desired sub-region, we must do the following:

        newList.TailOf(List,offset,err);
        newList.HeadOf(newList,length + (offset % bs),err);
        ByteArrayRef    baref(byte_array,newList.infoLen());

        newList.read(baref,err);
        baref.Offset(offset % bs);
        baref.Length(length);

At this stage, baref will point to the desired sub-region read from disk.
