@Override
  public final D apply(S source) {
    long ts = 0;
    D res = null;
    if (!initialized) {
      synchronized (this) {
        if (!initialized) {
          init();
        }
      }
    }
    if (log.isDebugEnabled()) {
      ts = System.nanoTime();
    }
    try {
      res = mapper.apply(source);
    } catch (Exception e) {
      log.warn("Failed to map the source");
      log.warn(buildExceptionMessage(e));
    }
    if (log.isDebugEnabled()) {
      long te = System.nanoTime();
      log.debug(String.format("Mapped %s, took %.2f ms",
          rootEntity.getSimpleName(), (double) (te - ts) / 1E6));
    }
    return res;
  }