Program: 184689
Project: 184689
Buggy source:
public ImageGetter(){
  mGetterThread=new Thread(new Runnable(){
    private Runnable callback(    final int position,    final int offset,    final boolean isThumb,    final Bitmap bitmap){
      return new Runnable(){
        public void run(){
          if (!isCanceled() && position == mCurrentPosition) {
            mCB.imageLoaded(position,offset,bitmap,isThumb);
          }
 else {
            if (bitmap != null)             bitmap.recycle();
          }
        }
      }
;
    }
    private Runnable completedCallback(    final boolean wasCanceled){
      return new Runnable(){
        public void run(){
          mCB.completed(wasCanceled);
        }
      }
;
    }
    public void run(){
      int lastPosition=-1;
      while (!mDone) {
synchronized (ImageGetter.this) {
          mReady=true;
          ImageGetter.this.notify();
          if (mCurrentPosition == -1 || lastPosition == mCurrentPosition) {
            try {
              ImageGetter.this.wait();
            }
 catch (            InterruptedException ex) {
              continue;
            }
          }
          lastPosition=mCurrentPosition;
          mReady=false;
        }
        if (lastPosition != -1) {
          int imageCount=mAllImages.getCount();
          int[] order=mCB.loadOrder();
          for (int i=0; i < order.length; i++) {
            int offset=order[i];
            int imageNumber=lastPosition + offset;
            if (imageNumber >= 0 && imageNumber < imageCount) {
              ImageManager.IImage image=mAllImages.getImageAt(lastPosition + offset);
              if (image == null || isCanceled()) {
                break;
              }
              if (mCB.wantsThumbnail(lastPosition,offset)) {
                if (Config.LOGV)                 Log.v(TAG,"String_Node_Str" + offset);
                Bitmap b=image.thumbBitmap();
                mHandler.postGetterCallback(callback(lastPosition,offset,true,b));
              }
            }
          }
          for (int i=0; i < order.length; i++) {
            int offset=order[i];
            int imageNumber=lastPosition + offset;
            if (imageNumber >= 0 && imageNumber < imageCount) {
              ImageManager.IImage image=mAllImages.getImageAt(lastPosition + offset);
              if (mCB.wantsFullImage(lastPosition,offset)) {
                if (Config.LOGV)                 Log.v(TAG,"String_Node_Str" + offset);
                int sizeToUse=mCB.fullImageSizeToUse(lastPosition,offset);
                if (image != null && !isCanceled()) {
                  mLoad=image.fullSizeBitmap_cancelable(sizeToUse);
                }
                if (mLoad != null) {
                  long t1;
                  if (Config.LOGV)                   t1=System.currentTimeMillis();
                  Bitmap b=mLoad.get();
                  if (Config.LOGV && b != null) {
                    long t2=System.currentTimeMillis();
                    Log.v(TAG,"String_Node_Str" + image.fullSizeImageUri() + "String_Node_Str"+ sizeToUse+ "String_Node_Str"+ (t2 - t1)+ "String_Node_Str"+ b.getWidth()+ "String_Node_Str"+ b.getHeight());
                  }
                  mLoad=null;
                  if (b != null) {
                    if (isCanceled()) {
                      b.recycle();
                    }
 else {
                      mHandler.postGetterCallback(callback(lastPosition,offset,false,b));
                    }
                  }
                }
              }
            }
          }
          mHandler.postGetterCallback(completedCallback(isCanceled()));
        }
      }
    }
  }
);
  mGetterThread.setName("String_Node_Str");
  mGetterThread.start();
}

Fixed version (ground truth):
public ImageGetter(){
  mGetterThread=new Thread(new Runnable(){
    private Runnable callback(    final int position,    final int offset,    final boolean isThumb,    final Bitmap bitmap){
      return new Runnable(){
        public void run(){
          if (!isCanceled() && position == mCurrentPosition) {
            mCB.imageLoaded(position,offset,bitmap,isThumb);
          }
 else           if (bitmap != null) {
            bitmap.recycle();
          }
        }
      }
;
    }
    private Runnable completedCallback(    final boolean wasCanceled){
      return new Runnable(){
        public void run(){
          mCB.completed(wasCanceled);
        }
      }
;
    }
    public void run(){
      int lastPosition=-1;
      while (!mDone) {
synchronized (ImageGetter.this) {
          mReady=true;
          ImageGetter.this.notify();
          if (mCurrentPosition == -1 || lastPosition == mCurrentPosition) {
            try {
              ImageGetter.this.wait();
            }
 catch (            InterruptedException ex) {
              continue;
            }
          }
          lastPosition=mCurrentPosition;
          mReady=false;
        }
        if (lastPosition != -1) {
          int imageCount=mAllImages.getCount();
          int[] order=mCB.loadOrder();
          for (int i=0; i < order.length; i++) {
            int offset=order[i];
            int imageNumber=lastPosition + offset;
            if (imageNumber >= 0 && imageNumber < imageCount) {
              ImageManager.IImage image=mAllImages.getImageAt(lastPosition + offset);
              if (image == null || isCanceled()) {
                break;
              }
              if (mCB.wantsThumbnail(lastPosition,offset)) {
                if (Config.LOGV)                 Log.v(TAG,"String_Node_Str" + offset);
                Bitmap b=image.thumbBitmap();
                mHandler.postGetterCallback(callback(lastPosition,offset,true,b));
              }
            }
          }
          for (int i=0; i < order.length; i++) {
            int offset=order[i];
            int imageNumber=lastPosition + offset;
            if (imageNumber >= 0 && imageNumber < imageCount) {
              ImageManager.IImage image=mAllImages.getImageAt(lastPosition + offset);
              if (mCB.wantsFullImage(lastPosition,offset)) {
                if (Config.LOGV)                 Log.v(TAG,"String_Node_Str" + offset);
                int sizeToUse=mCB.fullImageSizeToUse(lastPosition,offset);
                if (image != null && !isCanceled()) {
                  mLoad=image.fullSizeBitmap_cancelable(sizeToUse);
                }
                if (mLoad != null) {
                  long t1;
                  if (Config.LOGV)                   t1=System.currentTimeMillis();
                  Bitmap b=mLoad.get();
                  if (Config.LOGV && b != null) {
                    long t2=System.currentTimeMillis();
                    Log.v(TAG,"String_Node_Str" + image.fullSizeImageUri() + "String_Node_Str"+ sizeToUse+ "String_Node_Str"+ (t2 - t1)+ "String_Node_Str"+ b.getWidth()+ "String_Node_Str"+ b.getHeight());
                  }
                  mLoad=null;
                  if (b != null) {
                    if (isCanceled()) {
                      b.recycle();
                    }
 else {
                      mHandler.postGetterCallback(callback(lastPosition,offset,false,b));
                    }
                  }
                }
              }
            }
          }
          mHandler.postGetterCallback(completedCallback(isCanceled()));
        }
      }
    }
  }
);
  mGetterThread.setName("String_Node_Str");
  mGetterThread.start();
}