package com.github.blackrush.acara;

import java.lang.reflect.Method;

/**
 * {@link com.github.blackrush.acara.ListenerMetadata} holds all useful listener metadata.
 *
 * {@link com.github.blackrush.acara.ListenerMetadata} is a pure immutable type, implementing equals/hashCode.
 */
public final class ListenerMetadata {
    private final Class<?> listenerClass;
    private final Method listenerMethod;
    private final EventMetadata handledEventMetadata;

    /**
     * Default constructor.
     * @param listenerClass a non-null {@link java.lang.Class} representing listener's class
     * @param listenerMethod a non-null {@link java.lang.reflect.Method} representing listener's method
     * @param handledEventMetadata a non-null {@link com.github.blackrush.acara.EventMetadata} representing handled event's metadata
     */
    public ListenerMetadata(Class<?> listenerClass, Method listenerMethod, EventMetadata handledEventMetadata) {
        this.listenerClass = listenerClass;
        this.listenerMethod = listenerMethod;
        this.handledEventMetadata = handledEventMetadata;
    }

    /**
     * Get listener's {@link java.lang.Class}
     * @return a non-null class
     */
    public Class<?> getListenerClass() {
        return listenerClass;
    }

    /**
     * Get listener's {@link java.lang.reflect.Method}
     * @return a non-null method
     */
    public Method getListenerMethod() {
        return listenerMethod;
    }

    /**
     * Get handled event's {@link java.lang.Class}
     * @return a non-null value
     */
    public EventMetadata getHandledEventMetadata() {
        return handledEventMetadata;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ListenerMetadata metadata = (ListenerMetadata) o;

        return handledEventMetadata.equals(metadata.handledEventMetadata) &&
               listenerClass.equals(metadata.listenerClass) &&
               listenerMethod.equals(metadata.listenerMethod);

    }

    @Override
    public int hashCode() {
        int result = listenerClass.hashCode();
        result = 31 * result + listenerMethod.hashCode();
        result = 31 * result + handledEventMetadata.hashCode();
        return result;
    }

    @Override
    public String toString() {
        return "ListenerMetadata(" +
                "listenerClass=" + listenerClass +
                ", listenerMethod=" + listenerMethod +
                ", handledEventMetadata=" + handledEventMetadata +
                ')';
    }
}

@@ -1286,362 +1286,2170 @@
   * 
-Get listener's %7B@link java.lang.reflect.Method%7D%0A     * @return a non-null method%0A     */%0A    public Method getListenerMethod() %7B%0A        return listenerMethod;%0A    %7D%0A%0A    /**%0A     * Get handled event's %7B@link java.lang.Class%7D%0A     * @return a non-null value%0A     */%0A    public EventMetadata getHandledEventMetadata() %7B%0A        return handledEventMetadata
+Create a new %7B@link com.github.blackrush.acara.ListenerMetadata%7D with a new listener class%0A     * @param listenerClass a non-null %7B@link java.lang.Class%7D representing listener's class%0A     * @return a non-null %7B@link com.github.blackrush.acara.ListenerMetadata%7D or the same instance if the parameter is equal to actual listener class%0A     */%0A    public ListenerMetadata withListenerClass(Class%3C?%3E listenerClass) %7B%0A        return this.listenerClass != listenerClass ? this : new ListenerMetadata(listenerClass, listenerMethod, handledEventMetadata);%0A    %7D%0A%0A    /**%0A     * Get listener's %7B@link java.lang.reflect.Method%7D%0A     * @return a non-null method%0A     */%0A    public Method getListenerMethod() %7B%0A        return listenerMethod;%0A    %7D%0A%0A    /**%0A     * Create a new %7B@link com.github.blackrush.acara.ListenerMetadata%7D with a new listener method%0A     * @param listenerMethod a non-null %7B@link java.lang.Class%7D representing listener's method%0A     * @return a non-null %7B@link com.github.blackrush.acara.ListenerMetadata%7D or the same instance if the parameter is equal to actual listener method%0A     */%0A    public ListenerMetadata withListenerMethod(Method listenerMethod) %7B%0A        return this.listenerMethod != listenerMethod ? this : new ListenerMetadata(listenerClass, listenerMethod, handledEventMetadata);%0A    %7D%0A%0A    /**%0A     * Get handled event's %7B@link java.lang.Class%7D%0A     * @return a non-null value%0A     */%0A    public EventMetadata getHandledEventMetadata() %7B%0A        return handledEventMetadata;%0A    %7D%0A%0A    /**%0A     * Create a new %7B@link com.github.blackrush.acara.ListenerMetadata%7D with a new handled event metadata%0A     * @param handledEventMetadata a non-null %7B@link com.github.blackrush.acara.EventMetadata%7D representing handled event's metadata%0A     * @return a non-null %7B@link com.github.blackrush.acara.ListenerMetadata%7D or the same instance if the parameter is equal to actual handled event metadata%0A     */%0A    public ListenerMetadata withHandledEventMetadata(EventMetadata handledEventMetadata) %7B%0A        return this.handledEventMetadata != handledEventMetadata ? this : new ListenerMetadata(listenerClass, listenerMethod, handledEventMetadata)
 ;%0A  

fix issue #1