SLING-8646 : Remove LogService implementation
diff --git a/pom.xml b/pom.xml
index fb5edc7..a39ed5a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,16 +57,6 @@
                         <Bundle-DocURL>
                             http://sling.apache.org/site/logging.html
                         </Bundle-DocURL>
-                        <Export-Package>
-                            org.osgi.service.log
-                        </Export-Package>
-                        <Private-Package>
-                            org.apache.sling.commons.logservice.*,
-                        </Private-Package>
-                        <Import-Package>
-                            org.osgi.service.log;provide:=true,
-                            *
-                        </Import-Package>
                     </instructions>
                 </configuration>
             </plugin>
@@ -98,15 +88,22 @@
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
-            <version>4.2.0</version>
+            <version>6.0.0</version>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.compendium</artifactId>
-            <version>4.2.0</version>
+            <artifactId>org.osgi.service.log</artifactId>
+            <version>1.4.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.component</artifactId>
+            <version>1.3.0</version>
+            <scope>provided</scope>
         </dependency>
         
-        <!-- testing -->
+    <!-- testing -->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
diff --git a/src/main/java/org/apache/sling/commons/logservice/internal/Activator.java b/src/main/java/org/apache/sling/commons/logservice/internal/Activator.java
index 60a4755..6d9bf64 100644
--- a/src/main/java/org/apache/sling/commons/logservice/internal/Activator.java
+++ b/src/main/java/org/apache/sling/commons/logservice/internal/Activator.java
@@ -16,16 +16,12 @@
  */
 package org.apache.sling.commons.logservice.internal;
 
-import java.util.Dictionary;
-import java.util.Hashtable;
-
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogReaderService;
-import org.osgi.service.log.LogService;
-import org.osgi.service.startlevel.StartLevel;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
 /**
  * The <code>Activator</code> class is the <code>BundleActivator</code> for the
@@ -34,55 +30,51 @@
  */
 public class Activator implements BundleActivator {
 
-    private static final String VENDOR = "The Apache Software Foundation";
-
-    private LogSupport logSupport;
-
-    /** Reference to the start level service. */
-    private ServiceReference startLevelRef;
+    private volatile ServiceTracker<LogReaderService, LogReaderService> logReaderTracker;
 
     /**
      * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
      */
+    @Override
     public void start(final BundleContext context) throws Exception {
-        // get start level service, it's always there (required by the spec)
-        startLevelRef = context.getServiceReference(StartLevel.class.getName());
+        final SLF4JSupport listener = new SLF4JSupport();
+        this.logReaderTracker = new ServiceTracker<>(context, LogReaderService.class,
+                new ServiceTrackerCustomizer<LogReaderService, LogReaderService>() {
 
-        logSupport = new LogSupport((StartLevel)context.getService(startLevelRef));
-        context.addBundleListener(logSupport);
-        context.addFrameworkListener(logSupport);
-        context.addServiceListener(logSupport);
+                    @Override
+                    public LogReaderService addingService(final ServiceReference<LogReaderService> reference) {
+                        final LogReaderService srvc = context.getService(reference);
+                        if (srvc != null) {
+                            srvc.addLogListener(listener);
+                            listener.replay(srvc.getLog());
+                        }
+                        return srvc;
+                    }
 
-        LogServiceFactory lsf = new LogServiceFactory(logSupport);
-        Dictionary<String, String> props = new Hashtable<String, String>();
-        props.put(Constants.SERVICE_PID, lsf.getClass().getName());
-        props.put(Constants.SERVICE_DESCRIPTION,
-            "Apache Sling LogService implementation");
-        props.put(Constants.SERVICE_VENDOR, VENDOR);
-        context.registerService(LogService.class.getName(), lsf, props);
+                    @Override
+                    public void modifiedService(final ServiceReference<LogReaderService> reference,
+                            final LogReaderService service) {
+                        // nothing to do
+                    }
 
-        LogReaderServiceFactory lrsf = new LogReaderServiceFactory(logSupport);
-        props = new Hashtable<String, String>();
-        props.put(Constants.SERVICE_PID, lrsf.getClass().getName());
-        props.put(Constants.SERVICE_DESCRIPTION,
-            "Apache Sling LogReaderService implementation");
-        props.put(Constants.SERVICE_VENDOR, VENDOR);
-        context.registerService(LogReaderService.class.getName(), lrsf, props);
+                    @Override
+                    public void removedService(final ServiceReference<LogReaderService> reference,
+                            final LogReaderService service) {
+                        service.removeLogListener(listener);
+
+                    }
+                });
+        this.logReaderTracker.open();
     }
 
     /**
      * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
      */
+    @Override
     public void stop(final BundleContext context) throws Exception {
-        if ( startLevelRef != null ) {
-            context.ungetService(startLevelRef);
-        }
-        if (logSupport != null) {
-            context.removeBundleListener(logSupport);
-            context.removeFrameworkListener(logSupport);
-            context.removeServiceListener(logSupport);
-            logSupport.shutdown();
-            logSupport = null;
+        if (this.logReaderTracker != null) {
+            this.logReaderTracker.close();
+            this.logReaderTracker = null;
         }
     }
 }
diff --git a/src/main/java/org/apache/sling/commons/logservice/internal/LogEntryImpl.java b/src/main/java/org/apache/sling/commons/logservice/internal/LogEntryImpl.java
deleted file mode 100644
index a317293..0000000
--- a/src/main/java/org/apache/sling/commons/logservice/internal/LogEntryImpl.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.commons.logservice.internal;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.log.LogEntry;
-
-public class LogEntryImpl implements LogEntry {
-
-    private final Bundle bundle;
-
-    private final ServiceReference serviceReference;
-
-    private final int level;
-
-    private final String message;
-
-    private final Throwable exception;
-
-    private final long time;
-
-    /* package */LogEntryImpl(Bundle bundle,
-            ServiceReference serviceReference, int level, String message,
-            Throwable exception) {
-        this.bundle = bundle;
-        this.serviceReference = serviceReference;
-        this.level = level;
-        this.message = message;
-        this.exception = exception;
-        this.time = System.currentTimeMillis();
-    }
-
-    public Bundle getBundle() {
-        return this.bundle;
-    }
-
-    public ServiceReference getServiceReference() {
-        return this.serviceReference;
-    }
-
-    public int getLevel() {
-        return this.level;
-    }
-
-    public String getMessage() {
-        return this.message;
-    }
-
-    public Throwable getException() {
-        return this.exception;
-    }
-
-    public long getTime() {
-        return this.time;
-    }
-}
diff --git a/src/main/java/org/apache/sling/commons/logservice/internal/LogReaderServiceFactory.java b/src/main/java/org/apache/sling/commons/logservice/internal/LogReaderServiceFactory.java
deleted file mode 100644
index 79791e4..0000000
--- a/src/main/java/org/apache/sling/commons/logservice/internal/LogReaderServiceFactory.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.commons.logservice.internal;
-
-import java.util.Enumeration;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.log.LogListener;
-import org.osgi.service.log.LogReaderService;
-
-/**
- * The <code>LogReaderServiceFactory</code> is the service factory for
- * <code>LogReader</code> service instances supplied to bundles.
- * <p>
- * <blockquote> When a bundle which registers a LogListener object is stopped or
- * otherwise releases the Log Reader Service, the Log Reader Service must remove
- * all of the bundle's listeners.</blockquote>
- */
-public class LogReaderServiceFactory implements ServiceFactory {
-
-    private LogSupport logSupport;
-
-    LogReaderServiceFactory(LogSupport logSupport) {
-        this.logSupport = logSupport;
-    }
-
-    // ---------- ServiceFactory interface ------------------------------------
-
-    public Object getService(Bundle bundle, ServiceRegistration registration) {
-        return new LogReaderServiceImpl(bundle);
-    }
-
-    public void ungetService(Bundle bundle, ServiceRegistration registration,
-            Object service) {
-        ((LogReaderServiceImpl) service).shutdown();
-    }
-
-    // --------- internal LogReaderService implementation ----------------------
-
-    private class LogReaderServiceImpl implements LogReaderService {
-
-        private Bundle bundle;
-
-        /* package */LogReaderServiceImpl(Bundle bundle) {
-            this.bundle = bundle;
-        }
-
-        /* package */void shutdown() {
-            LogReaderServiceFactory.this.logSupport.removeLogListeners(this.bundle);
-        }
-
-        public void addLogListener(LogListener listener) {
-            LogReaderServiceFactory.this.logSupport.addLogListener(this.bundle,
-                listener);
-        }
-
-        public void removeLogListener(LogListener listener) {
-            LogReaderServiceFactory.this.logSupport.removeLogListener(listener);
-        }
-
-        @SuppressWarnings("rawtypes")
-        public Enumeration getLog() {
-            return LogReaderServiceFactory.this.logSupport.getLog();
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/commons/logservice/internal/LogServiceFactory.java b/src/main/java/org/apache/sling/commons/logservice/internal/LogServiceFactory.java
deleted file mode 100644
index e62faf8..0000000
--- a/src/main/java/org/apache/sling/commons/logservice/internal/LogServiceFactory.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.commons.logservice.internal;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.log.LogEntry;
-import org.osgi.service.log.LogService;
-
-/**
- * The <code>LogServiceFactory</code> implements the OSGi Log Service
- * specification and provides the functionality for the logging system. This
- * service should be one of the first services loaded in the system.
- */
-public class LogServiceFactory implements ServiceFactory {
-
-    private LogSupport logSupport;
-
-    /**
-     * Initializes the logging system with settings from some startup properties
-     * before the real configuration is read after ContentBus bootstrap.
-     * 
-     * @param properties The startup properties to initialize the logging system
-     *            with.
-     */
-    LogServiceFactory(LogSupport logSupport) {
-        this.logSupport = logSupport;
-
-    }
-
-    // ---------- ServiceFactory
-
-    public Object getService(Bundle bundle, ServiceRegistration registration) {
-        return new LogServiceImpl(bundle);
-    }
-
-    public void ungetService(Bundle bundle, ServiceRegistration registration,
-            Object service) {
-        // nothing to do currently
-    }
-
-    private class LogServiceImpl implements LogService {
-
-        private Bundle bundle;
-
-        /**
-         * Initializes the logging system with settings from some startup
-         * properties before the real configuration is read after ContentBus
-         * bootstrap.
-         * 
-         * @param properties The startup properties to initialize the logging
-         *            system with.
-         */
-        /* package */LogServiceImpl(Bundle bundle) {
-            this.bundle = bundle;
-        }
-
-        // ---------- LogService
-
-        public void log(int level, String message) {
-            this.log(null, level, message, null);
-        }
-
-        public void log(int level, String message, Throwable exception) {
-            this.log(null, level, message, exception);
-        }
-
-        public void log(ServiceReference sr, int level, String message) {
-            this.log(sr, level, message, null);
-        }
-
-        public void log(ServiceReference sr, int level, String message,
-                Throwable exception) {
-            // simply fire a log event
-            LogEntry entry = new LogEntryImpl(this.bundle, sr, level, message,
-                exception);
-            LogServiceFactory.this.logSupport.fireLogEvent(entry);
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/commons/logservice/internal/LogSupport.java b/src/main/java/org/apache/sling/commons/logservice/internal/LogSupport.java
deleted file mode 100644
index 00be9c3..0000000
--- a/src/main/java/org/apache/sling/commons/logservice/internal/LogSupport.java
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.commons.logservice.internal;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.FrameworkListener;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.SynchronousBundleListener;
-import org.osgi.service.component.ComponentConstants;
-import org.osgi.service.log.LogEntry;
-import org.osgi.service.log.LogListener;
-import org.osgi.service.log.LogService;
-import org.osgi.service.startlevel.StartLevel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The <code>LogReaderServiceFactory</code> TODO
- */
-public class LogSupport implements SynchronousBundleListener, ServiceListener,
-        FrameworkListener {
-
-    /**
-     * The service property name of the component name (value is
-     * "component.name"). Note: We use a private constant here to not create a
-     * unneded dependency on the org.osgi.service.component package.
-     */
-    private static final String COMPONENT_NAME = ComponentConstants.COMPONENT_NAME; // "component.name";
-
-    /**
-     * The empty enumeration currently returned on the {@link #getLog()} call
-     * because we do not currently record the log events.
-     */
-    private final Enumeration<?> EMPTY = Collections.enumeration(Collections.emptyList());
-
-    // The registered LogListeners
-    private LogListenerProxy[] listeners;
-
-    // The lock used to guard concurrent access to the listeners array
-    private final Object listenersLock = new Object();
-
-    // The loggers by bundle id used for logging messages originated from
-    // specific bundles
-    @SuppressWarnings("serial")
-    private final Map<Long, Logger> loggers = new LinkedHashMap<Long, Logger>(16,
-        0.75f, true) {
-        private static final int MAX_SIZE = 50;
-
-        @Override
-        protected boolean removeEldestEntry(Map.Entry<Long, Logger> eldest) {
-            return size() > MAX_SIZE;
-        }
-    };
-
-    // the worker thread actually sending LogEvents to LogListeners
-    private final LogEntryDispatcher logEntryDispatcher;
-
-    private final StartLevel startLevelService;
-
-    /* package */LogSupport(final StartLevel startLevelService) {
-        logEntryDispatcher = new LogEntryDispatcher(this);
-        logEntryDispatcher.start();
-        this.startLevelService = startLevelService;
-    }
-
-    /* package */void shutdown() {
-
-        // terminate the dispatcher and wait for its termination here
-        logEntryDispatcher.terminate();
-        try {
-            logEntryDispatcher.join(1000L);
-        } catch (InterruptedException ie) {
-            // don't care
-        }
-
-        // drop all listeners
-        synchronized (listenersLock) {
-            listeners = null;
-        }
-    }
-
-    // ---------- LogReaderService interface -----------------------------------
-
-    /* package */void addLogListener(Bundle bundle, LogListener listener) {
-        synchronized (listenersLock) {
-            LogListenerProxy llp = new LogListenerProxy(bundle, listener);
-            if (listeners == null) {
-                listeners = new LogListenerProxy[] { llp };
-            } else if (getListener(listener) < 0) {
-                LogListenerProxy[] newListeners = new LogListenerProxy[listeners.length + 1];
-                System.arraycopy(listeners, 0, newListeners, 0,
-                    listeners.length);
-                newListeners[listeners.length] = llp;
-                listeners = newListeners;
-            }
-        }
-    }
-
-    /* package */void removeLogListener(LogListener listener) {
-        synchronized (listenersLock) {
-            // no listeners registered, nothing to do
-            if (listeners == null) {
-                return;
-            }
-
-            // listener is not registered, nothing to do
-            int idx = getListener(listener);
-            if (idx < 0) {
-                return;
-            }
-
-            LogListenerProxy[] newListeners = new LogListenerProxy[listeners.length - 1];
-            if (idx > 0) {
-                System.arraycopy(listeners, 0, newListeners, 0, idx);
-            }
-            if (idx < listeners.length) {
-                System.arraycopy(listeners, idx + 1, newListeners, 0,
-                    newListeners.length - idx);
-            }
-            listeners = newListeners;
-        }
-    }
-
-    /**
-     * Removes all registered LogListeners belonging to the given bundle. This
-     * is the task required by the specification from a Log Service
-     * implemenation:
-     * <p>
-     * <blockquote> When a bundle which registers a LogListener object is
-     * stopped or otherwise releases the Log Reader Service, the Log Reader
-     * Service must remove all of the bundle's listeners.</blockquote>
-     * <p>
-     *
-     * @param bundle The bundle whose listeners are to be removed.
-     */
-    /* package */void removeLogListeners(Bundle bundle) {
-        // grab an immediate copy of the array
-        LogListenerProxy[] current = getListeners();
-        if (current == null) {
-            return;
-        }
-
-        // check for listeners by bundle
-        for (int i = 0; i < current.length; i++) {
-            if (current[i].hasBundle(bundle)) {
-                removeLogListener(current[i]);
-            }
-        }
-    }
-
-    private int getListener(LogListener listener) {
-        if (listeners != null) {
-            for (int i = 0; i < listeners.length; i++) {
-                if (listeners[i].isSame(listener)) {
-                    return i;
-                }
-            }
-        }
-
-        // fall back to not found
-        return -1;
-    }
-
-    /**
-     * Returns the currently registered LogListeners
-     */
-    private LogListenerProxy[] getListeners() {
-        synchronized (listenersLock) {
-            return listeners;
-        }
-    }
-
-    /**
-     * Returns an empty enumeration for now because we do not implement log
-     * entry recording for the moment.
-     */
-    Enumeration<?> getLog() {
-        return EMPTY;
-    }
-
-    // ---------- Firing a log event -------------------------------------------
-
-    /**
-     * Logs the given log entry to the log file and enqueues for the dispatching
-     * to the registered LogListeners in a separate worker thread.
-     */
-    /* package */void fireLogEvent(LogEntry logEntry) {
-
-        // actually log it to SLF4J
-        logOut(logEntry);
-
-        // enqueue for asynchronous delivery
-        logEntryDispatcher.enqueLogEntry(logEntry);
-    }
-
-    // ---------- BundleListener -----------------------------------------------
-
-    /**
-     * Listens for Bundle events and logs the respective events according to the
-     * Log Service specification. In addition, all LogListener instances
-     * registered for stopped bundles are removed by this method.
-     */
-    public void bundleChanged(BundleEvent event) {
-        String message;
-        switch (event.getType()) {
-            case BundleEvent.INSTALLED:
-                message = "BundleEvent INSTALLED";
-                break;
-            case BundleEvent.RESOLVED:
-                message = "BundleEvent RESOLVED";
-                break;
-            case BundleEvent.STARTING:
-                message = "BundleEvent STARTING";
-                break;
-            case BundleEvent.STARTED:
-                message = "BundleEvent STARTED";
-                break;
-            case BundleEvent.STOPPING:
-                message = "BundleEvent STOPPING";
-                break;
-            case BundleEvent.STOPPED:
-                // this is special, as we have to fix the listener list for
-                // stopped bundles
-                removeLogListeners(event.getBundle());
-                message = "BundleEvent STOPPED";
-                break;
-            case BundleEvent.UNRESOLVED:
-                message = "BundleEvent UNRESOLVED";
-                break;
-            case BundleEvent.UPDATED:
-                message = "BundleEvent UPDATED";
-                break;
-            case BundleEvent.UNINSTALLED:
-                // remove any cached logger for the uninstalled bundle
-                ungetLogger(event.getBundle());
-                message = "BundleEvent UNINSTALLED";
-                break;
-            default:
-                message = "BundleEvent " + event.getType();
-        }
-
-        LogEntry entry = new LogEntryImpl(event.getBundle(), null,
-            LogService.LOG_INFO, message, null);
-        fireLogEvent(entry);
-    }
-
-    // ---------- ServiceListener ----------------------------------------------
-
-    /**
-     * Listens for Service events and logs the respective events according to
-     * the Log Service specification.
-     */
-    public void serviceChanged(ServiceEvent event) {
-        int level = LogService.LOG_INFO;
-        String message;
-        switch (event.getType()) {
-            case ServiceEvent.REGISTERED:
-                message = "ServiceEvent REGISTERED";
-                break;
-            case ServiceEvent.MODIFIED:
-                message = "ServiceEvent MODIFIED";
-                level = LogService.LOG_DEBUG;
-                break;
-            case ServiceEvent.UNREGISTERING:
-                message = "ServiceEvent UNREGISTERING";
-                break;
-            default:
-                message = "ServiceEvent " + event.getType();
-        }
-
-        LogEntry entry = new LogEntryImpl(
-            event.getServiceReference().getBundle(),
-            event.getServiceReference(), level, message, null);
-        fireLogEvent(entry);
-    }
-
-    // ---------- FrameworkListener --------------------------------------------
-
-    /**
-     * Listens for Framework events and logs the respective events according to
-     * the Log Service specification.
-     * <p>
-     * In the case of a Framework ERROR which is a ClassNotFoundException for an
-     * unresolved bundle, the message is logged at INFO level instead of ERROR
-     * level as prescribed by the spec. This is because such a situation should
-     * not really result in a Framework ERROR but the Apache Felix framework has
-     * no means of controlling this at the moment (framework 1.0.4 release).
-     */
-    public void frameworkEvent(FrameworkEvent event) {
-        int level = LogService.LOG_INFO;
-        String message;
-        Throwable exception = event.getThrowable();
-        switch (event.getType()) {
-            case FrameworkEvent.STARTED:
-                message = "FrameworkEvent STARTED";
-                break;
-            case FrameworkEvent.ERROR:
-                message = "FrameworkEvent ERROR";
-
-                // special precaution for Felix.loadBundleClass event overkill
-                // FIXME: actually, the error is ok, if the bundle failed to
-                // resolve
-                if (exception instanceof BundleException) {
-                    StackTraceElement[] ste = exception.getStackTrace();
-                    if (ste != null && ste.length > 0
-                        && "loadBundleClass".equals(ste[0].getMethodName())) {
-                        message += ": Class " + exception.getMessage()
-                            + " not found";
-                        if (event.getBundle() != null) {
-                            message += " in bundle "
-                                + event.getBundle().getSymbolicName() + " ("
-                                + event.getBundle().getBundleId() + ")";
-                        }
-                        level = LogService.LOG_INFO;
-                        exception = null; // don't care for a stack trace here
-                        break;
-                    }
-                }
-
-                level = LogService.LOG_ERROR;
-                break;
-            case FrameworkEvent.PACKAGES_REFRESHED:
-                message = "FrameworkEvent PACKAGES REFRESHED";
-                break;
-            case FrameworkEvent.STARTLEVEL_CHANGED:
-                message = "FrameworkEvent STARTLEVEL CHANGED to " + this.startLevelService.getStartLevel();
-                break;
-            case FrameworkEvent.WARNING:
-                message = "FrameworkEvent WARNING";
-                break;
-            case FrameworkEvent.INFO:
-                message = "FrameworkEvent INFO";
-                break;
-            default:
-                message = "FrameworkEvent " + event.getType();
-        }
-
-        final LogEntry entry = new LogEntryImpl(event.getBundle(), null, level,
-            message, exception);
-        fireLogEvent(entry);
-    }
-
-    // ---------- Effective logging --------------------------------------------
-
-    /**
-     * Get a logger for messages orginating from the given bundle. If no bundle
-     * is specified, we use the system bundle logger.
-     *
-     * @param bundle The bundle for which a logger is to be returned.
-     * @return The Logger for the bundle.
-     */
-    private Logger getLogger(Bundle bundle) {
-        Long bundleId = new Long((bundle == null) ? 0 : bundle.getBundleId());
-        Logger log;
-        synchronized (loggers) {
-            log = loggers.get(bundleId);
-        }
-        if (log == null) {
-
-            String name;
-            if (bundle == null) {
-
-                // if we have no bundle, use the system bundle's name
-                name = Constants.SYSTEM_BUNDLE_SYMBOLICNAME;
-
-            } else {
-
-                // otherwise use the bundle symbolic name
-                name = bundle.getSymbolicName();
-
-                // if the bundle has no symbolic name, use the location
-                if (name == null) {
-                    name = bundle.getLocation();
-                }
-
-                // if the bundle also has no location, use the bundle Id
-                if (name == null) {
-                    name = String.valueOf(bundle.getBundleId());
-                }
-            }
-
-            log = LoggerFactory.getLogger(name);
-            synchronized (loggers) {
-                loggers.put(bundleId, log);
-            }
-        }
-        return log;
-    }
-
-    /**
-     * Removes the cached logger for the given bundle, for example if the
-     * bundle is uninstalled and thus there will be no more logs from this
-     * bundle.
-     */
-    private void ungetLogger(Bundle bundle) {
-        synchronized (loggers) {
-            loggers.remove(bundle.getBundleId());
-        }
-    }
-
-    /**
-     * Actually logs the given log entry to the logger for the bundle recorded
-     * in the log entry.
-     */
-    private void logOut(LogEntry logEntry) {
-        // get the logger for the bundle
-        Logger log = getLogger(logEntry.getBundle());
-        if (logEntry.getLevel() > getLevel(log))
-            // early Exit, this message will not be logged, don't do any work...
-            return;
-
-        final StringBuilder msg = new StringBuilder();
-
-        ServiceReference sr = logEntry.getServiceReference();
-        if (sr != null) {
-            msg.append("Service [");
-            if (sr.getProperty(Constants.SERVICE_PID) != null) {
-                msg.append(sr.getProperty(Constants.SERVICE_PID)).append(',');
-            } else if (sr.getProperty(COMPONENT_NAME) != null) {
-                msg.append(sr.getProperty(COMPONENT_NAME)).append(',');
-            } else if (sr.getProperty(Constants.SERVICE_DESCRIPTION) != null) {
-                msg.append(sr.getProperty(Constants.SERVICE_DESCRIPTION)).append(
-                    ',');
-            }
-            msg.append(sr.getProperty(Constants.SERVICE_ID))
-                .append(", ")
-                .append(Arrays.toString((String[]) sr.getProperty(Constants.OBJECTCLASS)))
-                .append("] ");
-        }
-
-        if (logEntry.getMessage() != null) {
-            msg.append(logEntry.getMessage());
-        }
-
-        Throwable exception = logEntry.getException();
-        if (exception != null) {
-            msg.append(" (").append(exception).append(')');
-        }
-
-        String message = msg.toString();
-        switch (logEntry.getLevel()) {
-            case LogService.LOG_DEBUG:
-                log.debug(message, exception);
-                break;
-            case LogService.LOG_INFO:
-                log.info(message, exception);
-                break;
-            case LogService.LOG_WARNING:
-                log.warn(message, exception);
-                break;
-            case LogService.LOG_ERROR:
-                log.error(message, exception);
-                break;
-            default:
-                if (logEntry.getLevel() > LogService.LOG_DEBUG) {
-                    log.trace(message, exception);
-                } else if (logEntry.getLevel() < LogService.LOG_ERROR) {
-                    log.error(message, exception);
-                }
-                break;
-        }
-    }
-
-    static int getLevel(Logger log) {
-        if (log.isTraceEnabled())
-            return LogService.LOG_DEBUG + 1; // No constant for trace in LogService
-        else if (log.isDebugEnabled())
-            return LogService.LOG_DEBUG;
-        else if (log.isInfoEnabled())
-            return LogService.LOG_INFO;
-        else if (log.isWarnEnabled())
-            return LogService.LOG_WARNING;
-        return LogService.LOG_ERROR;
-    }
-
-    // ---------- internal class -----------------------------------------------
-
-    /**
-     * The <code>LogListenerProxy</code> class is a proxy to the actually
-     * registered <code>LogListener</code> which also records the bundle
-     * registering the listener. This allows for the removal of the log
-     * listeners registered by bundles which have not been removed before the
-     * bundle has been stopped.
-     */
-    private static class LogListenerProxy implements LogListener {
-
-        private final int runningBundle = Bundle.STARTING | Bundle.ACTIVE
-            | Bundle.STOPPING;
-
-        private final Bundle bundle;
-
-        private final LogListener delegatee;
-
-        public LogListenerProxy(Bundle bundle, LogListener delegatee) {
-            this.bundle = bundle;
-            this.delegatee = delegatee;
-        }
-
-        public void logged(LogEntry entry) {
-            if ((bundle.getState() & runningBundle) != 0) {
-                delegatee.logged(entry);
-            }
-        }
-
-        /* package */boolean isSame(LogListener listener) {
-            return listener == delegatee || listener == this;
-        }
-
-        /* package */boolean hasBundle(Bundle bundle) {
-            return this.bundle == bundle;
-        }
-    }
-
-    /**
-     * The <code>LogEntryDispatcher</code> implements the worker thread
-     * responsible for delivering log events to the log listeners.
-     */
-    private static class LogEntryDispatcher extends Thread {
-
-        // provides the actual log listeners on demand
-        private final LogSupport logSupport;
-
-        // the queue of log events to be dispatched
-        private final BlockingQueue<LogEntry> dispatchQueue;
-
-        // true as long as the thread is active
-        private boolean active;
-
-        LogEntryDispatcher(LogSupport logSupport) {
-            super("LogEntry Dispatcher");
-
-            this.logSupport = logSupport;
-            this.dispatchQueue = new LinkedBlockingQueue<LogEntry>();
-            this.active = true;
-        }
-
-        /**
-         * Add a log entry for dispatching.
-         */
-        void enqueLogEntry(LogEntry logEntry) {
-            dispatchQueue.offer(logEntry);
-        }
-
-        /**
-         * Get the next log entry for dispatching. This method blocks until an
-         * event is available or the thread is interrupted.
-         *
-         * @return The next event to dispatch
-         * @throws InterruptedException If the thread has been interrupted while
-         *             waiting for a log event to dispatch.
-         */
-        LogEntry dequeueLogEntry() throws InterruptedException {
-            return dispatchQueue.take();
-        }
-
-        /**
-         * Terminates this work thread by resetting the active flag and
-         * interrupting itself such that the {@link #dequeueLogEntry()} is
-         * aborted for the thread to terminate.
-         */
-        void terminate() {
-            active = false;
-            interrupt();
-        }
-
-        /**
-         * Runs the actual log event dispatching. This method continues to get
-         * log events from the {@link #dequeueLogEntry()} method until the
-         * active flag is reset.
-         */
-        @Override
-        public void run() {
-            while (active) {
-
-                LogEntry logEntry = null;
-                try {
-                    logEntry = dequeueLogEntry();
-                } catch (InterruptedException ie) {
-                    // don't care, this is expected
-                }
-
-                // dispatch the log entry
-                if (logEntry != null) {
-
-                    // grab an immediate copy of the array
-                    LogListener[] logListeners = logSupport.getListeners();
-
-                    // fire the events outside of the listenersLock
-                    if (logListeners != null) {
-                        for (LogListener logListener : logListeners) {
-                            try {
-                                logListener.logged(logEntry);
-                            } catch (Throwable t) {
-                                // should we really care ??
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/commons/logservice/internal/SLF4JSupport.java b/src/main/java/org/apache/sling/commons/logservice/internal/SLF4JSupport.java
new file mode 100644
index 0000000..4a7b96c
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/logservice/internal/SLF4JSupport.java
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.commons.logservice.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.log.LogEntry;
+import org.osgi.service.log.LogListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@code SLF4JSupport} uses slf4j API to output all log entries.
+ */
+public class SLF4JSupport implements LogListener {
+
+    @Override
+    public void logged(final LogEntry logEntry) {
+        doLog(logEntry);
+    }
+
+    private void doLog(final LogEntry logEntry) {
+        // get the logger for the bundle
+        final boolean isLogService = "LogService".equals(logEntry.getLoggerName());
+        final Logger logger = LoggerFactory
+                .getLogger(isLogService ? getLoggerName(logEntry.getBundle()) : logEntry.getLoggerName());
+        if (!isEnabled(logger, logEntry)) {
+            // early Exit, this message will not be logged, don't do any work...
+            return;
+        }
+        logOut(logger, logEntry);
+    }
+
+    /**
+     * The service property name of the component name (value is "component.name").
+     * Note: We use a private constant here to not create a unneeded dependency on
+     * the org.osgi.service.component package.
+     */
+    private static final String COMPONENT_NAME = ComponentConstants.COMPONENT_NAME; // "component.name";
+
+    private String getLoggerName(final Bundle bundle) {
+        String name;
+        if (bundle == null) {
+
+            // if we have no bundle, use the system bundle's name
+            name = Constants.SYSTEM_BUNDLE_SYMBOLICNAME;
+
+        } else {
+
+            // otherwise use the bundle symbolic name
+            name = bundle.getSymbolicName();
+
+            // if the bundle has no symbolic name, use the location
+            if (name == null) {
+                name = bundle.getLocation();
+            }
+
+            // if the bundle also has no location, use the bundle Id
+            if (name == null) {
+                name = String.valueOf(bundle.getBundleId());
+            }
+        }
+
+        return name;
+    }
+
+    /**
+     * Actually logs the given log entry to the logger
+     */
+    private synchronized void logOut(final Logger logger, final LogEntry logEntry) {
+
+        final StringBuilder msg = new StringBuilder();
+
+        ServiceReference<?> sr = logEntry.getServiceReference();
+        if (sr != null) {
+            msg.append("Service [");
+            if (sr.getProperty(Constants.SERVICE_PID) != null) {
+                msg.append(sr.getProperty(Constants.SERVICE_PID)).append(',');
+            } else if (sr.getProperty(COMPONENT_NAME) != null) {
+                msg.append(sr.getProperty(COMPONENT_NAME)).append(',');
+            } else if (sr.getProperty(Constants.SERVICE_DESCRIPTION) != null) {
+                msg.append(sr.getProperty(Constants.SERVICE_DESCRIPTION)).append(
+                    ',');
+            }
+            msg.append(sr.getProperty(Constants.SERVICE_ID))
+                .append(", ")
+                .append(Arrays.toString((String[]) sr.getProperty(Constants.OBJECTCLASS)))
+                .append("] ");
+        }
+
+        if (logEntry.getMessage() != null) {
+            msg.append(logEntry.getMessage());
+        }
+
+        Throwable exception = logEntry.getException();
+        if (exception != null) {
+            msg.append(" (").append(exception).append(')');
+        }
+
+        String message = msg.toString();
+        switch (logEntry.getLogLevel()) {
+        case DEBUG:
+            logger.debug(message, exception);
+                break;
+        case INFO:
+            logger.info(message, exception);
+                break;
+        case WARN:
+            logger.warn(message, exception);
+                break;
+        case ERROR:
+            logger.error(message, exception);
+                break;
+        case TRACE:
+                logger.trace(message, exception);
+                break;
+        case AUDIT: // we treat audit as info for now as there is no audit in slf4j (TODO)
+            logger.info(message, exception);
+            break;
+        }
+    }
+
+    static boolean isEnabled(final Logger logger, final LogEntry logEntry) {
+        switch (logEntry.getLogLevel()) {
+        case DEBUG:
+            return logger.isDebugEnabled();
+        case INFO:
+            return logger.isInfoEnabled();
+        case WARN:
+            return logger.isWarnEnabled();
+        case ERROR:
+            return logger.isErrorEnabled();
+        case TRACE:
+            return logger.isTraceEnabled();
+        case AUDIT: // we treat audit as info for now as there is no audit in slf4j (TODO)
+            return logger.isInfoEnabled();
+        }
+        return false;
+    }
+
+    public synchronized void replay(final Enumeration<LogEntry> log) {
+        // the enumeration contains the most recent entries first
+        final List<LogEntry> entries = new ArrayList<>(Collections.list(log));
+        Collections.reverse(entries);
+        for (final LogEntry entry : entries) {
+            doLog(entry);
+        }
+    }
+}
diff --git a/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java b/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java
deleted file mode 100644
index 7bf0c2f..0000000
--- a/src/test/java/org/apache/sling/commons/logservice/internal/LogSupportTest.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.commons.logservice.internal;
-
-import static org.junit.Assert.assertEquals;
-
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.log.LogEntry;
-import org.osgi.service.log.LogService;
-import org.osgi.service.startlevel.StartLevel;
-import org.slf4j.Logger;
-
-public class LogSupportTest {
-    
-    private Bundle bundle;
-    private LogSupport logSupport;
-    private Logger testLogger;
-
-    @Before
-    @SuppressWarnings("unchecked")
-    public void prepare() throws Exception {
-        
-        bundle = Mockito.mock(Bundle.class);
-        Mockito.when(bundle.getSymbolicName()).thenReturn("foo.bundle");
-        Mockito.when(bundle.getBundleId()).thenReturn(42L);
-        
-        StartLevel startLevel = Mockito.mock(StartLevel.class);
-        logSupport = new LogSupport(startLevel);
-        Field loggerField = LogSupport.class.getDeclaredField("loggers");
-        loggerField.setAccessible(true);
-        Map<Long, Logger> loggers = (Map<Long, Logger>) loggerField.get(logSupport);
-        
-        testLogger = getMockInfoLogger();
-        loggers.put(bundle.getBundleId(), testLogger);
-    }
-    
-    @Test
-    public void testServiceEvent() throws Exception {
-
-
-        final Map<String, Object> props = new HashMap<String, Object>();
-        props.put(Constants.OBJECTCLASS, new String [] {"some.class.Name"});
-        props.put(Constants.SERVICE_ID, 999L);
-
-        ServiceReference sr = Mockito.mock(ServiceReference.class);
-        Mockito.when(sr.getBundle()).thenReturn(bundle);
-        Mockito.when(sr.getProperty(Mockito.anyString())).then(new Answer<Object>() {
-            public Object answer(InvocationOnMock invocation) throws Throwable {
-                return props.get(invocation.getArguments()[0]);
-            }
-        });
-        Mockito.when(sr.getPropertyKeys()).thenReturn(props.keySet().toArray(new String[] {}));
-        ServiceEvent se = new ServiceEvent(ServiceEvent.REGISTERED, sr);
-
-        logSupport.serviceChanged(se);
-
-        Mockito.verify(testLogger).info("Service [999, [some.class.Name]] ServiceEvent REGISTERED", (Throwable) null);
-    }
-
-    @Test
-    public void testEarlyExit() throws Exception {
-        
-        ServiceReference sr = Mockito.mock(ServiceReference.class);
-        LogEntry le = new LogEntryImpl(bundle, sr, LogService.LOG_DEBUG, "test", null);
-
-        logSupport.fireLogEvent(le);
-
-        // The log message is on DEBUG level while the logger is set to INFO level
-        // we don't want the actual log.info() call to be made, neither do we want
-        // any preparatory work on the log message being made (which involves
-        // inspecting the service reference).
-        Mockito.verify(testLogger).isTraceEnabled();
-        Mockito.verify(testLogger).isDebugEnabled();
-        Mockito.verify(testLogger).isInfoEnabled();
-        Mockito.verifyNoMoreInteractions(testLogger);
-        Mockito.verifyZeroInteractions(sr);
-    }
-
-    @Test
-    public void testErrorLogger() throws Exception {
-        
-        Exception e = new Exception();
-        LogEntry le = new LogEntryImpl(bundle, null, LogService.LOG_ERROR, "my-error-msg", e);
-
-        logSupport.fireLogEvent(le);
-        
-        Mockito.verify(testLogger).error("my-error-msg (java.lang.Exception)", e);
-    }
-    
-	@Test
-    public void testWarningLogger() throws Exception {
-	    
-        Exception e = new Exception();
-        LogEntry le = new LogEntryImpl(bundle, null, LogService.LOG_WARNING, "my-warning-message", e);
-
-        logSupport.fireLogEvent(le);
-        
-        Mockito.verify(testLogger).warn("my-warning-message (java.lang.Exception)", e);
-    }
-	
-	@Test
-	public void testInfoLogger() throws Exception {
-	    
-        LogEntry le = new LogEntryImpl(bundle, null, LogService.LOG_INFO, "my-info-message", null);
-
-        logSupport.fireLogEvent(le);
-        
-        Mockito.verify(testLogger).info("my-info-message", (Throwable) null);
-	}
-
-	@Test
-	public void testBundleChanges() throws Exception {
-
-        logSupport.bundleChanged(new BundleEvent(BundleEvent.INSTALLED, bundle));
-
-        Mockito.verify(testLogger).info("BundleEvent INSTALLED", (Throwable) null);
-	}
-	
-	@Test
-	public void testFrameworkEventStarted() throws Exception {
-        
-        FrameworkEvent frameworkEvent = new FrameworkEvent(FrameworkEvent.STARTED, bundle, null);
-        
-        logSupport.frameworkEvent(frameworkEvent);
-        
-        Mockito.verify(testLogger).info("FrameworkEvent STARTED", (Throwable) null);
-	}
-	
-	@Test
-	public void testFrameworkEventError() throws Exception {
-
-	    BundleException bundleException = new BundleException("my bundle exception", BundleException.ACTIVATOR_ERROR);
-        FrameworkEvent frameworkEvent = new FrameworkEvent(FrameworkEvent.ERROR, bundle, bundleException);
-        
-        logSupport.frameworkEvent(frameworkEvent);
-        
-        Mockito.verify(testLogger).error("FrameworkEvent ERROR (org.osgi.framework.BundleException: my bundle exception)", bundleException);
-	}
-	
-    @Test
-    public void testGetLevels() {
-        Logger traceLogger = Mockito.mock(Logger.class);
-        Mockito.when(traceLogger.isTraceEnabled()).thenReturn(true);
-        assertEquals(5, LogSupport.getLevel(traceLogger));
-
-        Logger debugLogger = Mockito.mock(Logger.class);
-        Mockito.when(debugLogger.isDebugEnabled()).thenReturn(true);
-        assertEquals(LogService.LOG_DEBUG, LogSupport.getLevel(debugLogger));
-
-        Logger infoLogger = Mockito.mock(Logger.class);
-        Mockito.when(infoLogger.isInfoEnabled()).thenReturn(true);
-        assertEquals(LogService.LOG_INFO, LogSupport.getLevel(infoLogger));
-
-        Logger warnLogger = Mockito.mock(Logger.class);
-        Mockito.when(warnLogger.isWarnEnabled()).thenReturn(true);
-        assertEquals(LogService.LOG_WARNING, LogSupport.getLevel(warnLogger));
-
-        Logger errorLogger = Mockito.mock(Logger.class);
-        Mockito.when(errorLogger.isErrorEnabled()).thenReturn(true);
-        assertEquals(LogService.LOG_ERROR, LogSupport.getLevel(errorLogger));
-    }
-
-    private Logger getMockInfoLogger() {
-        Logger testLogger = Mockito.mock(Logger.class);
-        Mockito.when(testLogger.isTraceEnabled()).thenReturn(false);
-        Mockito.when(testLogger.isDebugEnabled()).thenReturn(false);
-        Mockito.when(testLogger.isInfoEnabled()).thenReturn(true);
-        Mockito.when(testLogger.isWarnEnabled()).thenReturn(true);
-        Mockito.when(testLogger.isErrorEnabled()).thenReturn(true);
-        return testLogger;
-    }
-}