/** {@inheritDoc} */
  @Override
  public final void doExecute() throws Exception {
    getLog().info("options: " + options);

    final Collection<Callable<Void>> callables = new ArrayList<Callable<Void>>();

    final Collection<String> groupsAsList = getTargetGroupsAsList();
    for (final String group : groupsAsList) {
      for (final ResourceType resourceType : ResourceType.values()) {
        final String groupWithExtension = group + "." + resourceType.name().toLowerCase();

        if (isParallelProcessing()) {
          callables.add(
              Context.decorate(
                  new Callable<Void>() {
                    public Void call() throws Exception {
                      processGroup(groupWithExtension);
                      return null;
                    }
                  }));
        } else {
          processGroup(groupWithExtension);
        }
      }
    }
    if (isParallelProcessing()) {
      getTaskExecutor().submit(callables);
    }
  }
 @Test
 public void shouldComputeCorrectlySupportedResourceTypes() {
   assertTrue(
       Arrays.equals(
           new ResourceType[] {ResourceType.JS},
           new ProcessorDecorator(new JSMinProcessor()).getSupportedResourceTypes()));
   assertTrue(
       Arrays.equals(
           new ResourceType[] {ResourceType.CSS},
           new ProcessorDecorator(new CssMinProcessor()).getSupportedResourceTypes()));
   assertTrue(
       Arrays.equals(
           ResourceType.values(),
           new ProcessorDecorator(new CommentStripperProcessor()).getSupportedResourceTypes()));
 }