private void progressiveRun() {
        final Thread current = Thread.currentThread();
        //if(animated) DjVuOptions.err.println("bcr progressiveRun "+this);
        GRect lastFullRect = null;
        boolean repeat;

        do {
            final boolean decoding = page.isDecoding();
            repeat = decoding;

            GMap map;
            GRect fullRect;
            GRect bufferRect;
            {
//        final long lockTime=System.currentTimeMillis();
                synchronized (mapArray) {
                    map = mapArray[0];
                    bufferRect = segment();
                    fullRect = segmentArray[FULL_RECT];
//          DjVuObject.checkLockTime(lockTime,10000);
                }
            }

            GMap newMap = page.updateMap(map, bufferRect, subsample);

            if ((newMap != null) && (map != newMap)) {
//        final long lockTime=System.currentTimeMillis();
                synchronized (mapArray) {
                    reuseArray[0] = DjVuObject.createSoftReference(mapArray[1], mapArray[1]);
                    mapArray[0] = mapArray[1] = newMap;
                    segmentArray[BUFFER_RECT] = bufferRect;
                    segmentArray[LAST_RENDERED_RECT] = lastFullRect = null;
//          DjVuObject.checkLockTime(lockTime,10000);
                }

                newPixels();
                lastFullRect = fullRect;

                if (DjVuOptions.COLLECT_GARBAGE) {
                    System.gc();
                }

                repeat = true;
            } else if (!fullRect.equals(lastFullRect)) {
                newPixels();
                lastFullRect = fullRect;
            }

            if (decoding) {
                page.waitForCodec(page.progressiveLock, 0L);

                if (newMap != null) {
//          final long lockTime=System.currentTimeMillis();
                    synchronized (mapArray) {
                        bufferRect = segment();
                        fullRect = segmentArray[FULL_RECT];
//            DjVuObject.checkLockTime(lockTime,10000);
                    }

                    if (fullRect.equals(lastFullRect)) {
                        // Wait at least half a second before updating
                        // a page which is still decoding.
                        try {
                            page.waitForCodec(page.doneLock, 500L);
                        } catch (final Throwable ignored) {
                        }
                    }
                }
            }
        } while (repeat);

        flags[PROGRESSIVE_FLAG] = false;
    }