public void run() {
         try {
            boolean eos=false;
            byte[] buffer=new byte[8192];
            while(!eos) {
               OggPage op=OggPage.create(source);
               synchronized (drainLock) {
                  int listSize=pageOffsets.size();

                  long pos=
                     listSize>0?
                        ((Long)pageOffsets.get(listSize-1)).longValue()+
                        ((Long)pageLengths.get(listSize-1)).longValue():
                        0;

                  byte[] arr1=op.getHeader();
                  byte[] arr2=op.getSegmentTable();
                  byte[] arr3=op.getData();

                  if(drain!=null) {
                     drain.seek(pos);
                     drain.write(arr1);
                     drain.write(arr2);
                     drain.write(arr3);
                  }
                  else {
                     System.arraycopy(arr1, 0, memoryCache, (int)pos, arr1.length);
                     System.arraycopy(arr2, 0, memoryCache, (int)pos+arr1.length, arr2.length);
                     System.arraycopy(arr3, 0, memoryCache, (int)pos+arr1.length+arr2.length, arr3.length);
                  }

                  pageOffsets.add(new Long(pos));
                  pageLengths.add(new Long(arr1.length+arr2.length+arr3.length));
               }

               if(!op.isBos()) {
                  bosDone=true;
                  //System.out.println("bosDone=true;");
               }
               if(op.isEos()) {
                  eos=true;
               }

               LogicalOggStreamImpl los=(LogicalOggStreamImpl)getLogicalStream(op.getStreamSerialNumber());
               if(los==null) {
                  los=new LogicalOggStreamImpl(CachedUrlStream.this, op.getStreamSerialNumber());
                  logicalStreams.put(new Integer(op.getStreamSerialNumber()), los);
                  los.checkFormat(op);
               }

               los.addPageNumberMapping(pageNumber);
               los.addGranulePosition(op.getAbsoluteGranulePosition());

               pageNumber++;
               cacheLength=op.getAbsoluteGranulePosition();
               //System.out.println("read page: "+pageNumber);
            }
         }
         catch(EndOfOggStreamException e) {
            // ok
         }
         catch(IOException e) {
            e.printStackTrace();
         }
      }