```java
/**
* Return the {@link ILoggerFactory} instance in use.
* <p/>
* <p/>
* ILoggerFactory instance is bound with this class at compile time.
*
* @return the ILoggerFactory instance in use
*/
public static ILoggerFactory getILoggerFactory() {
if (INITIALIZATION_STATE == UNINITIALIZED) {
synchronized (LoggerFactory.class) {
if (INITIALIZATION_STATE == UNINITIALIZED) {
INITIALIZATION_STATE = ONGOING_INITIALIZATION;
performInitialization();
}
}
}
switch (INITIALIZATION_STATE) {
case SUCCESSFUL_INITIALIZATION:
return StaticLoggerBinder.getSingleton().getLoggerFactory();
case NOP_FALLBACK_INITIALIZATION:
return NOP_FALLBACK_FACTORY;
case FAILED_INITIALIZATION:
throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
case ONGOING_INITIALIZATION:
return SUBST_FACTORY;
}
throw new IllegalStateException("Unreachable code");
}
```
```java
private final static void bind() {
try {
Set<URL> staticLoggerBinderPathSet = null;
if (!isAndroid()) {
staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
}
StaticLoggerBinder.getSingleton();
INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
reportActualBinding(staticLoggerBinderPathSet);
fixSubstitutedLoggers();
playRecordedEvents();
SUBST_FACTORY.clear();
} catch (NoClassDefFoundError ncde) {
String msg = ncde.getMessage();
if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
Util.report("Defaulting to no-operation (NOP) logger implementation");
Util.report("See " + NO_STATICLOGGERBINDER_URL + " for further details.");
} else {
failedBinding(ncde);
throw ncde;
}
} catch (java.lang.NoSuchMethodError nsme) {
String msg = nsme.getMessage();
if (msg != null && msg.contains("org.slf4j.impl.StaticLoggerBinder.getSingleton()")) {
INITIALIZATION_STATE = FAILED_INITIALIZATION;
Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
Util.report("Your binding is version 1.5.5 or earlier.");
Util.report("Upgrade your binding to version 1.6.x.");
}
throw nsme;
} catch (Exception e) {
failedBinding(e);
throw new IllegalStateException("Unexpected initialization failure", e);
}
}
```
```java
private static void playRecordedEvents() {
List<SubstituteLoggingEvent> events = SUBST_FACTORY.getEventList();
if (events.isEmpty()) {
return;
}
for (int i = 0; i < events.size(); i++) {
SubstituteLoggingEvent event = events.get(i);
SubstituteLogger substLogger = event.getLogger();
if (substLogger.isDelegateNOP()) {
break;
} else if (substLogger.isDelegateEventAware()) {
if (i == 0)
emitReplayWarning(events.size());
substLogger.log(event);
} else {
if (i == 0)
emitSubstitutionWarning();
Util.report(substLogger.getName());
}
}
}
private final static void fixSubstitutedLoggers() {
List<SubstituteLogger> loggers = SUBST_FACTORY.getLoggers();
if (loggers.isEmpty()) {
return;
}
for (SubstituteLogger subLogger : loggers) {
Logger logger = getLogger(subLogger.getName());
subLogger.setDelegate(logger);
}
}
```
```java
public class SubstituteLogger implements Logger {
…………………………
public SubstituteLogger(String name, List<SubstituteLoggingEvent> eventList) {
this.name = name;
this.eventList = eventList;
}
public void debug(String msg) {
delegate().debug(msg);
}
…………………………
/**
* Return the delegate logger instance if set. Otherwise, return a {@link NOPLogger}
* instance.
*/
Logger delegate() {
return _delegate != null ? _delegate : getEventRecordingLogger();
}
private Logger getEventRecordingLogger() {
if (eventRecodingLogger == null) {
eventRecodingLogger = new EventRecodingLogger(this, eventList);
}
return eventRecodingLogger;
}
/**
* Typically called after the {@link org.slf4j.LoggerFactory} initialization phase is completed.
* @param delegate
*/
public void setDelegate(Logger delegate) {
this._delegate = delegate;
}
public boolean isDelegateEventAware() {
if (delegateEventAware != null)
return delegateEventAware;
try {
logMethodCache = _delegate.getClass().getMethod("log", LoggingEvent.class);
delegateEventAware = Boolean.TRUE;
} catch (NoSuchMethodException e) {
delegateEventAware = Boolean.FALSE;
}
return delegateEventAware;
}
}
```