function AdfLogger(loggerName, logWriter, level) {
  this.Init(loggerName, logWriter, level);
}
AdfObject.createSubclass(AdfLogger);
AdfLogger.getLogger = function(loggerName) {
  if (!loggerName) {
    loggername = "global";
  }
  return AdfLogger._LOGGERS[loggerName];
};
AdfLogger.prototype.register = function() {
  var loggers = AdfLogger._LOGGERS;
  var loggerName = this.getName();
  var oldLogger = loggers[loggerName];
  if (this !== oldLogger) {
    if (oldLogger) {
      var oldLogWriter = oldLogger.getLogWriter();
      if (AdfBufferedLogWriter.prototype.isPrototypeOf(oldLogWriter)) {
        this.logRecords(oldLogWriter.getLogRecords());
      }
      oldLogWriter.close();
    }
    loggers[loggerName] = this;
  }
  return oldLogger;
};
AdfLogger.prototype.getName = function() {
  return this._loggerName;
};
AdfLogger.prototype.setLevel = function(level) {
  AdfAssert.assertNumeric(level);
  this._level = level;
};
AdfLogger.prototype.getLevel = function() {
  return this._level;
};
AdfLogger.prototype.isLoggable = function(level) {
  return level >= this._level;
};
AdfLogger.prototype.getName = function() {
  return this._loggerName;
};
AdfLogger.prototype.getLogWriter = function() {
  return this._logWriter;
};
AdfLogger.prototype.setFilter = function(newFilter) {
  AdfAssert.assertFunctionOrNull(newFilter);
  this._filter = newFilter;
};
AdfLogger.prototype.getFilter = function() {
  return this._filter;
};
AdfLogger.prototype.log = function(logRecord) {
  AdfAssert.assert(logRecord);
  var level = logRecord.level;
  if (level < this._level) {
    return;
  }
  this.AddLogRecord(logRecord);
};
AdfLogger.prototype.logRecords = function(logRecords) {
  AdfAssert.assert(logRecords);
  var recordCount = logRecords.length;
  for (var i = 0;i < recordCount;i++) {
    this.log(logRecords[i]);
  }
};
AdfLogger.prototype.logMessage = function(level, messages) {
  AdfAssert.assertNumeric(level);
  if (level < this._level) {
    return;
  }
  this._calcMsg["_skipArgs"] = 1;
  var message = this._calcMsg.apply(this, arguments);
  this.AddLogRecord(new AdfLogRecord(level, message));
};
AdfLogger.prototype.logError = function(error, level, message) {
  if (!level) {
    level = AdfLogger.INFO;
  }
  AdfAssert.assertNumeric(level);
  if (level < this._level) {
    return;
  }
  this._calcMsg["_skipArgs"] = 2;
  message = this._calcMsg.apply(this, arguments);
  this.AddLogRecord(new AdfLogRecord(level, message, error));
};
AdfLogger.prototype.logErrorAsSevere = function(error, message) {
  var level = AdfLogger.SEVERE;
  if (level < this._level) {
    return;
  }
  this._calcMsg["_skipArgs"] = 1;
  message = this._calcMsg.apply(this, arguments);
  this.AddLogRecord(new AdfLogRecord(level, message, error));
};
AdfLogger.prototype.logErrorAsWarning = function(error, message) {
  var level = AdfLogger.WARNING;
  if (level < this._level) {
    return;
  }
  this._calcMsg["_skipArgs"] = 1;
  message = this._calcMsg.apply(this, arguments);
  this.AddLogRecord(new AdfLogRecord(level, message, error));
};
AdfLogger.prototype.logErrorAsInfo = function(error, message) {
  var level = AdfLogger.INFO;
  if (level < this._level) {
    return;
  }
  this._calcMsg["_skipArgs"] = 1;
  message = this._calcMsg.apply(this, arguments);
  this.AddLogRecord(new AdfLogRecord(level, message, error));
};
AdfLogger.prototype.logElapsedTime = function(startTime, message, level) {
  AdfAssert.assert(startTime);
  if (!level) {
    level = this.FINE;
  }
  if (level < this._level) {
    return;
  }
  var now = new Date;
  var elapsedSeconds = (now.getTime() - startTime.getTime()) / 1E3;
  message += elapsedSeconds + " seconds";
  this.AddLogRecord(new AdfLogRecord(level, message, null, now));
};
AdfLogger.InitClass = function() {
  this.RegisterLevels(AdfLogger, [{name:"OFF", severity:Number.MAX_VALUE}, {name:"SEVERE", severity:1E3}, {name:"WARNING", severity:900}, {name:"INFO", severity:800}, {name:"CONFIG", severity:700}, {name:"FINE", severity:500}, {name:"FINER", severity:400}, {name:"FINEST", severity:300}, {name:"ALL", severity:Number.MIN_VALUE}]);
  this["DEFAULT_LEVEL"] = this.WARNING;
  this._LOGGERS = {};
};
AdfLogger.RegisterLevels = function(ourClass, levelArr) {
  AdfAssert.assertFunction(ourClass);
  var ourPrototype = ourClass.prototype;
  ourClass.__reverseMap = new Object;
  var levelCount = levelArr.length;
  var funcArray = ["if (this.", null, "\x3cthis._level) return; this._calcMsg._skipArgs \x3d 0; this.logMessage(this.", null, ",this._calcMsg.apply(this, arguments));"];
  for (var i = 0;i < levelCount;i++) {
    var currLevel = levelArr[i];
    var currLevelName = currLevel.name;
    var currLevelSeverity = currLevel.severity;
    ourClass.__reverseMap[currLevelSeverity] = currLevelName;
    ourClass[currLevelName] = currLevelSeverity;
    ourPrototype[currLevelName] = currLevelSeverity;
    if (currLevelSeverity != Number.MAX_VALUE && currLevelSeverity != Number.MIN_VALUE) {
      funcArray[1] = currLevelName;
      funcArray[3] = currLevelName;
      var funcBody = funcArray.join("");
      var functionName = currLevelName.toLowerCase();
      ourPrototype[functionName] = function anonymous(msg) {
      };
    }
  }
};
AdfLogger.prototype._calcMsg = function(varArgs) {
  var startArgIndex = arguments.callee["_skipArgs"];
  var argCount = arguments.length;
  var firstArg = arguments[startArgIndex];
  if (argCount - startArgIndex == 1 && typeof firstArg == "string") {
    return firstArg;
  } else {
    var message = "";
    for (var i = startArgIndex;i < argCount;i++) {
      var currValue = arguments[i];
      message += currValue;
    }
    return message;
  }
};
AdfLogger.prototype.Init = function(loggerName, logWriter, level) {
  AdfAssert.assert(loggerName, "loggerName required");
  AdfAssert.assert(logWriter, "logWriter required");
  AdfLogger.superclass.Init.call(this);
  this._logWriter = logWriter;
  this._loggerName = loggerName;
  this._level = level !== undefined ? level : AdfLogger["DEFAULT_LEVEL"];
  this._filter = null;
};
AdfLogger.prototype.toDebugString = function() {
  return this.getTypeName() + " [loggerName:'" + this._loggerName + "',level:" + this._level + ",logWriter:" + this._logWriter + "]";
};
AdfLogger.prototype.AddLogRecord = function(logRecord) {
  var filter = this._filter;
  if (filter && !filter(logRecord)) {
    return;
  }
  this.getLogWriter().publish(logRecord);
};
AdfLogger.LOGGER = new AdfLogger("global", new AdfBufferedLogWriter);
AdfLogger.LOGGER.register();
