// This method prevents locked files on Windows from not allowing to delete unlocked files, i.e.,
  // it will keep on
  // deleting other files even if it reaches a locked file first.
  protected static void deleteFilesRecursively(File folder) {
    TaskUtil.checkInterruption();

    // First check if it's a directory to avoid future misuse.
    if (folder.isDirectory()) {
      File[] files = folder.listFiles();
      for (File file : files) {
        TaskUtil.checkInterruption();

        if (file.isDirectory()) {
          deleteFilesRecursively(file);
        } else {
          try {
            FileUtils.forceDelete(file);
          } catch (IOException ioe) {
            ioe.printStackTrace();
          }
        }
      }
      // After cleaning the files, tries to delete the containing folder.
      try {
        FileUtils.forceDelete(folder);
      } catch (IOException ioe) {
        // If the folder cannot be deleted it means there are locked files in it. But we don't need
        // to log it
        // here once the file locks had already been detected and logged in the for loop above.
      }
    } else {
      try {
        FileUtils.forceDelete(folder);
      } catch (IOException ioe) {
        ioe.printStackTrace();
      }
    }
  }
  /**
   * Removes the snapshots from maven repository.
   *
   * @param repository the repository
   * @throws Exception the exception
   */
  protected SnapshotRemovalRepositoryResult removeSnapshotsFromMavenRepository(
      MavenRepository repository, SnapshotRemovalRequest request) {
    TaskUtil.checkInterruption();

    SnapshotRemovalRepositoryResult result =
        new SnapshotRemovalRepositoryResult(repository.getId(), 0, 0, true);

    if (!repository.getLocalStatus().shouldServiceRequest()) {
      return result;
    }

    // we are already processed here, so skip repo
    if (request.isProcessedRepo(repository.getId())) {
      return new SnapshotRemovalRepositoryResult(repository.getId(), true);
    }

    request.addProcessedRepo(repository.getId());

    // if this is not snap repo, do nothing
    if (!RepositoryPolicy.SNAPSHOT.equals(repository.getRepositoryPolicy())) {
      return result;
    }

    if (getLogger().isDebugEnabled()) {
      getLogger()
          .debug(
              "Collecting deletable snapshots on repository "
                  + repository.getId()
                  + " from storage directory "
                  + repository.getLocalUrl());
    }

    request.getMetadataRebuildPaths().clear();

    // create a walker to collect deletables and let it loose on collections only
    SnapshotRemoverWalkerProcessor snapshotRemoveProcessor =
        new SnapshotRemoverWalkerProcessor(repository, request);

    DefaultWalkerContext ctxMain =
        new DefaultWalkerContext(
            repository, new ResourceStoreRequest("/"), new DottedStoreWalkerFilter());

    ctxMain.getProcessors().add(snapshotRemoveProcessor);

    walker.walk(ctxMain);

    if (ctxMain.getStopCause() != null) {
      result.setSuccessful(false);
    }

    // and collect results
    result.setDeletedSnapshots(snapshotRemoveProcessor.getDeletedSnapshots());
    result.setDeletedFiles(snapshotRemoveProcessor.getDeletedFiles());

    if (getLogger().isDebugEnabled()) {
      getLogger()
          .debug(
              "Collected and deleted "
                  + snapshotRemoveProcessor.getDeletedSnapshots()
                  + " snapshots with alltogether "
                  + snapshotRemoveProcessor.getDeletedFiles()
                  + " files on repository "
                  + repository.getId());
    }

    repository.expireCaches(new ResourceStoreRequest(RepositoryItemUid.PATH_ROOT));

    RecreateMavenMetadataWalkerProcessor metadataRebuildProcessor =
        new RecreateMavenMetadataWalkerProcessor(getLogger());

    for (String path : request.getMetadataRebuildPaths()) {
      DefaultWalkerContext ctxMd =
          new DefaultWalkerContext(
              repository, new ResourceStoreRequest(path), new DottedStoreWalkerFilter());

      ctxMd.getProcessors().add(metadataRebuildProcessor);

      try {
        walker.walk(ctxMd);
      } catch (WalkerException e) {
        if (!(e.getCause() instanceof ItemNotFoundException)) {
          // do not ignore it
          throw e;
        }
      }
    }

    return result;
  }
 @Override
 public void inspect(final Event<?> evt) {
   if (isActive()) {
     TaskUtil.getCurrentProgressListener().cancel();
   }
 }