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

                        long pos = listSize > 0 ? pageOffsets.get(listSize - 1) + pageLengths.get(listSize - 1) : 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(pos);
                        pageLengths.add((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);
                        logicalStreams.put(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();
            }
        }