public void add(Task task) {
        tasks.put('/' + task.getName(), task);

        TaskExecutor taskExecutor = new TaskExecutor(task);
        try {
            final Method executeMethod = task.getClass().getMethod("execute",
                    Map.class, PrintWriter.class);

            if (executeMethod.isAnnotationPresent(Timed.class)) {
                final Timed annotation = executeMethod.getAnnotation(Timed.class);
                final String name = chooseName(annotation.name(),
                        annotation.absolute(),
                        task);
                taskExecutor = new TimedTask(taskExecutor, metricRegistry.timer(name));
            }

            if (executeMethod.isAnnotationPresent(Metered.class)) {
                final Metered annotation = executeMethod.getAnnotation(Metered.class);
                final String name = chooseName(annotation.name(),
                                        annotation.absolute(),
                                        task);
                taskExecutor = new MeteredTask(taskExecutor, metricRegistry.meter(name));
            }

            if (executeMethod.isAnnotationPresent(ExceptionMetered.class)) {
                final ExceptionMetered annotation = executeMethod.getAnnotation(ExceptionMetered.class);
                final String name = chooseName(annotation.name(),
                                        annotation.absolute(),
                                        task,
                                        ExceptionMetered.DEFAULT_NAME_SUFFIX);
                taskExecutor = new ExceptionMeteredTask(taskExecutor, metricRegistry.meter(name), annotation.cause());
            }
        } catch (NoSuchMethodException ignored) {
        }

        taskExecutors.put(task, taskExecutor);
    }
@Test
    void testRunsExceptionMeteredTask() throws Exception {
        final ServletInputStream bodyStream = new TestServletInputStream(
            new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)));

        final Task exceptionMeteredTask = new Task("exception-metered-task") {
            @Override
            @ExceptionMetered(name = "vacuum-cleaning-exceptions")
            public void execute(Map<String, List<String>> parameters, PrintWriter output) {
                throw new RuntimeException("The engine has died");
            }
        };
        servlet.add(exceptionMeteredTask);

        when(request.getInputStream()).thenReturn(bodyStream);
        when(request.getParameterNames()).thenReturn(Collections.emptyEnumeration());
        when(request.getMethod()).thenReturn("POST");
        when(request.getPathInfo()).thenReturn("/exception-metered-task");
        when(response.getWriter()).thenReturn(mock(PrintWriter.class));

        servlet.service(request, response);

        assertThat(metricRegistry.getMeters()).containsKey(name(exceptionMeteredTask.getClass(),
            "vacuum-cleaning-exceptions"));
    }