@Override
 public boolean matches(Challenge c) {
   final LinkCrawler lcrawler = getCrawler();
   if (lcrawler != null && lcrawler.isRunning()) {
     final Plugin plugin = c.getPlugin();
     if (plugin instanceof PluginForDecrypt) {
       final PluginForDecrypt decrypt = (PluginForDecrypt) plugin;
       return decrypt.getCrawler() == lcrawler && decrypt.getHost().equalsIgnoreCase(getHost());
     }
   }
   return false;
 }
 public <T> SolverJob<T> handle(final Challenge<T> c) throws InterruptedException, SkipException {
   LogSource logger = LogController.getInstance().getPreviousThreadLogSource();
   if (logger == null) {
     logger = this.logger;
   }
   logger.info("Log to " + logger.getName());
   logger.info("Handle Challenge: " + c);
   final ArrayList<ChallengeSolver<T>> solver = createList(c);
   logger.info("Solver: " + solver);
   if (solver.size() == 0) {
     logger.info("No solver available!");
     throw new SkipException(SkipRequest.BLOCK_HOSTER);
   }
   final SolverJob<T> job = new SolverJob<T>(this, c, solver);
   job.setLogger(logger);
   final Plugin plugin = c.getPlugin();
   if (plugin != null) {
     if (plugin instanceof PluginForHost) {
       ((PluginForHost) plugin).setLastSolverJob(job);
     } else if (plugin instanceof PluginForDecrypt) {
       ((PluginForDecrypt) plugin).setLastSolverJob(job);
     }
   }
   final UniqueAlltimeID jobID = c.getId();
   synchronized (activeJobs) {
     activeJobs.add(job);
     idToJobMap.put(jobID, job);
   }
   try {
     for (final ChallengeSolver<T> cs : solver) {
       logger.info("Send to solver: " + cs + " " + job);
       cs.enqueue(job);
     }
     logger.info("Fire New Job Event");
     fireNewJobEvent(job);
     logger.info("Wait");
     while (!job.isSolved() && !job.isDone()) {
       synchronized (job) {
         if (!job.isSolved() && !job.isDone()) {
           job.wait(10000);
         }
       }
     }
     if (job.getSkipRequest() != null) {
       throw new SkipException(job.getSkipRequest());
     }
     final ResponseList<T> response = job.getResponseAndKill();
     logger.info("All Responses: " + job.getResponses());
     logger.info("Solving Done. Result: " + response);
     return job;
   } catch (InterruptedException e) { // for example downloads have been stopped
     job.kill();
     throw e;
   } finally {
     try {
       synchronized (activeJobs) {
         activeJobs.remove(job);
         idToJobMap.remove(jobID);
       }
     } finally {
       fireJobDone(job);
     }
   }
 }