Program: 170796
Project: 170796
Buggy source:
public void stopIt(int _stateAfterStopping,final boolean remove_torrent,final boolean remove_data,final boolean for_removal){
  long current_up=stats.getDataSendRate();
  if (current_up != 0) {
    data_send_rate_at_close=current_up;
  }
  boolean closing=_stateAfterStopping == DownloadManager.STATE_CLOSED;
  if (closing) {
    _stateAfterStopping=DownloadManager.STATE_STOPPED;
  }
  final int stateAfterStopping=_stateAfterStopping;
  try {
    control_mon.enter();
    int state=getState();
    if (state == DownloadManager.STATE_STOPPED || (state == DownloadManager.STATE_ERROR && getDiskManager() == null)) {
      if (remove_data) {
        download_manager.deleteDataFiles();
      }
 else {
        if (for_removal && COConfigurationManager.getBooleanParameter("String_Node_Str")) {
          download_manager.deletePartialDataFiles();
        }
      }
      if (remove_torrent) {
        download_manager.deleteTorrentFile();
      }
      setState(_stateAfterStopping,false);
      return;
    }
    if (state == DownloadManager.STATE_STOPPING) {
      return;
    }
    setSubState(_stateAfterStopping);
    setState(DownloadManager.STATE_STOPPING,false);
    final AESemaphore nd_sem=new AESemaphore("String_Node_Str");
    NonDaemonTaskRunner.runAsync(new NonDaemonTask(){
      @Override public Object run(){
        nd_sem.reserve();
        return (null);
      }
      @Override public String getName(){
        return ("String_Node_Str" + getDisplayName() + "String_Node_Str");
      }
    }
);
    try {
      try {
        if (peer_manager != null) {
          peer_manager.stopAll();
          stats.saveSessionTotals();
          DownloadManagerState dmState=download_manager.getDownloadState();
          dmState.setLongParameter(DownloadManagerState.PARAM_DOWNLOAD_LAST_ACTIVE_TIME,SystemTime.getCurrentTime());
          SimpleTimer.removeTickReceiver(this);
          DownloadManagerRateController.removePeerManager(peer_manager);
          download_manager.getDownloadState().removeListener(dm_attribute_listener,DownloadManagerState.AT_FLAGS,DownloadManagerStateAttributeListener.WRITTEN);
          dm_attribute_listener=null;
        }
        download_manager.informStopped(peer_manager,stateAfterStopping == DownloadManager.STATE_QUEUED);
        peer_manager=null;
        DiskManager dm=getDiskManager();
        if (dm != null) {
          boolean went_async=dm.stop(closing);
          if (went_async) {
            int wait_count=0;
            Thread.sleep(10);
            while (!dm.isStopped()) {
              wait_count++;
              if (wait_count > 2 * 60 * 10) {
                Debug.out("String_Node_Str");
                break;
              }
 else               if (wait_count % 200 == 0) {
                Debug.out("String_Node_Str" + wait_count + "String_Node_Str");
              }
              Thread.sleep(100);
            }
          }
          stats.setCompleted(stats.getCompleted());
          stats.recalcDownloadCompleteBytes();
          if (!download_manager.getAssumedComplete()) {
            download_manager.getDownloadState().save();
          }
          setDiskManager(null,null);
        }
      }
  finally {
        force_start=false;
        if (remove_data) {
          download_manager.deleteDataFiles();
        }
 else {
          if (for_removal && COConfigurationManager.getBooleanParameter("String_Node_Str")) {
            download_manager.deletePartialDataFiles();
          }
        }
        if (remove_torrent) {
          download_manager.deleteTorrentFile();
        }
        List<ExternalSeedPeer> to_remove=new ArrayList<>();
synchronized (http_seeds) {
          to_remove.addAll(http_seeds);
          http_seeds.clear();
        }
        for (        ExternalSeedPeer peer : to_remove) {
          peer.remove();
        }
        if (getState() == DownloadManager.STATE_STOPPING) {
          setState(stateAfterStopping,true);
        }
      }
    }
  finally {
      nd_sem.release();
    }
  }
 catch (  Throwable e) {
    Debug.printStackTrace(e);
  }
 finally {
    control_mon.exit();
    download_manager.informStateChanged();
  }
}

Fixed version (ground truth):
public void stopIt(int _stateAfterStopping,final boolean remove_torrent,final boolean remove_data,final boolean for_removal){
  long current_up=stats.getDataSendRate();
  if (current_up != 0) {
    data_send_rate_at_close=current_up;
  }
  boolean closing=_stateAfterStopping == DownloadManager.STATE_CLOSED;
  if (closing) {
    _stateAfterStopping=DownloadManager.STATE_STOPPED;
  }
  final int stateAfterStopping=_stateAfterStopping;
  try {
    control_mon.enter();
    int state=getState();
    if (state == DownloadManager.STATE_STOPPED || (state == DownloadManager.STATE_ERROR && getDiskManager() == null)) {
      if (remove_data) {
        download_manager.deleteDataFiles();
      }
 else {
        if (for_removal && COConfigurationManager.getBooleanParameter("String_Node_Str")) {
          download_manager.deletePartialDataFiles();
        }
      }
      if (remove_torrent) {
        download_manager.deleteTorrentFile();
      }
      setState(_stateAfterStopping,false);
      return;
    }
    if (state == DownloadManager.STATE_STOPPING) {
      return;
    }
    setSubState(_stateAfterStopping);
    setState(DownloadManager.STATE_STOPPING,false);
    NonDaemonTaskRunner.run(new NonDaemonTask(){
      @Override public Object run(){
        try {
          if (peer_manager != null) {
            peer_manager.stopAll();
            stats.saveSessionTotals();
            DownloadManagerState dmState=download_manager.getDownloadState();
            dmState.setLongParameter(DownloadManagerState.PARAM_DOWNLOAD_LAST_ACTIVE_TIME,SystemTime.getCurrentTime());
            SimpleTimer.removeTickReceiver(DownloadManagerController.this);
            DownloadManagerRateController.removePeerManager(peer_manager);
            download_manager.getDownloadState().removeListener(dm_attribute_listener,DownloadManagerState.AT_FLAGS,DownloadManagerStateAttributeListener.WRITTEN);
            dm_attribute_listener=null;
          }
          download_manager.informStopped(peer_manager,stateAfterStopping == DownloadManager.STATE_QUEUED);
          peer_manager=null;
          DiskManager dm=getDiskManager();
          if (dm != null) {
            boolean went_async=dm.stop(closing);
            if (went_async) {
              try {
                int wait_count=0;
                Thread.sleep(10);
                while (!dm.isStopped()) {
                  wait_count++;
                  if (wait_count > 2 * 60 * 10) {
                    Debug.out("String_Node_Str");
                    break;
                  }
 else                   if (wait_count % 200 == 0) {
                    Debug.out("String_Node_Str" + wait_count + "String_Node_Str");
                  }
                  Thread.sleep(100);
                }
              }
 catch (              Throwable e) {
                Debug.out(e);
              }
            }
            stats.setCompleted(stats.getCompleted());
            stats.recalcDownloadCompleteBytes();
            if (!download_manager.getAssumedComplete()) {
              download_manager.getDownloadState().save();
            }
            setDiskManager(null,null);
          }
        }
  finally {
          force_start=false;
          if (remove_data) {
            download_manager.deleteDataFiles();
          }
 else {
            if (for_removal && COConfigurationManager.getBooleanParameter("String_Node_Str")) {
              download_manager.deletePartialDataFiles();
            }
          }
          if (remove_torrent) {
            download_manager.deleteTorrentFile();
          }
          List<ExternalSeedPeer> to_remove=new ArrayList<>();
synchronized (http_seeds) {
            to_remove.addAll(http_seeds);
            http_seeds.clear();
          }
          for (          ExternalSeedPeer peer : to_remove) {
            peer.remove();
          }
          if (getState() == DownloadManager.STATE_STOPPING) {
            setState(stateAfterStopping,true);
          }
        }
        return (null);
      }
      @Override public String getName(){
        return ("String_Node_Str" + getDisplayName() + "String_Node_Str");
      }
    }
);
  }
 catch (  Throwable e) {
    Debug.printStackTrace(e);
  }
 finally {
    control_mon.exit();
    download_manager.informStateChanged();
  }
}