// Path: src/main/java/com/github/vbauer/herald/exception/LoggerInstantiationException.java
// @SuppressWarnings("serial")
// public class LoggerInstantiationException extends HeraldException {
// 
//     private final LogFactory loggerFactory;
// 
// 
//     public LoggerInstantiationException(final LogFactory loggerFactory) {
//         this.loggerFactory = loggerFactory;
//     }
// 
// 
//     /**
//      * Get logger factory, see {@link LogFactory}.
//      *
//      * @return logger factory
//      */
//     public LogFactory getLoggerFactory() {
//         return loggerFactory;
//     }
// 
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public String getMessage() {
//         return String.format("Can't create logger using factory %s", getLoggerFactory());
//     }
// 
// }
// 
// Path: src/main/java/com/github/vbauer/herald/exception/MissedLogFactoryException.java
// @SuppressWarnings("serial")
// public class MissedLogFactoryException extends HeraldException {
// 
//     private final Class<?> loggerClass;
// 
// 
//     public MissedLogFactoryException(final Class<?> loggerClass) {
//         this.loggerClass = loggerClass;
//     }
// 
// 
//     /**
//      * Get logger class.
//      *
//      * @return logger class
//      */
//     public Class<?> getLoggerClass() {
//         return loggerClass;
//     }
// 
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public String getMessage() {
//         return String.format("Can not find log factory for logger %s", getLoggerClass());
//     }
// 
// }
// 
// Path: src/main/java/com/github/vbauer/herald/logger/LogFactory.java
// public interface LogFactory {
// 
//     /**
//      * Check if logger class is compatible with the log factory.
//      *
//      * @param loggerClass logger class
//      * @return true if compatible and false - otherwise
//      */
//     boolean isCompatible(Class<?> loggerClass);
// 
//     /**
//      * Create logger with the given name (as configuration parameter).
//      *
//      * @param name logger name
//      * @return logger instance
//      */
//     Object createLogger(String name);
// 
//     /**
//      * Create logger with the given class (as configuration parameter).
//      *
//      * @param clazz class
//      * @return logger instance
//      */
//     Object createLogger(Class<?> clazz);
// 
// }
// 
// Path: src/main/java/com/github/vbauer/herald/util/ReflectionUtils.java
// public final class ReflectionUtils {
// 
//     private ReflectionUtils() {
//         throw new UnsupportedOperationException();
//     }
// 
// 
//     public static boolean isAssignableFrom(final String className, final Class<?> from) {
//         try {
//             final Class<?> clazz = Class.forName(className);
//             return clazz.isAssignableFrom(from);
//         } catch (final Throwable ex) {
//             return false;
//         }
//     }
// 
//     @SuppressWarnings("unchecked")
//     public  static <I, O> O invokeStatic(final String className, final String methodName, final I argument) {
//         try {
//             final Class<?> clazz = Class.forName(className);
//             final Class<?> argumentClass = argument.getClass();
// 
//             final Method method = clazz.getDeclaredMethod(methodName, argumentClass);
//             return (O) method.invoke(null, argument);
//         } catch (final Exception ex) {
//             return handleReflectionException(ex);
//         }
//     }
// 
//     public static <T> T handleReflectionException(final Throwable ex) {
//         if (ex instanceof RuntimeException) {
//             throw (RuntimeException) ex;
//         } else if (ex instanceof Error) {
//             throw (Error) ex;
//         }
//         throw new RuntimeException(ex);
//     }
// 
//     public static <T extends Annotation> T findAnnotation(
//         final Class<T> annotationClass, final Class<?> beanClass, final Field field
//     ) {
//         final T fieldAnnotation = field.getAnnotation(annotationClass);
//         return fieldAnnotation == null ? beanClass.getAnnotation(annotationClass) : fieldAnnotation;
//     }
// 
//     public static boolean setAccessible(final AccessibleObject object, final boolean accessible) {
//         try {
//             object.setAccessible(accessible);
//             return true;
//         } catch (final Throwable ignored) {
//             // Ignored.
//             return false;
//         }
//     }
// 
// }
// 
// Path: src/main/java/com/github/vbauer/herald/util/ServiceLoaderUtils.java
// public final class ServiceLoaderUtils {
// 
//     private ServiceLoaderUtils() {
//         throw new UnsupportedOperationException();
//     }
// 
// 
//     public static <T> Collection<T> load(final Class<T> beanClass) {
//         final ServiceLoader<T> serviceLoader = ServiceLoader.load(beanClass);
//         final Iterator<T> iterator = serviceLoader.iterator();
// 
//         final List<T> result = new ArrayList<>();
//         while (iterator.hasNext()) {
//             result.add(iterator.next());
//         }
//         return result;
//     }
// 
// }


import com.github.vbauer.herald.annotation.Log;
import com.github.vbauer.herald.exception.LoggerInstantiationException;
import com.github.vbauer.herald.exception.MissedLogFactoryException;
import com.github.vbauer.herald.logger.LogFactory;
import com.github.vbauer.herald.util.ReflectionUtils;
import com.github.vbauer.herald.util.ServiceLoaderUtils;
import java.lang.reflect.Field;
import java.util.Collection;
            if (required) {
                ReflectionUtils.handleReflectionException(ex);
            }
        } finally {
            ReflectionUtils.setAccessible(field, isAccessible);
        }
    }

    private static Object createLogger(
        final Class<?> beanClass, final Class<?> loggerClass, final String loggerName
    ) {
        // Find corresponding logger factory.
        final LogFactory logFactory =
            LogFactoryDetector.findCompatible(LOG_FACTORIES, loggerClass);

        if (logFactory == null) {
            throw new MissedLogFactoryException(loggerClass);
        }

        // Create logger.
        final Object logger = !loggerName.isEmpty()
            ? logFactory.createLogger(loggerName) : logFactory.createLogger(beanClass);

        if (logger == null) {
            throw new LoggerInstantiationException(logFactory);
        }
        return logger;
    }

    private static Collection<LogFactory> loadLogFactories() {
// Path: src/main/java/com/github/vbauer/herald/exception/LoggerInstantiationException.java
// @SuppressWarnings("serial")
// public class LoggerInstantiationException extends HeraldException {
// 
//     private final LogFactory loggerFactory;
// 
// 
//     public LoggerInstantiationException(final LogFactory loggerFactory) {
//         this.loggerFactory = loggerFactory;
//     }
// 
// 
//     /**
//      * Get logger factory, see {@link LogFactory}.
//      *
//      * @return logger factory
//      */
//     public LogFactory getLoggerFactory() {
//         return loggerFactory;
//     }
// 
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public String getMessage() {
//         return String.format("Can't create logger using factory %s", getLoggerFactory());
//     }
// 
// }
// 
// Path: src/main/java/com/github/vbauer/herald/exception/MissedLogFactoryException.java
// @SuppressWarnings("serial")
// public class MissedLogFactoryException extends HeraldException {
// 
//     private final Class<?> loggerClass;
// 
// 
//     public MissedLogFactoryException(final Class<?> loggerClass) {
//         this.loggerClass = loggerClass;
//     }
// 
// 
//     /**
//      * Get logger class.
//      *
//      * @return logger class
//      */
//     public Class<?> getLoggerClass() {
//         return loggerClass;
//     }
// 
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public String getMessage() {
//         return String.format("Can not find log factory for logger %s", getLoggerClass());
//     }
// 
// }
// 
// Path: src/main/java/com/github/vbauer/herald/logger/LogFactory.java
// public interface LogFactory {
// 
//     /**
//      * Check if logger class is compatible with the log factory.
//      *
//      * @param loggerClass logger class
//      * @return true if compatible and false - otherwise
//      */
//     boolean isCompatible(Class<?> loggerClass);
// 
//     /**
//      * Create logger with the given name (as configuration parameter).
//      *
//      * @param name logger name
//      * @return logger instance
//      */
//     Object createLogger(String name);
// 
//     /**
//      * Create logger with the given class (as configuration parameter).
//      *
//      * @param clazz class
//      * @return logger instance
//      */
//     Object createLogger(Class<?> clazz);
// 
// }
// 
// Path: src/main/java/com/github/vbauer/herald/util/ReflectionUtils.java
// public final class ReflectionUtils {
// 
//     private ReflectionUtils() {
//         throw new UnsupportedOperationException();
//     }
// 
// 
//     public static boolean isAssignableFrom(final String className, final Class<?> from) {
//         try {
//             final Class<?> clazz = Class.forName(className);
//             return clazz.isAssignableFrom(from);
//         } catch (final Throwable ex) {
//             return false;
//         }
//     }
// 
//     @SuppressWarnings("unchecked")
//     public  static <I, O> O invokeStatic(final String className, final String methodName, final I argument) {
//         try {
//             final Class<?> clazz = Class.forName(className);
//             final Class<?> argumentClass = argument.getClass();
// 
//             final Method method = clazz.getDeclaredMethod(methodName, argumentClass);
//             return (O) method.invoke(null, argument);
//         } catch (final Exception ex) {
//             return handleReflectionException(ex);
//         }
//     }
// 
//     public static <T> T handleReflectionException(final Throwable ex) {
//         if (ex instanceof RuntimeException) {
//             throw (RuntimeException) ex;
//         } else if (ex instanceof Error) {
//             throw (Error) ex;
//         }
//         throw new RuntimeException(ex);
//     }
// 
//     public static <T extends Annotation> T findAnnotation(
//         final Class<T> annotationClass, final Class<?> beanClass, final Field field
//     ) {
//         final T fieldAnnotation = field.getAnnotation(annotationClass);
//         return fieldAnnotation == null ? beanClass.getAnnotation(annotationClass) : fieldAnnotation;
//     }
// 
//     public static boolean setAccessible(final AccessibleObject object, final boolean accessible) {
//         try {
//             object.setAccessible(accessible);
//             return true;
//         } catch (final Throwable ignored) {
//             // Ignored.
//             return false;
//         }
//     }
// 
// }
// 
// Path: src/main/java/com/github/vbauer/herald/util/ServiceLoaderUtils.java
// public final class ServiceLoaderUtils {
// 
//     private ServiceLoaderUtils() {
//         throw new UnsupportedOperationException();
//     }
// 
// 
//     public static <T> Collection<T> load(final Class<T> beanClass) {
//         final ServiceLoader<T> serviceLoader = ServiceLoader.load(beanClass);
//         final Iterator<T> iterator = serviceLoader.iterator();
// 
//         final List<T> result = new ArrayList<>();
//         while (iterator.hasNext()) {
//             result.add(iterator.next());
//         }
//         return result;
//     }
// 
// }


// Path: src/main/java/com/github/vbauer/herald/injector/LoggerInjector.java
import com.github.vbauer.herald.annotation.Log;
import com.github.vbauer.herald.exception.LoggerInstantiationException;
import com.github.vbauer.herald.exception.MissedLogFactoryException;
import com.github.vbauer.herald.logger.LogFactory;
import com.github.vbauer.herald.util.ReflectionUtils;
import com.github.vbauer.herald.util.ServiceLoaderUtils;
import java.lang.reflect.Field;
import java.util.Collection;

            if (required) {
                ReflectionUtils.handleReflectionException(ex);
            }
        } finally {
            ReflectionUtils.setAccessible(field, isAccessible);
        }
    }

    private static Object createLogger(
        final Class<?> beanClass, final Class<?> loggerClass, final String loggerName
    ) {
        // Find corresponding logger factory.
        final LogFactory logFactory =
            LogFactoryDetector.findCompatible(LOG_FACTORIES, loggerClass);

        if (logFactory == null) {
            throw new MissedLogFactoryException(loggerClass);
        }

        // Create logger.
        final Object logger = !loggerName.isEmpty()
            ? logFactory.createLogger(loggerName) : logFactory.createLogger(beanClass);

        if (logger == null) {
            throw new LoggerInstantiationException(logFactory);
        }
        return logger;
    }

    private static Collection<LogFactory> loadLogFactories() {
        return ServiceLoaderUtils.load(LogFactory.class);