Program: 4976
Project: 4976
Buggy source:
/** 
 * Actually does the download, finding duplicate files, trying all locations, resuming, waiting, and retrying as necessary.  Also takes care of moving file from incomplete directory to save directory and adding file to the library.  Called from dloadManagerThread.  
 */
private void tryAllDownloads(){
  int numRequeries=0;
  long nextRequeryTime=0;
synchronized (this) {
    buckets=new RemoteFileDescGrouper(allFiles,incompleteFileManager);
  }
  while (true) {
    try {
      setState(QUEUED);
      manager.waitForSlot(this);
      boolean waitForRetry=false;
      try {
        for (Iterator iter=buckets.buckets(); iter.hasNext(); ) {
          List bucket=(List)iter.next();
          if (bucket.size() <= 0)           continue;
synchronized (this) {
            RemoteFileDesc rfd=(RemoteFileDesc)bucket.get(0);
            currentFileName=rfd.getFileName();
            currentFileSize=rfd.getSize();
          }
          int status=tryAllDownloads2(bucket);
          if (status == COMPLETE) {
            setState(COMPLETE);
            manager.remove(this,true);
            return;
          }
 else           if (status == COULDNT_MOVE_TO_LIBRARY) {
            setState(COULDNT_MOVE_TO_LIBRARY);
            manager.remove(this,false);
            return;
          }
 else           if (status == WAITING_FOR_RETRY) {
            waitForRetry=true;
          }
 else {
            Assert.that(status == GAVE_UP,"String_Node_Str" + status);
          }
        }
      }
 catch (      InterruptedException e) {
        if (!stopped)         ManagedDownloader.this.manager.internalError(e);
      }
      manager.yieldSlot(this);
      if (stopped) {
        setState(ABORTED);
        manager.remove(this,false);
        return;
      }
      final long currTime=System.currentTimeMillis();
      if ((currTime >= nextRequeryTime) && (numRequeries++ < REQUERY_ATTEMPTS)) {
        manager.sendQuery(allFiles);
        nextRequeryTime=currTime + (getMinutesToWaitForRequery(numRequeries) * 60 * 1000);
      }
      if (waitForRetry) {
synchronized (this) {
          retriesWaiting=0;
          for (Iterator iter=buckets.buckets(); iter.hasNext(); ) {
            List bucket=(List)iter.next();
            retriesWaiting+=bucket.size();
          }
        }
        long time=calculateWaitTime();
        setState(WAITING_FOR_RETRY,time);
        reqLock.lock(time);
      }
 else {
        if (numRequeries <= REQUERY_ATTEMPTS) {
          final long waitTime=nextRequeryTime - System.currentTimeMillis();
          if (waitTime > 0) {
            setState(WAITING_FOR_RESULTS,waitTime);
            reqLock.lock(waitTime);
          }
        }
 else {
          setState(GAVE_UP);
          manager.remove(this,false);
          return;
        }
      }
    }
 catch (    InterruptedException e) {
      if (stopped) {
        setState(ABORTED);
        manager.remove(this,false);
        return;
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * Actually does the download, finding duplicate files, trying all locations, resuming, waiting, and retrying as necessary.  Also takes care of moving file from incomplete directory to save directory and adding file to the library.  Called from dloadManagerThread.  
 */
private void tryAllDownloads(){
  int numRequeries=0;
  long nextRequeryTime=System.currentTimeMillis() + getMinutesToWaitForRequery(numRequeries) * 60 * 1000;
synchronized (this) {
    buckets=new RemoteFileDescGrouper(allFiles,incompleteFileManager);
  }
  while (true) {
    try {
      setState(QUEUED);
      manager.waitForSlot(this);
      boolean waitForRetry=false;
      try {
        for (Iterator iter=buckets.buckets(); iter.hasNext(); ) {
          List bucket=(List)iter.next();
          if (bucket.size() <= 0)           continue;
synchronized (this) {
            RemoteFileDesc rfd=(RemoteFileDesc)bucket.get(0);
            currentFileName=rfd.getFileName();
            currentFileSize=rfd.getSize();
          }
          int status=tryAllDownloads2(bucket);
          if (status == COMPLETE) {
            setState(COMPLETE);
            manager.remove(this,true);
            return;
          }
 else           if (status == COULDNT_MOVE_TO_LIBRARY) {
            setState(COULDNT_MOVE_TO_LIBRARY);
            manager.remove(this,false);
            return;
          }
 else           if (status == WAITING_FOR_RETRY) {
            waitForRetry=true;
          }
 else {
            Assert.that(status == GAVE_UP,"String_Node_Str" + status);
          }
        }
      }
 catch (      InterruptedException e) {
        if (!stopped)         ManagedDownloader.this.manager.internalError(e);
      }
      manager.yieldSlot(this);
      if (stopped) {
        setState(ABORTED);
        manager.remove(this,false);
        return;
      }
      final long currTime=System.currentTimeMillis();
      if ((currTime >= nextRequeryTime) && (numRequeries < REQUERY_ATTEMPTS)) {
        manager.sendQuery(allFiles);
        numRequeries++;
        nextRequeryTime=currTime + (getMinutesToWaitForRequery(numRequeries) * 60 * 1000);
      }
      if (waitForRetry) {
synchronized (this) {
          retriesWaiting=0;
          for (Iterator iter=buckets.buckets(); iter.hasNext(); ) {
            List bucket=(List)iter.next();
            retriesWaiting+=bucket.size();
          }
        }
        long time=calculateWaitTime();
        setState(WAITING_FOR_RETRY,time);
        reqLock.lock(time);
      }
 else {
        if (numRequeries <= REQUERY_ATTEMPTS) {
          final long waitTime=nextRequeryTime - System.currentTimeMillis();
          if (waitTime > 0) {
            setState(WAITING_FOR_RESULTS,waitTime);
            reqLock.lock(waitTime);
          }
        }
 else {
          setState(GAVE_UP);
          manager.remove(this,false);
          return;
        }
      }
    }
 catch (    InterruptedException e) {
      if (stopped) {
        setState(ABORTED);
        manager.remove(this,false);
        return;
      }
    }
  }
}