I didn't test it, but I was thinking about something like this.
The advantage: each resolver's `remove` is invoked once, delegating batch operations when deleting multiple filters/paths (even combinations) to the resolver itself.

```php
class CacheManager
{
    // ..

    public function remove($paths = null, $filters = null)
    {
        if (null === $filters) {
            $filters = array_keys($this->filterConfig->all());
        }
        if (!is_array($filters)) {
            $filters = array($filters);
        }
        if (null !== $paths && !is_array($paths)) {
            $paths = array($paths);
        }

        $mapping = new \SplObjectStorage();
        foreach ($filters as $filter) {
            // Retrieve the resolver for the current filter.
            $resolver = $this->getResolver($filter);

            // Create a new list and retrieve any existing list.
            $list = array();
            if ($mapping->contains($resolver)) {
                $list = $mapping[$resolver];
            }

            // Append the current filter to the filters list, replace the list for this resolver.
            $list[] = $filter;
            $mapping[$resolver] = $list;
        }

        foreach ($mapping as $resolver) {
            $resolver->remove($paths, $mapping[$resolver]);
        }
    }
}
```