package com.github.blackrush.acara;

import java.util.stream.Stream;

/**
 * {@inheritDoc}
 */
public final class SuperviseListenerMetadataLookup implements ListenerMetadataLookup {

    /**
     * {@inheritDoc}
     */
    @Override
    public Stream<ListenerMetadata> lookup(Object listener) {
        throw new Error("not implemented"); // TODO
    }
}

@@ -30,16 +30,107 @@
 acara;%0A%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0Aimport java.lang.reflect.Method;%0A
 import j
@@ -275,168 +275,1684 @@
     
-/**%0A     * %7B@inheritDoc%7D%0A     */%0A    @Override%0A    public Stream%3CListenerMetadata%3E lookup(Object listener) %7B%0A        throw new Error(%22not implemented%22); // TODO
+public static final SuperviseListenerMetadataLookup SHARED = new SuperviseListenerMetadataLookup();%0A%0A    public static boolean isSuperviseListener(Method method) %7B%0A        return method.isAnnotationPresent(Supervise.class);%0A    %7D%0A%0A    public static boolean isValidSuperviseListener(Method method) %7B%0A        return method.getParameterCount() == 2 &&%0A               Throwable.class.isAssignableFrom(method.getParameterTypes()%5B0%5D);%0A    %7D%0A%0A    private static final Logger log = LoggerFactory.getLogger(SuperviseListenerMetadataLookup.class);%0A%0A    private boolean checkSuperviseListenerValidity(Method method) %7B%0A        if (!isSuperviseListener(method)) %7B%0A            return false;%0A        %7D%0A        if (!isValidSuperviseListener(method)) %7B%0A            log.warn(%22method %7B%7D has an invalid signature%22);%0A            return false;%0A        %7D%0A        return true;%0A    %7D%0A%0A    @SuppressWarnings(%22unchecked%22)%0A    private Class%3CThrowable%3E getHandledCauseClass(Method method) %7B%0A        return (Class) method.getParameterTypes()%5B0%5D;%0A    %7D%0A%0A    private Class%3C?%3E getHandledInitialEventClass(Method method) %7B%0A        return method.getParameterTypes()%5B0%5D;%0A    %7D%0A%0A    /**%0A     * %7B@inheritDoc%7D%0A     */%0A    @Override%0A    public Stream%3CListenerMetadata%3E lookup(Object listener) %7B%0A        return StreamUtils.traverseInheritance(listener.getClass())%0A                .flatMap(it -%3E Stream.of(it.getDeclaredMethods()))%0A                .filter(this::checkSuperviseListenerValidity)%0A                .map(m -%3E new ListenerMetadata(listener.getClass(), m, new SupervisedEventMetadata(%0A                        getHandledCauseClass(m),%0A                        getHandledInitialEventClass(m)%0A                )));
 %0A   

implement SuperviseListenerMetadataLookup