Program: 4827
Project: 4827
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=System.currentTimeMillis() + TIME_BETWEEN_REQUERIES;
synchronized (this) {
    buckets=new RemoteFileDescGrouper(allFiles,incompleteFileManager);
  }
  while (true) {
    try {
      setState(QUEUED);
      queuePosition="String_Node_Str";
      queuedCount=0;
      manager.waitForSlot(this);
      boolean waitForRetry=false;
      bucketNumber=0;
      try {
        for (Iterator iter=buckets.buckets(); iter.hasNext(); bucketNumber++) {
          cleanup();
          files=(List)iter.next();
          if (checkHosts()) {
            setState(GAVE_UP);
            return;
          }
          if (files.size() <= 0)           continue;
synchronized (this) {
            RemoteFileDesc rfd=(RemoteFileDesc)files.get(0);
            currentFileName=rfd.getFileName();
            currentFileSize=rfd.getSize();
          }
          int status=tryAllDownloads2();
          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 == CORRUPT_FILE) {
            setState(CORRUPT_FILE);
            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)) {
        try {
          if (manager.sendQuery(this,newRequery()))           numRequeries++;
        }
 catch (        CantResumeException ignore) {
        }
        nextRequeryTime=currTime + TIME_BETWEEN_REQUERIES;
      }
      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() + TIME_BETWEEN_REQUERIES;
synchronized (this) {
    buckets=new RemoteFileDescGrouper(allFiles,incompleteFileManager);
  }
  while (true) {
    try {
      setState(QUEUED);
      queuePosition="String_Node_Str";
      queuedCount=0;
      manager.waitForSlot(this);
      boolean waitForRetry=false;
      bucketNumber=0;
      try {
        for (Iterator iter=buckets.buckets(); iter.hasNext(); bucketNumber++) {
          cleanup();
          files=(List)iter.next();
          if (checkHosts()) {
            setState(GAVE_UP);
            return;
          }
          if (files.size() <= 0)           continue;
          int status=tryAllDownloads2();
          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 == CORRUPT_FILE) {
            setState(CORRUPT_FILE);
            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)) {
        try {
          if (manager.sendQuery(this,newRequery()))           numRequeries++;
        }
 catch (        CantResumeException ignore) {
        }
        nextRequeryTime=currTime + TIME_BETWEEN_REQUERIES;
      }
      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;
      }
    }
  }
}