/**
 * Copyright (c) 2004-2011 QOS.ch
 * All rights reserved.
 *
 * Permission is hereby granted, free  of charge, to any person obtaining
 * a  copy  of this  software  and  associated  documentation files  (the
 * "Software"), to  deal in  the Software without  restriction, including
 * without limitation  the rights to  use, copy, modify,  merge, publish,
 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
 * permit persons to whom the Software  is furnished to do so, subject to
 * the following conditions:
 *
 * The  above  copyright  notice  and  this permission  notice  shall  be
 * included in all copies or substantial portions of the Software.
 *
 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */
package org.slf4j.ext;

import org.slf4j.Logger;
import org.slf4j.Marker;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;
import org.slf4j.spi.LocationAwareLogger;

/**
 * A helper class wrapping an {@link org.slf4j.Logger} instance preserving
 * location information if the wrapped instance supports it.
 * 
 * @author Ralph Goers
 * @author Ceki G&uuml;lc&uuml;
 */
public class LoggerWrapper implements Logger {

  // To ensure consistency between two instances sharing the same name
  // (homonyms)
  // a LoggerWrapper should not contain any state beyond
  // the Logger instance it wraps.
  // Note that 'instanceofLAL' directly depends on Logger.
  // fqcn depend on the caller, but its value would not be different
  // between successive invocations of a factory class

  protected final Logger logger;
  final String fqcn;
  // is this logger instance a LocationAwareLogger
  protected final boolean instanceofLAL;

  public LoggerWrapper(Logger logger, String fqcn) {
    this.logger = logger;
    this.fqcn = fqcn;
    if (logger instanceof LocationAwareLogger) {
      instanceofLAL = true;
    } else {
      instanceofLAL = false;
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public boolean isTraceEnabled() {
    return logger.isTraceEnabled();
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public boolean isTraceEnabled(Marker marker) {
    return logger.isTraceEnabled(marker);
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void trace(String msg) {
    if (!logger.isTraceEnabled())
      return;

    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.TRACE_INT, msg, null, null);
    } else {
      logger.trace(msg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void trace(String format, Object arg) {
    if (!logger.isTraceEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.TRACE_INT, formattedMessage,
          new Object[] { arg }, null);
    } else {
      logger.trace(format, arg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void trace(String format, Object arg1, Object arg2) {
    if (!logger.isTraceEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg1, arg2)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.TRACE_INT, formattedMessage, new Object[] { arg1,
              arg2 }, null);
    } else {
      logger.trace(format, arg1, arg2);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void trace(String format, Object... args) {
    if (!logger.isTraceEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.arrayFormat(format, args)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.TRACE_INT, formattedMessage, args, null);
    } else {
      logger.trace(format, args);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void trace(String msg, Throwable t) {
    if (!logger.isTraceEnabled())
      return;

    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.TRACE_INT, msg, null, t);
    } else {
      logger.trace(msg, t);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void trace(Marker marker, String msg) {
    if (!logger.isTraceEnabled(marker))
      return;
    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.TRACE_INT, msg, null, null);
    } else {
      logger.trace(marker, msg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void trace(Marker marker, String format, Object arg) {
    if (!logger.isTraceEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.TRACE_INT, formattedMessage,
          new Object[] { arg }, null);
    } else {
      logger.trace(marker, format, arg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void trace(Marker marker, String format, Object arg1, Object arg2) {
    if (!logger.isTraceEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg1, arg2)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.TRACE_INT, formattedMessage, new Object[] { arg1,
              arg2 }, null);
    } else {
      logger.trace(marker, format, arg1, arg2);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void trace(Marker marker, String format, Object... args) {
    if (!logger.isTraceEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.arrayFormat(format, args)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.TRACE_INT, formattedMessage, args, null);
    } else {
      logger.trace(marker, format, args);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void trace(Marker marker, String msg, Throwable t) {
    if (!logger.isTraceEnabled(marker))
      return;
    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.TRACE_INT, msg, null, t);
    } else {
      logger.trace(marker, msg, t);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public boolean isDebugEnabled() {
    return logger.isDebugEnabled();
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public boolean isDebugEnabled(Marker marker) {
    return logger.isDebugEnabled(marker);
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void debug(String msg) {
    if (!logger.isDebugEnabled())
      return;

    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.DEBUG_INT, msg, null, null);
    } else {
      logger.debug(msg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void debug(String format, Object arg) {
    if (!logger.isDebugEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.DEBUG_INT, formattedMessage,
          new Object[] { arg }, null);
    } else {
      logger.debug(format, arg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void debug(String format, Object arg1, Object arg2) {
    if (!logger.isDebugEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg1, arg2)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.DEBUG_INT, formattedMessage, new Object[] { arg1,
              arg2 }, null);
    } else {
      logger.debug(format, arg1, arg2);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void debug(String format, Object... argArray) {
    if (!logger.isDebugEnabled())
      return;

    if (instanceofLAL) {
      FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.DEBUG_INT, ft.getMessage(), ft.getArgArray(), ft
              .getThrowable());
    } else {
      logger.debug(format, argArray);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void debug(String msg, Throwable t) {
    if (!logger.isDebugEnabled())
      return;

    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.DEBUG_INT, msg, null, t);
    } else {
      logger.debug(msg, t);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void debug(Marker marker, String msg) {
    if (!logger.isDebugEnabled(marker))
      return;
    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.DEBUG_INT, msg, null, null);
    } else {
      logger.debug(marker, msg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void debug(Marker marker, String format, Object arg) {
    if (!logger.isDebugEnabled(marker))
      return;
    if (instanceofLAL) {
      FormattingTuple ft = MessageFormatter.format(format, arg);
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.DEBUG_INT, ft.getMessage(), ft.getArgArray(), ft
              .getThrowable());
    } else {
      logger.debug(marker, format, arg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void debug(Marker marker, String format, Object arg1, Object arg2) {
    if (!logger.isDebugEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg1, arg2)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.DEBUG_INT, formattedMessage, new Object[] { arg1,
              arg2 }, null);
    } else {
      logger.debug(marker, format, arg1, arg2);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void debug(Marker marker, String format, Object... argArray) {
    if (!logger.isDebugEnabled(marker))
      return;
    if (instanceofLAL) {

      FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.DEBUG_INT, ft.getMessage(), argArray, ft
              .getThrowable());
    } else {
      logger.debug(marker, format, argArray);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void debug(Marker marker, String msg, Throwable t) {
    if (!logger.isDebugEnabled(marker))
      return;
    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.DEBUG_INT, msg, null, t);
    } else {
      logger.debug(marker, msg, t);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public boolean isInfoEnabled() {
    return logger.isInfoEnabled();
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public boolean isInfoEnabled(Marker marker) {
    return logger.isInfoEnabled(marker);
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void info(String msg) {
    if (!logger.isInfoEnabled())
      return;

    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.INFO_INT, msg, null, null);
    } else {
      logger.info(msg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void info(String format, Object arg) {
    if (!logger.isInfoEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.INFO_INT, formattedMessage, new Object[] { arg },
          null);
    } else {
      logger.info(format, arg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void info(String format, Object arg1, Object arg2) {
    if (!logger.isInfoEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg1, arg2)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.INFO_INT, formattedMessage, new Object[] { arg1,
              arg2 }, null);
    } else {
      logger.info(format, arg1, arg2);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void info(String format, Object... args) {
    if (!logger.isInfoEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.arrayFormat(format, args)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.INFO_INT, formattedMessage, args, null);
    } else {
      logger.info(format, args);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void info(String msg, Throwable t) {
    if (!logger.isInfoEnabled())
      return;

    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.INFO_INT, msg, null, t);
    } else {
      logger.info(msg, t);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void info(Marker marker, String msg) {
    if (!logger.isInfoEnabled(marker))
      return;
    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.INFO_INT, msg, null, null);
    } else {
      logger.info(marker, msg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void info(Marker marker, String format, Object arg) {
    if (!logger.isInfoEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.INFO_INT, formattedMessage, new Object[] { arg },
          null);
    } else {
      logger.info(marker, format, arg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void info(Marker marker, String format, Object arg1, Object arg2) {
    if (!logger.isInfoEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg1, arg2)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.INFO_INT, formattedMessage, new Object[] { arg1,
              arg2 }, null);
    } else {
      logger.info(marker, format, arg1, arg2);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void info(Marker marker, String format, Object... args) {
    if (!logger.isInfoEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.arrayFormat(format, args)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.INFO_INT, formattedMessage, args, null);
    } else {
      logger.info(marker, format, args);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void info(Marker marker, String msg, Throwable t) {
    if (!logger.isInfoEnabled(marker))
      return;
    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.INFO_INT, msg, null, t);
    } else {
      logger.info(marker, msg, t);
    }
  }

  public boolean isWarnEnabled() {
    return logger.isWarnEnabled();
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public boolean isWarnEnabled(Marker marker) {
    return logger.isWarnEnabled(marker);
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void warn(String msg) {
    if (!logger.isWarnEnabled())
      return;

    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.WARN_INT, msg, null, null);
    } else {
      logger.warn(msg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void warn(String format, Object arg) {
    if (!logger.isWarnEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.WARN_INT, formattedMessage, new Object[] { arg },
          null);
    } else {
      logger.warn(format, arg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void warn(String format, Object arg1, Object arg2) {
    if (!logger.isWarnEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg1, arg2)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.WARN_INT, formattedMessage, new Object[] { arg1,
              arg2 }, null);
    } else {
      logger.warn(format, arg1, arg2);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void warn(String format, Object... args) {
    if (!logger.isWarnEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.arrayFormat(format, args)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.WARN_INT, formattedMessage, args, null);
    } else {
      logger.warn(format, args);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void warn(String msg, Throwable t) {
    if (!logger.isWarnEnabled())
      return;

    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.WARN_INT, msg, null, t);
    } else {
      logger.warn(msg, t);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void warn(Marker marker, String msg) {
    if (!logger.isWarnEnabled(marker))
      return;
    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.WARN_INT, msg, null, null);
    } else {
      logger.warn(marker, msg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void warn(Marker marker, String format, Object arg) {
    if (!logger.isWarnEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.WARN_INT, formattedMessage, new Object[] { arg },
          null);
    } else {
      logger.warn(marker, format, arg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void warn(Marker marker, String format, Object arg1, Object arg2) {
    if (!logger.isWarnEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg1, arg2)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.WARN_INT, formattedMessage, new Object[] { arg1,
              arg2 }, null);
    } else {
      logger.warn(marker, format, arg1, arg2);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void warn(Marker marker, String format, Object... args) {
    if (!logger.isWarnEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.arrayFormat(format, args)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.WARN_INT, formattedMessage, args, null);
    } else {
      logger.warn(marker, format, args);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void warn(Marker marker, String msg, Throwable t) {
    if (!logger.isWarnEnabled(marker))
      return;
    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.WARN_INT, msg, null, t);
    } else {
      logger.warn(marker, msg, t);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public boolean isErrorEnabled() {
    return logger.isErrorEnabled();
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public boolean isErrorEnabled(Marker marker) {
    return logger.isErrorEnabled(marker);
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void error(String msg) {
    if (!logger.isErrorEnabled())
      return;

    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.ERROR_INT, msg, null, null);
    } else {
      logger.error(msg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void error(String format, Object arg) {
    if (!logger.isErrorEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.ERROR_INT, formattedMessage,
          new Object[] { arg }, null);
    } else {
      logger.error(format, arg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void error(String format, Object arg1, Object arg2) {
    if (!logger.isErrorEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg1, arg2)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.ERROR_INT, formattedMessage, new Object[] { arg1,
              arg2 }, null);
    } else {
      logger.error(format, arg1, arg2);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void error(String format, Object... args) {
    if (!logger.isErrorEnabled())
      return;

    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.arrayFormat(format, args)
          .getMessage();
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.ERROR_INT, formattedMessage, args, null);
    } else {
      logger.error(format, args);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void error(String msg, Throwable t) {
    if (!logger.isErrorEnabled())
      return;

    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(null, fqcn,
          LocationAwareLogger.ERROR_INT, msg, null, t);
    } else {
      logger.error(msg, t);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void error(Marker marker, String msg) {
    if (!logger.isErrorEnabled(marker))
      return;
    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.ERROR_INT, msg, null, null);
    } else {
      logger.error(marker, msg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void error(Marker marker, String format, Object arg) {
    if (!logger.isErrorEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.ERROR_INT, formattedMessage,
          new Object[] { arg }, null);
    } else {
      logger.error(marker, format, arg);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void error(Marker marker, String format, Object arg1, Object arg2) {
    if (!logger.isErrorEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.format(format, arg1, arg2)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.ERROR_INT, formattedMessage, new Object[] { arg1,
              arg2 }, null);
    } else {
      logger.error(marker, format, arg1, arg2);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void error(Marker marker, String format, Object... args) {
    if (!logger.isErrorEnabled(marker))
      return;
    if (instanceofLAL) {
      String formattedMessage = MessageFormatter.arrayFormat(format, args)
          .getMessage();
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.ERROR_INT, formattedMessage, args, null);
    } else {
      logger.error(marker, format, args);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public void error(Marker marker, String msg, Throwable t) {
    if (!logger.isErrorEnabled(marker))
      return;
    if (instanceofLAL) {
      ((LocationAwareLogger) logger).log(marker, fqcn,
          LocationAwareLogger.ERROR_INT, msg, null, t);
    } else {
      logger.error(marker, msg, t);
    }
  }

  /**
   * Delegate to the appropriate method of the underlying logger.
   */
  public String getName() {
    return logger.getName();
  }
}
