@Override
  public Future<Bitmap> asBitmap() {
    if (builder.uri == null) {
      return FUTURE_BITMAP_NULL_URI;
    }

    // see if we get something back synchronously
    BitmapFetcher bitmapFetcher = executeCache();
    if (bitmapFetcher.info != null) {
      SimpleFuture<Bitmap> ret = new SimpleFuture<Bitmap>();
      Bitmap bitmap = bitmapFetcher.info.bitmaps == null ? null : bitmapFetcher.info.bitmaps[0];
      ret.setComplete(bitmapFetcher.info.exception, bitmap);
      return ret;
    }

    bitmapFetcher.execute();
    // we're loading, so let's register for the result.
    BitmapInfoToBitmap ret = new BitmapInfoToBitmap(builder.context);
    ion.bitmapsPending.add(bitmapFetcher.bitmapKey, ret);
    return ret;
  }
  @Override
  public Future<ImageView> intoImageView(ImageView imageView) {
    if (imageView == null) throw new IllegalArgumentException("imageView");
    assert Thread.currentThread() == Looper.getMainLooper().getThread();

    if (builder.uri != null && builder.uri.startsWith("android.resource:/")) {
      IonDrawable drawable = setIonDrawable(imageView, null, 0);
      SimpleFuture<ImageView> imageViewFuture = drawable.getFuture();
      imageViewFuture.reset();
      imageView.setImageURI(Uri.parse(builder.uri));
      imageViewFuture.setComplete(null, imageView);
      return imageViewFuture;
    }

    // no uri? just set a placeholder and bail
    if (builder.uri == null) {
      setIonDrawable(imageView, null, 0).cancel();
      return FUTURE_IMAGEVIEW_NULL_URI;
    }

    // executeCache the request, see if we get a bitmap from cache.
    BitmapFetcher bitmapFetcher = executeCache();
    if (bitmapFetcher.info != null) {
      doAnimation(imageView, null, 0);
      IonDrawable drawable =
          setIonDrawable(imageView, bitmapFetcher.info, Loader.LoaderEmitter.LOADED_FROM_MEMORY);
      drawable.cancel();
      SimpleFuture<ImageView> imageViewFuture = drawable.getFuture();
      imageViewFuture.reset();
      imageViewFuture.setComplete(bitmapFetcher.info.exception, imageView);
      return imageViewFuture;
    }

    // nothing from cache, check to see if there's too many imageview loads
    // already in progress
    if (BitmapFetcher.shouldDeferImageView(ion)) {
      bitmapFetcher.defer();
    } else {
      bitmapFetcher.execute();
    }

    IonDrawable drawable = setIonDrawable(imageView, null, 0);
    doAnimation(imageView, loadAnimation, loadAnimationResource);
    SimpleFuture<ImageView> imageViewFuture = drawable.getFuture();
    imageViewFuture.reset();
    drawable.register(ion, bitmapFetcher.bitmapKey);
    return imageViewFuture;
  }