// Path: library/src/main/java/com/danikula/aibolit/InjectingException.java
// public class InjectingException extends RuntimeException {
// 
//     private static final long serialVersionUID = -1L;
// 
//     public InjectingException(String message) {
//         super(message);
//     }
// 
//     public InjectingException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public InjectingException(Throwable cause) {
//         super(cause);
//     }
// }
// 
// Path: library/src/main/java/com/danikula/aibolit/ServicesResolver.java
// public interface ServicesResolver {
// 
//     /**
//      * Resolves application service by class
//      * 
//      * @param serviceClass Class service's class
//      * @return Object application service
//      */
//     Object resolve(Class<?> serviceClass);
// 
// }
// 
// Path: library/src/main/java/com/danikula/aibolit/Validate.java
// public class Validate {
// 
//     /**
//      * Checks variable on <code>null</code>
//      * 
//      * @param object Object variable to be checked
//      * @param message String message of exception to be throwed if parameter is <code>null</code>
//      * @throws IllegalArgumentException if <code>object</code> is <code>null</code>
//      */
//     public static void notNull(Object object, String message) {
//         if (object == null) {
//             throw new IllegalArgumentException(message);
//         }
//     }
// 
//     /**
//      * Checks contition on <code>true</code>
//      * 
//      * @param condition boolean condition to check
//      * @param message String message of exception to be throwed if condition is not <code>true</code>
//      * @throws IllegalArgumentException if <code>condition</code> is not <code>true</code>
//      */
//     public static void checkTrue(boolean condition, String message) {
//         if (!condition) {
//             throw new IllegalArgumentException(message);
//         }
//     }
// 
// }


import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.danikula.aibolit.InjectingException;
import com.danikula.aibolit.ServicesResolver;
import com.danikula.aibolit.Validate;
import com.danikula.aibolit.annotation.InjectArrayAdapter;
import com.danikula.aibolit.annotation.InjectOnCheckedChangeListener;
import com.danikula.aibolit.annotation.InjectOnClickListener;
import com.danikula.aibolit.annotation.InjectOnCreateContextMenuListener;
import com.danikula.aibolit.annotation.InjectOnEditorActionListener;
import com.danikula.aibolit.annotation.InjectOnFocusChangeListener;
import com.danikula.aibolit.annotation.InjectOnItemClickListener;
import com.danikula.aibolit.annotation.InjectOnItemSelectedListener;
import com.danikula.aibolit.annotation.InjectOnKeyListener;
import com.danikula.aibolit.annotation.InjectOnLongClickListener;
import com.danikula.aibolit.annotation.InjectOnRadioGroupCheckedChangeListener;
import com.danikula.aibolit.annotation.InjectOnTextChangedListener;
import com.danikula.aibolit.annotation.InjectOnTouchListener;
import com.danikula.aibolit.annotation.InjectResource;
import com.danikula.aibolit.annotation.InjectService;
import com.danikula.aibolit.annotation.InjectSystemService;
import com.danikula.aibolit.annotation.InjectView;
        INJECTORS_REGISTER.put(InjectOnKeyListener.class, new OnKeyListenerInjector());
        INJECTORS_REGISTER.put(InjectOnFocusChangeListener.class, new OnFocusChangeListenerInjector());
        INJECTORS_REGISTER.put(InjectOnCreateContextMenuListener.class, new OnCreateContextMenuListenerInjector());
        INJECTORS_REGISTER.put(InjectOnTextChangedListener.class, new OnTextChangedListenerInjector());
        INJECTORS_REGISTER.put(InjectOnCheckedChangeListener.class, new OnCheckedChangeInjector());
        INJECTORS_REGISTER.put(InjectOnRadioGroupCheckedChangeListener.class, new OnRadioGroupCheckedChangeInjector());
        INJECTORS_REGISTER.put(InjectOnEditorActionListener.class, new OnEditorActionListenerInjector());
    }

    public static boolean contains(Class<? extends Annotation> annotationClass) {
        return INJECTORS_REGISTER.containsKey(annotationClass);
    }

    public static AbstractFieldInjector<Annotation> getFieldInjector(Class<? extends Annotation> annotationClass) {
        AbstractInjector<?> abstractInjector = INJECTORS_REGISTER.get(annotationClass);
        if (!(abstractInjector instanceof AbstractFieldInjector)){
            throw new InjectingException("There is no registered AbstractFieldInjector for annotation class "  + annotationClass.getName());
        }
        return (AbstractFieldInjector<Annotation>) abstractInjector;
    }
    
    public static AbstractMethodInjector<Annotation> getMethodInjector(Class<? extends Annotation> annotationClass) {
        AbstractInjector<?> abstractInjector = INJECTORS_REGISTER.get(annotationClass);
        if (!(abstractInjector instanceof AbstractMethodInjector)){
            throw new InjectingException("There is no registered AbstractMethodInjector for annotation class "  + annotationClass.getName());
        }
        return (AbstractMethodInjector<Annotation>) abstractInjector;
    }
    
    public static void addServicesResolver(ServicesResolver serviceResolver){
// Path: library/src/main/java/com/danikula/aibolit/InjectingException.java
// public class InjectingException extends RuntimeException {
// 
//     private static final long serialVersionUID = -1L;
// 
//     public InjectingException(String message) {
//         super(message);
//     }
// 
//     public InjectingException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public InjectingException(Throwable cause) {
//         super(cause);
//     }
// }
// 
// Path: library/src/main/java/com/danikula/aibolit/ServicesResolver.java
// public interface ServicesResolver {
// 
//     /**
//      * Resolves application service by class
//      * 
//      * @param serviceClass Class service's class
//      * @return Object application service
//      */
//     Object resolve(Class<?> serviceClass);
// 
// }
// 
// Path: library/src/main/java/com/danikula/aibolit/Validate.java
// public class Validate {
// 
//     /**
//      * Checks variable on <code>null</code>
//      * 
//      * @param object Object variable to be checked
//      * @param message String message of exception to be throwed if parameter is <code>null</code>
//      * @throws IllegalArgumentException if <code>object</code> is <code>null</code>
//      */
//     public static void notNull(Object object, String message) {
//         if (object == null) {
//             throw new IllegalArgumentException(message);
//         }
//     }
// 
//     /**
//      * Checks contition on <code>true</code>
//      * 
//      * @param condition boolean condition to check
//      * @param message String message of exception to be throwed if condition is not <code>true</code>
//      * @throws IllegalArgumentException if <code>condition</code> is not <code>true</code>
//      */
//     public static void checkTrue(boolean condition, String message) {
//         if (!condition) {
//             throw new IllegalArgumentException(message);
//         }
//     }
// 
// }


// Path: library/src/main/java/com/danikula/aibolit/injector/InjectorRegister.java
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.danikula.aibolit.InjectingException;
import com.danikula.aibolit.ServicesResolver;
import com.danikula.aibolit.Validate;
import com.danikula.aibolit.annotation.InjectArrayAdapter;
import com.danikula.aibolit.annotation.InjectOnCheckedChangeListener;
import com.danikula.aibolit.annotation.InjectOnClickListener;
import com.danikula.aibolit.annotation.InjectOnCreateContextMenuListener;
import com.danikula.aibolit.annotation.InjectOnEditorActionListener;
import com.danikula.aibolit.annotation.InjectOnFocusChangeListener;
import com.danikula.aibolit.annotation.InjectOnItemClickListener;
import com.danikula.aibolit.annotation.InjectOnItemSelectedListener;
import com.danikula.aibolit.annotation.InjectOnKeyListener;
import com.danikula.aibolit.annotation.InjectOnLongClickListener;
import com.danikula.aibolit.annotation.InjectOnRadioGroupCheckedChangeListener;
import com.danikula.aibolit.annotation.InjectOnTextChangedListener;
import com.danikula.aibolit.annotation.InjectOnTouchListener;
import com.danikula.aibolit.annotation.InjectResource;
import com.danikula.aibolit.annotation.InjectService;
import com.danikula.aibolit.annotation.InjectSystemService;
import com.danikula.aibolit.annotation.InjectView;

        INJECTORS_REGISTER.put(InjectOnKeyListener.class, new OnKeyListenerInjector());
        INJECTORS_REGISTER.put(InjectOnFocusChangeListener.class, new OnFocusChangeListenerInjector());
        INJECTORS_REGISTER.put(InjectOnCreateContextMenuListener.class, new OnCreateContextMenuListenerInjector());
        INJECTORS_REGISTER.put(InjectOnTextChangedListener.class, new OnTextChangedListenerInjector());
        INJECTORS_REGISTER.put(InjectOnCheckedChangeListener.class, new OnCheckedChangeInjector());
        INJECTORS_REGISTER.put(InjectOnRadioGroupCheckedChangeListener.class, new OnRadioGroupCheckedChangeInjector());
        INJECTORS_REGISTER.put(InjectOnEditorActionListener.class, new OnEditorActionListenerInjector());
    }

    public static boolean contains(Class<? extends Annotation> annotationClass) {
        return INJECTORS_REGISTER.containsKey(annotationClass);
    }

    public static AbstractFieldInjector<Annotation> getFieldInjector(Class<? extends Annotation> annotationClass) {
        AbstractInjector<?> abstractInjector = INJECTORS_REGISTER.get(annotationClass);
        if (!(abstractInjector instanceof AbstractFieldInjector)){
            throw new InjectingException("There is no registered AbstractFieldInjector for annotation class "  + annotationClass.getName());
        }
        return (AbstractFieldInjector<Annotation>) abstractInjector;
    }
    
    public static AbstractMethodInjector<Annotation> getMethodInjector(Class<? extends Annotation> annotationClass) {
        AbstractInjector<?> abstractInjector = INJECTORS_REGISTER.get(annotationClass);
        if (!(abstractInjector instanceof AbstractMethodInjector)){
            throw new InjectingException("There is no registered AbstractMethodInjector for annotation class "  + annotationClass.getName());
        }
        return (AbstractMethodInjector<Annotation>) abstractInjector;
    }
    
    public static void addServicesResolver(ServicesResolver serviceResolver){
        Validate.notNull(serviceResolver, "InjectionResolver must be not null");