@Override
   public boolean apply(final SliceIntArray input, final SliceIntArray output)
   {
      if ((!SliceIntArray.isValid(input)) || (!SliceIntArray.isValid(output)))
         return false;
      
      final int nbThreads = this.delegates.length;
      ArrayList<Callable<Boolean>> filterTasks = new ArrayList<Callable<Boolean>>(nbThreads);
      final int area = this.height * this.stride;
      boolean res = true;
      
      for (int i=0; i<this.delegates.length; i++)
      { 
         int srcIdx = (this.direction == HORIZONTAL) ? input.index + (area * i) / nbThreads
                 : input.index + (this.width * i) / nbThreads;
         SliceIntArray src = new SliceIntArray(input.array, srcIdx); 
         int dstIdx  = (this.direction == HORIZONTAL) ? output.index + (area * i) / nbThreads
                 : output.index + (this.width * i) / nbThreads;
         SliceIntArray dst = new SliceIntArray(output.array, dstIdx); 
         filterTasks.add(new FilterTask(this.delegates[i], src, dst));
      } 
      
      try 
      {
         List<Future<Boolean>> results = this.pool.invokeAll(filterTasks);
      
         for (Future<Boolean> fr : results)
            res &= fr.get();      
      }
      catch (InterruptedException e)
      {
         // Ignore
      }
      catch (ExecutionException e)
      {
         return false;
      }
      
      return res;      
   }