@Override
    public void renderPage(CharSequence source) {
        final List<ImageInfo> imageInfos = scanForImageInfo(source);
        CompletionService<ImageData> downloadImages = new ExecutorCompletionService<ImageData>(executorService);

        for (final ImageInfo imageInfo : imageInfos) {
            downloadImages.submit(new Callable<ImageData>() {
                @Override
                public ImageData call() throws Exception {
                    return imageInfo.downloadImage();
                }
            });

        }
        renderText(source);
        try {
            for (int t = 0, n = imageInfos.size(); t < n; t++) {
                Future<ImageData> maybeDownloaded = downloadImages.take();
                ImageData imageData = maybeDownloaded.get();
                renderImage(imageData);
            }
        } catch (InterruptedException e) {
            // Re-assert the thread's interrupted status
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            new RuntimeException();
        }
    }