diff --git a/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java b/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java
deleted file mode 100644
index 55d94e7..0000000
--- a/src/main/java/org/apache/log4j/LoggerRepositoryExImpl.java
+++ /dev/null
@@ -1,718 +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.log4j;
-
-import org.apache.log4j.helpers.LogLog;
-import org.apache.log4j.or.ObjectRenderer;
-import org.apache.log4j.or.RendererMap;
-import org.apache.log4j.plugins.Plugin;
-import org.apache.log4j.plugins.PluginRegistry;
-import org.apache.log4j.scheduler.Scheduler;
-import org.apache.log4j.spi.*;
-import org.apache.log4j.xml.DOMConfigurator;
-import org.apache.log4j.xml.UnrecognizedElementHandler;
-import org.w3c.dom.Element;
-
-import java.util.*;
-
-
-/**
- * This class implements LoggerRepositoryEx by
- * wrapping an existing LoggerRepository implementation
- * and implementing the newly added capabilities.
- */
-public final class LoggerRepositoryExImpl
-    implements LoggerRepositoryEx,
-    RendererSupport,
-    UnrecognizedElementHandler {
-
-    /**
-     * Wrapped logger repository.
-     */
-    private final LoggerRepository repo;
-
-    /**
-     * Logger factory.  Does not affect class of logger
-     * created by underlying repository.
-     */
-    private LoggerFactory loggerFactory;
-
-    /**
-     * Renderer support.
-     */
-    private final RendererSupport rendererSupport;
-
-    /**
-     * List of repository event listeners.
-     */
-    private final ArrayList<LoggerRepositoryEventListener> repositoryEventListeners = new ArrayList<>();
-    /**
-     * Map of HierarchyEventListener keyed by LoggingEventListener.
-     */
-    private final Map<LoggerEventListener, HierarchyEventListenerProxy> loggerEventListeners = new HashMap<>();
-    /**
-     * Name of hierarchy.
-     */
-    private String name;
-    /**
-     * Plug in registry.
-     */
-    private PluginRegistry pluginRegistry;
-    /**
-     * Properties.
-     */
-    private final Map<String, String> properties = new Hashtable<>();
-    /**
-     * Scheduler.
-     */
-    private Scheduler scheduler;
-
-    /**
-     * The repository can also be used as an object store
-     * for various objects used by log4j components.
-     */
-    private Map<String, Object> objectMap = new HashMap<>();
-
-
-    /**
-     * Error list.
-     */
-    private List<ErrorItem> errorList = new Vector<>();
-
-    /**
-     * True if hierarchy has not been modified.
-     */
-    private boolean pristine = true;
-
-    /**
-     * Constructs a new logger hierarchy.
-     *
-     * @param repository Base implementation of repository.
-     */
-    public LoggerRepositoryExImpl(final LoggerRepository repository) {
-        super();
-        if (repository == null) {
-            throw new NullPointerException("repository");
-        }
-        repo = repository;
-        if (repository instanceof RendererSupport) {
-            rendererSupport = (RendererSupport) repository;
-        } else {
-            rendererSupport = new RendererSupportImpl();
-        }
-    }
-
-
-    /**
-     * Add a {@link LoggerRepositoryEventListener} to the repository. The
-     * listener will be called when repository events occur.
-     *
-     * @param listener listener
-     */
-    public void addLoggerRepositoryEventListener(
-        final LoggerRepositoryEventListener listener) {
-        synchronized (repositoryEventListeners) {
-            if (repositoryEventListeners.contains(listener)) {
-                LogLog.warn(
-                    "Ignoring attempt to add a previously "
-                        + "registered LoggerRepositoryEventListener.");
-            } else {
-                repositoryEventListeners.add(listener);
-            }
-        }
-    }
-
-
-    /**
-     * Remove a {@link LoggerRepositoryEventListener} from the repository.
-     *
-     * @param listener listener
-     */
-    public void removeLoggerRepositoryEventListener(
-        final LoggerRepositoryEventListener listener) {
-        synchronized (repositoryEventListeners) {
-            if (!repositoryEventListeners.contains(listener)) {
-                LogLog.warn(
-                    "Ignoring attempt to remove a "
-                        + "non-registered LoggerRepositoryEventListener.");
-            } else {
-                repositoryEventListeners.remove(listener);
-            }
-        }
-    }
-
-    /**
-     * Add a {@link LoggerEventListener} to the repository. The  listener
-     * will be called when repository events occur.
-     *
-     * @param listener listener
-     */
-    public void addLoggerEventListener(final LoggerEventListener listener) {
-        synchronized (loggerEventListeners) {
-            if (loggerEventListeners.get(listener) != null) {
-                LogLog.warn(
-                    "Ignoring attempt to add a previously registerd LoggerEventListener.");
-            } else {
-                HierarchyEventListenerProxy proxy =
-                    new HierarchyEventListenerProxy(listener);
-                loggerEventListeners.put(listener, proxy);
-                repo.addHierarchyEventListener(proxy);
-            }
-        }
-    }
-
-    /**
-     * Add a {@link org.apache.log4j.spi.HierarchyEventListener}
-     * event to the repository.
-     *
-     * @param listener listener
-     * @deprecated Superceded by addLoggerEventListener
-     */
-    public void addHierarchyEventListener(final HierarchyEventListener listener) {
-        repo.addHierarchyEventListener(listener);
-    }
-
-
-    /**
-     * Remove a {@link LoggerEventListener} from the repository.
-     *
-     * @param listener listener to be removed
-     */
-    public void removeLoggerEventListener(final LoggerEventListener listener) {
-        synchronized (loggerEventListeners) {
-            HierarchyEventListenerProxy proxy =
-                loggerEventListeners.get(listener);
-            if (proxy == null) {
-                LogLog.warn(
-                    "Ignoring attempt to remove a non-registered LoggerEventListener.");
-            } else {
-                loggerEventListeners.remove(listener);
-                proxy.disable();
-            }
-        }
-    }
-
-    /**
-     * Issue warning that there are no appenders in hierarchy.
-     *
-     * @param cat logger, not currently used.
-     */
-    public void emitNoAppenderWarning(final Category cat) {
-        repo.emitNoAppenderWarning(cat);
-    }
-
-    /**
-     * Check if the named logger exists in the hierarchy. If so return
-     * its reference, otherwise returns <code>null</code>.
-     *
-     * @param loggerName The name of the logger to search for.
-     * @return true if logger exists.
-     */
-    public Logger exists(final String loggerName) {
-        return repo.exists(loggerName);
-    }
-
-    /**
-     * Return the name of this hierarchy.
-     *
-     * @return name of hierarchy
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Set the name of this repository.
-     * <p>
-     * Note that once named, a repository cannot be rerenamed.
-     *
-     * @param repoName name of hierarchy
-     */
-    public void setName(final String repoName) {
-        if (name == null) {
-            name = repoName;
-        } else if (!name.equals(repoName)) {
-            throw new IllegalStateException(
-                "Repository [" + name + "] cannot be renamed as [" + repoName + "].");
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public Map<String, String> getProperties() {
-        return properties;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getProperty(final String key) {
-        return properties.get(key);
-    }
-
-    /**
-     * Set a property by key and value. The property will be shared by all
-     * events in this repository.
-     *
-     * @param key   property name
-     * @param value property value
-     */
-    public void setProperty(final String key,
-                            final String value) {
-        properties.put(key, value);
-    }
-
-    /**
-     * The string form of {@link #setThreshold(Level)}.
-     *
-     * @param levelStr symbolic name for level
-     */
-    public void setThreshold(final String levelStr) {
-        repo.setThreshold(levelStr);
-    }
-
-    /**
-     * Enable logging for logging requests with level <code>l</code> or
-     * higher. By default all levels are enabled.
-     *
-     * @param l The minimum level for which logging requests are sent to
-     *          their appenders.
-     */
-    public void setThreshold(final Level l) {
-        repo.setThreshold(l);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public PluginRegistry getPluginRegistry() {
-        if (pluginRegistry == null) {
-            pluginRegistry = new PluginRegistry(this);
-        }
-        return pluginRegistry;
-    }
-
-
-    /**
-     * Requests that a appender added event be sent to any registered
-     * {@link LoggerEventListener}.
-     *
-     * @param logger   The logger to which the appender was added.
-     * @param appender The appender added to the logger.
-     */
-    public void fireAddAppenderEvent(final Category logger,
-                                     final Appender appender) {
-        repo.fireAddAppenderEvent(logger, appender);
-    }
-
-
-    /**
-     * Requests that a appender removed event be sent to any registered
-     * {@link LoggerEventListener}.
-     *
-     * @param logger   The logger from which the appender was removed.
-     * @param appender The appender removed from the logger.
-     */
-    public void fireRemoveAppenderEvent(final Category logger,
-                                        final Appender appender) {
-        if (repo instanceof Hierarchy) {
-            ((Hierarchy) repo).fireRemoveAppenderEvent(logger, appender);
-        }
-    }
-
-
-    /**
-     * Requests that a level changed event be sent to any registered
-     * {@link LoggerEventListener}.
-     *
-     * @param logger The logger which changed levels.
-     */
-    public void fireLevelChangedEvent(final Logger logger) {
-    }
-
-    /**
-     * Requests that a configuration changed event be sent to any registered
-     * {@link LoggerRepositoryEventListener}.
-     */
-    public void fireConfigurationChangedEvent() {
-    }
-
-
-    /**
-     * Returns the current threshold.
-     *
-     * @return current threshold level
-     * @since 1.2
-     */
-    public Level getThreshold() {
-        return repo.getThreshold();
-    }
-
-
-    /**
-     * Return a new logger instance named as the first parameter using
-     * the default factory.
-     * <p>
-     * <p>If a logger of that name already exists, then it will be
-     * returned.  Otherwise, a new logger will be instantiated and
-     * then linked with its existing ancestors as well as children.
-     *
-     * @param loggerName The name of the logger to retrieve.
-     * @return logger
-     */
-    public Logger getLogger(final String loggerName) {
-        return repo.getLogger(loggerName);
-    }
-
-    /**
-     * Return a new logger instance named as the first parameter using
-     * <code>factory</code>.
-     * <p>
-     * <p>If a logger of that name already exists, then it will be
-     * returned.  Otherwise, a new logger will be instantiated by the
-     * <code>factory</code> parameter and linked with its existing
-     * ancestors as well as children.
-     *
-     * @param loggerName The name of the logger to retrieve.
-     * @param factory    The factory that will make the new logger instance.
-     * @return logger
-     */
-    public Logger getLogger(final String loggerName,
-                            final LoggerFactory factory) {
-        return repo.getLogger(loggerName, factory);
-    }
-
-    /**
-     * Returns all the currently defined categories in this hierarchy as
-     * an {@link java.util.Enumeration Enumeration}.
-     * <p>
-     * <p>The root logger is <em>not</em> included in the returned
-     * {@link Enumeration}.
-     *
-     * @return enumerator of current loggers
-     */
-    public Enumeration getCurrentLoggers() {
-        return repo.getCurrentLoggers();
-    }
-
-    /**
-     * Return the the list of previously encoutered {@link ErrorItem error items}.
-     *
-     * @return list of errors
-     */
-    public List<ErrorItem> getErrorList() {
-        return errorList;
-    }
-
-    /**
-     * Add an error item to the list of previously encountered errors.
-     *
-     * @param errorItem error to add to list of errors.
-     */
-    public void addErrorItem(final ErrorItem errorItem) {
-        getErrorList().add(errorItem);
-    }
-
-    /**
-     * Get enumerator over current loggers.
-     *
-     * @return enumerator over current loggers
-     * @deprecated Please use {@link #getCurrentLoggers} instead.
-     */
-    public Enumeration getCurrentCategories() {
-        return repo.getCurrentCategories();
-    }
-
-    /**
-     * Get the renderer map for this hierarchy.
-     *
-     * @return renderer map
-     */
-    public RendererMap getRendererMap() {
-        return rendererSupport.getRendererMap();
-    }
-
-    /**
-     * Get the root of this hierarchy.
-     *
-     * @return root of hierarchy
-     * @since 0.9.0
-     */
-    public Logger getRootLogger() {
-        return repo.getRootLogger();
-    }
-
-    /**
-     * This method will return <code>true</code> if this repository is
-     * disabled for <code>level</code> value passed as parameter and
-     * <code>false</code> otherwise. See also the {@link
-     * #setThreshold(Level) threshold} method.
-     *
-     * @param level numeric value for level.
-     * @return true if disabled for specified level
-     */
-    public boolean isDisabled(final int level) {
-        return repo.isDisabled(level);
-    }
-
-    /**
-     * Reset all values contained in this hierarchy instance to their
-     * default.  This removes all appenders from all categories, sets
-     * the level of all non-root categories to <code>null</code>,
-     * sets their additivity flag to <code>true</code> and sets the level
-     * of the root logger to DEBUG.  Moreover,
-     * message disabling is set its default "off" value.
-     * <p>
-     * <p>Existing categories are not removed. They are just reset.
-     * <p>
-     * <p>This method should be used sparingly and with care as it will
-     * block all logging until it is completed.</p>
-     *
-     * @since 0.8.5
-     */
-    public void resetConfiguration() {
-        repo.resetConfiguration();
-    }
-
-    /**
-     * Used by subclasses to add a renderer to the hierarchy passed as parameter.
-     *
-     * @param renderedClass class
-     * @param renderer      object used to render class.
-     */
-    public void setRenderer(final Class renderedClass,
-                            final ObjectRenderer renderer) {
-        rendererSupport.setRenderer(renderedClass, renderer);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean isPristine() {
-        return pristine;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void setPristine(final boolean state) {
-        pristine = state;
-    }
-
-    /**
-     * Shutting down a hierarchy will <em>safely</em> close and remove
-     * all appenders in all categories including the root logger.
-     * <p>
-     * <p>Some appenders such as org.apache.log4j.net.SocketAppender
-     * and AsyncAppender need to be closed before the
-     * application exists. Otherwise, pending logging events might be
-     * lost.
-     * <p>
-     * <p>The <code>shutdown</code> method is careful to close nested
-     * appenders before closing regular appenders. This is allows
-     * configurations where a regular appender is attached to a logger
-     * and again to a nested appender.
-     *
-     * @since 1.0
-     */
-    public void shutdown() {
-        repo.shutdown();
-    }
-
-
-    /**
-     * Return this repository's own scheduler.
-     * The scheduler is lazily instantiated.
-     *
-     * @return this repository's own scheduler.
-     */
-    public Scheduler getScheduler() {
-        if (scheduler == null) {
-            scheduler = new Scheduler();
-            scheduler.setDaemon(true);
-            scheduler.start();
-        }
-        return scheduler;
-    }
-
-    /**
-     * Puts object by key.
-     *
-     * @param key   key, may not be null.
-     * @param value object to associate with key.
-     */
-    public void putObject(final String key,
-                          final Object value) {
-        objectMap.put(key, value);
-    }
-
-    /**
-     * Get object by key.
-     *
-     * @param key key, may not be null.
-     * @return object associated with key or null.
-     */
-    public Object getObject(final String key) {
-        return objectMap.get(key);
-    }
-
-    /**
-     * Set logger factory.
-     *
-     * @param factory logger factory.
-     */
-    public void setLoggerFactory(final LoggerFactory factory) {
-        if (factory == null) {
-            throw new NullPointerException();
-        }
-        this.loggerFactory = factory;
-    }
-
-    /**
-     * Get logger factory.
-     *
-     * @return logger factory.
-     */
-    public LoggerFactory getLoggerFactory() {
-        return loggerFactory;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean parseUnrecognizedElement(
-        final Element element,
-        final Properties props) throws Exception {
-        if ("plugin".equals(element.getNodeName())) {
-            Object instance =
-                DOMConfigurator.parseElement(element, props, Plugin.class);
-            if (instance instanceof Plugin) {
-                Plugin plugin = (Plugin) instance;
-                String pluginName = DOMConfigurator.subst(element.getAttribute("name"), props);
-                if (pluginName.length() > 0) {
-                    plugin.setName(pluginName);
-                }
-                getPluginRegistry().addPlugin(plugin);
-                plugin.setLoggerRepository(this);
-
-                LogLog.debug("Pushing plugin on to the object stack.");
-                plugin.activateOptions();
-                return true;
-            }
-        }
-        return false;
-    }
-
-
-    /**
-     * Implementation of RendererSupportImpl if not
-     * provided by LoggerRepository.
-     */
-    private static final class RendererSupportImpl implements RendererSupport {
-        /**
-         * Renderer map.
-         */
-        private final RendererMap renderers = new RendererMap();
-
-        /**
-         * Create new instance.
-         */
-        public RendererSupportImpl() {
-            super();
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public RendererMap getRendererMap() {
-            return renderers;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void setRenderer(final Class renderedClass,
-                                final ObjectRenderer renderer) {
-            renderers.put(renderedClass, renderer);
-        }
-    }
-
-    /**
-     * Proxy that implements HierarchyEventListener
-     * and delegates to LoggerEventListener.
-     */
-    private static final class HierarchyEventListenerProxy
-        implements HierarchyEventListener {
-        /**
-         * Wrapper listener.
-         */
-        private LoggerEventListener listener;
-
-        /**
-         * Creates new instance.
-         *
-         * @param l listener
-         */
-        public HierarchyEventListenerProxy(final LoggerEventListener l) {
-            super();
-            if (l == null) {
-                throw new NullPointerException("l");
-            }
-            listener = l;
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void addAppenderEvent(final Category cat,
-                                     final Appender appender) {
-            if (isEnabled() && cat instanceof Logger) {
-                listener.appenderAddedEvent((Logger) cat, appender);
-            }
-        }
-
-        /**
-         * {@inheritDoc}
-         */
-        public void removeAppenderEvent(final Category cat,
-                                        final Appender appender) {
-            if (isEnabled() && cat instanceof Logger) {
-                listener.appenderRemovedEvent((Logger) cat, appender);
-            }
-        }
-
-        /**
-         * Disable forwarding of notifications to
-         * simulate removal of listener.
-         */
-        public synchronized void disable() {
-            listener = null;
-        }
-
-        /**
-         * Gets whether proxy is enabled.
-         *
-         * @return true if proxy is enabled.
-         */
-        private synchronized boolean isEnabled() {
-            return listener != null;
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/log4j/chainsaw/LogUI.java b/src/main/java/org/apache/log4j/chainsaw/LogUI.java
index fb706c1..676e02d 100644
--- a/src/main/java/org/apache/log4j/chainsaw/LogUI.java
+++ b/src/main/java/org/apache/log4j/chainsaw/LogUI.java
@@ -150,10 +150,6 @@
     private EventListenerList shutdownListenerList = new EventListenerList();
     private WelcomePanel welcomePanel;
 
-    private static final Object repositorySelectorGuard = new Object();
-    private static final LoggerRepositoryExImpl repositoryExImpl = new LoggerRepositoryExImpl(LogManager.getLoggerRepository());
-
-    private PluginRegistry pluginRegistry;
     //map of tab names to rulecolorizers
     private Map<String, RuleColorizer> allColorizers = new HashMap<>();
     private ReceiverConfigurationPanel receiverConfigurationPanel = new ReceiverConfigurationPanel();
@@ -219,8 +215,6 @@
             System.setProperty("apple.laf.useScreenMenuBar", "true");
         }
 
-        LogManager.setRepositorySelector(() -> repositoryExImpl, repositorySelectorGuard);
-
         final ApplicationPreferenceModel model = new ApplicationPreferenceModel();
 
         SettingsManager.getInstance().configure(new ApplicationPreferenceModelSaver(model));
@@ -288,7 +282,6 @@
             showSplash(logUI);
         }
         logUI.cyclicBufferSize = model.getCyclicBufferSize();
-        logUI.pluginRegistry = repositoryExImpl.getPluginRegistry();
 
         final LoggerContext ctx = (LoggerContext) org.apache.logging.log4j.LogManager.getContext(false);
         logUI.chainsawAppender = ctx.getConfiguration().getAppender("chainsaw");
@@ -414,8 +407,6 @@
             System.setProperty("apple.laf.useScreenMenuBar", "true");
         }
 
-        LogManager.setRepositorySelector(() -> repositoryExImpl, repositorySelectorGuard);
-
         //if Chainsaw is launched as an appender, ensure the root logger level is TRACE
         LogManager.getRootLogger().setLevel(Level.TRACE);
 
@@ -665,15 +656,11 @@
      * table columns, and sets itself viewable.
      */
     public void activateViewer() {
-        LoggerRepository repo = LogManager.getLoggerRepository();
-        if (repo instanceof LoggerRepositoryEx) {
-            this.pluginRegistry = ((LoggerRepositoryEx) repo).getPluginRegistry();
-        }
         initGUI();
 
         initPrefModelListeners();
 
-        if (pluginRegistry.getPlugins(Receiver.class).size() == 0) {
+        if (m_receivers.size() == 0) {
             noReceiversDefined = true;
         }
 
@@ -798,13 +785,6 @@
 
         getContentPane().add(mainReceiverSplitPane, BorderLayout.CENTER);
 
-        /**
-         * We need to make sure that all the internal GUI components have been added to the
-         * JFrame so that any plugns that get activated during initPlugins(...) method
-         * have access to inject menus
-         */
-        initPlugins(pluginRegistry);
-
         mainReceiverSplitPane.setResizeWeight(1.0);
         addWindowListener(
             new WindowAdapter() {
@@ -951,128 +931,128 @@
             SwingHelper.invokeOnEDT(this::showReceiverConfigurationPanel);
         }
 
-        Container container = tutorialFrame.getContentPane();
-        final JEditorPane tutorialArea = new JEditorPane();
-        tutorialArea.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
-        tutorialArea.setEditable(false);
-        container.setLayout(new BorderLayout());
-
-        try {
-            tutorialArea.setPage(ChainsawConstants.TUTORIAL_URL);
-            JTextComponentFormatter.applySystemFontAndSize(tutorialArea);
-
-            container.add(new JScrollPane(tutorialArea), BorderLayout.CENTER);
-        } catch (Exception e) {
-            logger.error("Can't load tutorial", e);
-            statusBar.setMessage("Can't load tutorail");
-        }
-
-        tutorialFrame.setIconImage(new ImageIcon(ChainsawIcons.HELP).getImage());
-        tutorialFrame.setSize(new Dimension(640, 480));
-
-        final Action startTutorial =
-            new AbstractAction(
-                "Start Tutorial", new ImageIcon(ChainsawIcons.ICON_RESUME_RECEIVER)) {
-                public void actionPerformed(ActionEvent e) {
-                    if (
-                        JOptionPane.showConfirmDialog(
-                            null,
-                            "This will start 3 \"Generator\" receivers for use in the Tutorial.  Is that ok?",
-                            "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
-                        new Thread(new Tutorial()).start();
-                        putValue("TutorialStarted", Boolean.TRUE);
-                    } else {
-                        putValue("TutorialStarted", Boolean.FALSE);
-                    }
-                }
-            };
-
-        final Action stopTutorial =
-            new AbstractAction(
-                "Stop Tutorial", new ImageIcon(ChainsawIcons.ICON_STOP_RECEIVER)) {
-                public void actionPerformed(ActionEvent e) {
-                    if (
-                        JOptionPane.showConfirmDialog(
-                            null,
-                            "This will stop all of the \"Generator\" receivers used in the Tutorial, but leave any other Receiver untouched.  Is that ok?",
-                            "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
-                        new Thread(
-                            () -> {
-                                LoggerRepository repo1 = LogManager.getLoggerRepository();
-                                if (repo1 instanceof LoggerRepositoryEx) {
-                                    PluginRegistry pluginRegistry = ((LoggerRepositoryEx) repo1).getPluginRegistry();
-                                    List list = pluginRegistry.getPlugins(Generator.class);
-
-                                    for (Object aList : list) {
-                                        Plugin plugin = (Plugin) aList;
-                                        pluginRegistry.stopPlugin(plugin.getName());
-                                    }
-                                }
-                            }).start();
-                        setEnabled(false);
-                        startTutorial.putValue("TutorialStarted", Boolean.FALSE);
-                    }
-                }
-            };
-
-        stopTutorial.putValue(
-            Action.SHORT_DESCRIPTION,
-            "Removes all of the Tutorials Generator Receivers, leaving all other Receivers untouched");
-        startTutorial.putValue(
-            Action.SHORT_DESCRIPTION,
-            "Begins the Tutorial, starting up some Generator Receivers so you can see Chainsaw in action");
-        stopTutorial.setEnabled(false);
-
-        final SmallToggleButton startButton = new SmallToggleButton(startTutorial);
-        PropertyChangeListener pcl =
-            evt -> {
-                stopTutorial.setEnabled(
-                    startTutorial.getValue("TutorialStarted").equals(Boolean.TRUE));
-                startButton.setSelected(stopTutorial.isEnabled());
-            };
-
-        startTutorial.addPropertyChangeListener(pcl);
-        stopTutorial.addPropertyChangeListener(pcl);
-
-        pluginRegistry.addPluginListener(
-            new PluginListener() {
-                public void pluginStarted(PluginEvent e) {
-                }
-
-                public void pluginStopped(PluginEvent e) {
-                    List list = pluginRegistry.getPlugins(Generator.class);
-
-                    if (list.size() == 0) {
-                        startTutorial.putValue("TutorialStarted", Boolean.FALSE);
-                    }
-                }
-            });
-
-        final SmallButton stopButton = new SmallButton(stopTutorial);
-
-        final JToolBar tutorialToolbar = new JToolBar();
-        tutorialToolbar.setFloatable(false);
-        tutorialToolbar.add(startButton);
-        tutorialToolbar.add(stopButton);
-        container.add(tutorialToolbar, BorderLayout.NORTH);
-        tutorialArea.addHyperlinkListener(
-            e -> {
-                if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
-                    if (e.getDescription().equals("StartTutorial")) {
-                        startTutorial.actionPerformed(null);
-                    } else if (e.getDescription().equals("StopTutorial")) {
-                        stopTutorial.actionPerformed(null);
-                    } else {
-                        try {
-                            tutorialArea.setPage(e.getURL());
-                        } catch (IOException e1) {
-                            statusBar.setMessage("Failed to change URL for tutorial");
-                            logger.error(
-                                "Failed to change the URL for the Tutorial", e1);
-                        }
-                    }
-                }
-            });
+//        Container container = tutorialFrame.getContentPane();
+//        final JEditorPane tutorialArea = new JEditorPane();
+//        tutorialArea.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
+//        tutorialArea.setEditable(false);
+//        container.setLayout(new BorderLayout());
+//
+//        try {
+//            tutorialArea.setPage(ChainsawConstants.TUTORIAL_URL);
+//            JTextComponentFormatter.applySystemFontAndSize(tutorialArea);
+//
+//            container.add(new JScrollPane(tutorialArea), BorderLayout.CENTER);
+//        } catch (Exception e) {
+//            logger.error("Can't load tutorial", e);
+//            statusBar.setMessage("Can't load tutorail");
+//        }
+//
+//        tutorialFrame.setIconImage(new ImageIcon(ChainsawIcons.HELP).getImage());
+//        tutorialFrame.setSize(new Dimension(640, 480));
+//
+//        final Action startTutorial =
+//            new AbstractAction(
+//                "Start Tutorial", new ImageIcon(ChainsawIcons.ICON_RESUME_RECEIVER)) {
+//                public void actionPerformed(ActionEvent e) {
+//                    if (
+//                        JOptionPane.showConfirmDialog(
+//                            null,
+//                            "This will start 3 \"Generator\" receivers for use in the Tutorial.  Is that ok?",
+//                            "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
+//                        new Thread(new Tutorial()).start();
+//                        putValue("TutorialStarted", Boolean.TRUE);
+//                    } else {
+//                        putValue("TutorialStarted", Boolean.FALSE);
+//                    }
+//                }
+//            };
+//
+//        final Action stopTutorial =
+//            new AbstractAction(
+//                "Stop Tutorial", new ImageIcon(ChainsawIcons.ICON_STOP_RECEIVER)) {
+//                public void actionPerformed(ActionEvent e) {
+//                    if (
+//                        JOptionPane.showConfirmDialog(
+//                            null,
+//                            "This will stop all of the \"Generator\" receivers used in the Tutorial, but leave any other Receiver untouched.  Is that ok?",
+//                            "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
+//                        new Thread(
+//                            () -> {
+//                                LoggerRepository repo1 = LogManager.getLoggerRepository();
+//                                if (repo1 instanceof LoggerRepositoryEx) {
+//                                    PluginRegistry pluginRegistry = ((LoggerRepositoryEx) repo1).getPluginRegistry();
+//                                    List list = pluginRegistry.getPlugins(Generator.class);
+//
+//                                    for (Object aList : list) {
+//                                        Plugin plugin = (Plugin) aList;
+//                                        pluginRegistry.stopPlugin(plugin.getName());
+//                                    }
+//                                }
+//                            }).start();
+//                        setEnabled(false);
+//                        startTutorial.putValue("TutorialStarted", Boolean.FALSE);
+//                    }
+//                }
+//            };
+//
+//        stopTutorial.putValue(
+//            Action.SHORT_DESCRIPTION,
+//            "Removes all of the Tutorials Generator Receivers, leaving all other Receivers untouched");
+//        startTutorial.putValue(
+//            Action.SHORT_DESCRIPTION,
+//            "Begins the Tutorial, starting up some Generator Receivers so you can see Chainsaw in action");
+//        stopTutorial.setEnabled(false);
+//
+//        final SmallToggleButton startButton = new SmallToggleButton(startTutorial);
+//        PropertyChangeListener pcl =
+//            evt -> {
+//                stopTutorial.setEnabled(
+//                    startTutorial.getValue("TutorialStarted").equals(Boolean.TRUE));
+//                startButton.setSelected(stopTutorial.isEnabled());
+//            };
+//
+//        startTutorial.addPropertyChangeListener(pcl);
+//        stopTutorial.addPropertyChangeListener(pcl);
+//
+//        pluginRegistry.addPluginListener(
+//            new PluginListener() {
+//                public void pluginStarted(PluginEvent e) {
+//                }
+//
+//                public void pluginStopped(PluginEvent e) {
+//                    List list = pluginRegistry.getPlugins(Generator.class);
+//
+//                    if (list.size() == 0) {
+//                        startTutorial.putValue("TutorialStarted", Boolean.FALSE);
+//                    }
+//                }
+//            });
+//
+//        final SmallButton stopButton = new SmallButton(stopTutorial);
+//
+//        final JToolBar tutorialToolbar = new JToolBar();
+//        tutorialToolbar.setFloatable(false);
+//        tutorialToolbar.add(startButton);
+//        tutorialToolbar.add(stopButton);
+//        container.add(tutorialToolbar, BorderLayout.NORTH);
+//        tutorialArea.addHyperlinkListener(
+//            e -> {
+//                if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+//                    if (e.getDescription().equals("StartTutorial")) {
+//                        startTutorial.actionPerformed(null);
+//                    } else if (e.getDescription().equals("StopTutorial")) {
+//                        stopTutorial.actionPerformed(null);
+//                    } else {
+//                        try {
+//                            tutorialArea.setPage(e.getURL());
+//                        } catch (IOException e1) {
+//                            statusBar.setMessage("Failed to change URL for tutorial");
+//                            logger.error(
+//                                "Failed to change the URL for the Tutorial", e1);
+//                        }
+//                    }
+//                }
+//            });
 
         /**
          * loads the saved tab settings and if there are hidden tabs,
@@ -1197,179 +1177,179 @@
      * Displays a dialog which will provide options for selecting a configuration
      */
     private void showReceiverConfigurationPanel() {
-        SwingUtilities.invokeLater(
-            () -> {
-                final JDialog dialog = new JDialog(LogUI.this, true);
-                dialog.setTitle("Load events into Chainsaw");
-                dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
-
-                dialog.setResizable(false);
-
-                receiverConfigurationPanel.setCompletionActionListener(
-                    e -> {
-                        dialog.setVisible(false);
-
-                        if (receiverConfigurationPanel.getModel().isCancelled()) {
-                            return;
-                        }
-                        applicationPreferenceModel.setShowNoReceiverWarning(!receiverConfigurationPanel.isDontWarnMeAgain());
-                        //remove existing plugins
-                        List<Plugin> plugins = pluginRegistry.getPlugins();
-                        for (Object plugin1 : plugins) {
-                            Plugin plugin = (Plugin) plugin1;
-                            //don't stop ZeroConfPlugin if it is registered
-                            if (!plugin.getName().toLowerCase(Locale.ENGLISH).contains("zeroconf")) {
-                                pluginRegistry.stopPlugin(plugin.getName());
-                            }
-                        }
-                        URL configURL = null;
-
-                        if (receiverConfigurationPanel.getModel().isNetworkReceiverMode()) {
-                            int port = receiverConfigurationPanel.getModel().getNetworkReceiverPort();
-
-                            try {
-                                Class<? extends Receiver> receiverClass = receiverConfigurationPanel.getModel().getNetworkReceiverClass();
-                                Receiver networkReceiver = receiverClass.newInstance();
-                                networkReceiver.setName(receiverClass.getSimpleName() + "-" + port);
-
-                                Method portMethod =
-                                    networkReceiver.getClass().getMethod(
-                                        "setPort", int.class);
-                                portMethod.invoke(
-                                    networkReceiver, port);
-
-                                networkReceiver.setThreshold(Level.TRACE);
-
-                                pluginRegistry.addPlugin(networkReceiver);
-                                networkReceiver.activateOptions();
-                                receiversPanel.updateReceiverTreeInDispatchThread();
-                            } catch (Exception e3) {
-                                logger.error(
-                                    "Error creating Receiver", e3);
-                                statusBar.setMessage(
-                                    "An error occurred creating your Receiver");
-                            }
-                        } else if (receiverConfigurationPanel.getModel().isLog4jConfig()) {
-                            File log4jConfigFile = receiverConfigurationPanel.getModel().getLog4jConfigFile();
-                            if (log4jConfigFile != null) {
-                                try {
-                                    Map<String, Map<String, String>> entries = LogFilePatternLayoutBuilder.getAppenderConfiguration(log4jConfigFile);
-                                    for (Object o : entries.entrySet()) {
-                                        try {
-                                            Map.Entry entry = (Map.Entry) o;
-                                            String name = (String) entry.getKey();
-                                            Map values = (Map) entry.getValue();
-                                            //values: conversion, file
-                                            String conversionPattern = values.get("conversion").toString();
-                                            File file = new File(values.get("file").toString());
-                                            URL fileURL = file.toURI().toURL();
-                                            String timestampFormat = LogFilePatternLayoutBuilder.getTimeStampFormat(conversionPattern);
-                                            String receiverPattern = LogFilePatternLayoutBuilder.getLogFormatFromPatternLayout(conversionPattern);
-                                            VFSLogFilePatternReceiver fileReceiver = new VFSLogFilePatternReceiver();
-                                            fileReceiver.setName(name);
-                                            fileReceiver.setAutoReconnect(true);
-                                            fileReceiver.setContainer(LogUI.this);
-                                            fileReceiver.setAppendNonMatches(true);
-                                            fileReceiver.setFileURL(fileURL.toURI().toString());
-                                            fileReceiver.setTailing(true);
-                                            fileReceiver.setLogFormat(receiverPattern);
-                                            fileReceiver.setTimestampFormat(timestampFormat);
-//                                            fileReceiver.setThreshold(Level.TRACE);
-//                                            pluginRegistry.addPlugin(fileReceiver);
-                                            fileReceiver.activateOptions();
-                                            receiversPanel.updateReceiverTreeInDispatchThread();
-                                        } catch (URISyntaxException e1) {
-                                            e1.printStackTrace();
-                                        }
-                                    }
-                                } catch (IOException e1) {
-                                    e1.printStackTrace();
-                                }
-                            }
-                        } else if (receiverConfigurationPanel.getModel().isLoadConfig()) {
-                            configURL = receiverConfigurationPanel.getModel().getConfigToLoad();
-                        } else if (receiverConfigurationPanel.getModel().isLogFileReceiverConfig()) {
-                            try {
-                                URL fileURL = receiverConfigurationPanel.getModel().getLogFileURL();
-                                if (fileURL != null) {
-                                    VFSLogFilePatternReceiver fileReceiver = new VFSLogFilePatternReceiver();
-                                    fileReceiver.setName(fileURL.getFile());
-                                    fileReceiver.setAutoReconnect(true);
-                                    fileReceiver.setContainer(LogUI.this);
-                                    fileReceiver.setAppendNonMatches(true);
-                                    fileReceiver.setFileURL(fileURL.toURI().toString());
-                                    fileReceiver.setTailing(true);
-                                    if (receiverConfigurationPanel.getModel().isPatternLayoutLogFormat()) {
-                                        fileReceiver.setLogFormat(LogFilePatternLayoutBuilder.getLogFormatFromPatternLayout(receiverConfigurationPanel.getModel().getLogFormat()));
-                                    } else {
-                                        fileReceiver.setLogFormat(receiverConfigurationPanel.getModel().getLogFormat());
-                                    }
-                                    fileReceiver.setTimestampFormat(receiverConfigurationPanel.getModel().getLogFormatTimestampFormat());
-//                                    fileReceiver.setThreshold(Level.TRACE);
+//        SwingUtilities.invokeLater(
+//            () -> {
+//                final JDialog dialog = new JDialog(LogUI.this, true);
+//                dialog.setTitle("Load events into Chainsaw");
+//                dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
 //
-//                                    pluginRegistry.addPlugin(fileReceiver);
-                                    fileReceiver.activateOptions();
-                                    receiversPanel.updateReceiverTreeInDispatchThread();
-                                }
-                            } catch (Exception e2) {
-                                logger.error(
-                                    "Error creating Receiver", e2);
-                                statusBar.setMessage(
-                                    "An error occurred creating your Receiver");
-                            }
-                        }
-                        if (configURL == null && receiverConfigurationPanel.isDontWarnMeAgain()) {
-                            //use the saved config file as the config URL if defined
-                            if (receiverConfigurationPanel.getModel().getSaveConfigFile() != null) {
-                                try {
-                                    configURL = receiverConfigurationPanel.getModel().getSaveConfigFile().toURI().toURL();
-                                } catch (MalformedURLException e1) {
-                                    e1.printStackTrace();
-                                }
-                            } else {
-                                //no saved config defined but don't warn me is checked - use default config
-                                configURL = receiverConfigurationPanel.getModel().getDefaultConfigFileURL();
-                            }
-                        }
-                        if (configURL != null) {
-//                            MessageCenter.getInstance().getLogger().debug(
-//                                "Initialiazing Log4j with " + configURL.toExternalForm());
-                            final URL finalURL = configURL;
-                            new Thread(
-                                () -> {
-                                    if (receiverConfigurationPanel.isDontWarnMeAgain()) {
-                                        applicationPreferenceModel.setConfigurationURL(finalURL.toExternalForm());
-                                    } else {
-                                        try {
-                                            if (new File(finalURL.toURI()).exists()) {
-                                                loadConfigurationUsingPluginClassLoader(finalURL);
-                                            }
-                                        } catch (URISyntaxException e12) {
-                                            //ignore
-                                        }
-                                    }
-
-                                    receiversPanel.updateReceiverTreeInDispatchThread();
-                                }).start();
-                        }
-                        File saveConfigFile = receiverConfigurationPanel.getModel().getSaveConfigFile();
-                        if (saveConfigFile != null) {
-                            saveReceiversToFile(saveConfigFile);
-                        }
-                    });
-
-                receiverConfigurationPanel.setDialog(dialog);
-                dialog.getContentPane().add(receiverConfigurationPanel);
-
-                dialog.pack();
-
-                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
-                dialog.setLocation(
-                    (screenSize.width / 2) - (dialog.getWidth() / 2),
-                    (screenSize.height / 2) - (dialog.getHeight() / 2));
-
-                dialog.setVisible(true);
-            });
+//                dialog.setResizable(false);
+//
+//                receiverConfigurationPanel.setCompletionActionListener(
+//                    e -> {
+//                        dialog.setVisible(false);
+//
+//                        if (receiverConfigurationPanel.getModel().isCancelled()) {
+//                            return;
+//                        }
+//                        applicationPreferenceModel.setShowNoReceiverWarning(!receiverConfigurationPanel.isDontWarnMeAgain());
+//                        //remove existing plugins
+//                        List<Plugin> plugins = pluginRegistry.getPlugins();
+//                        for (Object plugin1 : plugins) {
+//                            Plugin plugin = (Plugin) plugin1;
+//                            //don't stop ZeroConfPlugin if it is registered
+//                            if (!plugin.getName().toLowerCase(Locale.ENGLISH).contains("zeroconf")) {
+//                                pluginRegistry.stopPlugin(plugin.getName());
+//                            }
+//                        }
+//                        URL configURL = null;
+//
+//                        if (receiverConfigurationPanel.getModel().isNetworkReceiverMode()) {
+//                            int port = receiverConfigurationPanel.getModel().getNetworkReceiverPort();
+//
+//                            try {
+//                                Class<? extends Receiver> receiverClass = receiverConfigurationPanel.getModel().getNetworkReceiverClass();
+//                                Receiver networkReceiver = receiverClass.newInstance();
+//                                networkReceiver.setName(receiverClass.getSimpleName() + "-" + port);
+//
+//                                Method portMethod =
+//                                    networkReceiver.getClass().getMethod(
+//                                        "setPort", int.class);
+//                                portMethod.invoke(
+//                                    networkReceiver, port);
+//
+//                                networkReceiver.setThreshold(Level.TRACE);
+//
+//                                pluginRegistry.addPlugin(networkReceiver);
+//                                networkReceiver.activateOptions();
+//                                receiversPanel.updateReceiverTreeInDispatchThread();
+//                            } catch (Exception e3) {
+//                                logger.error(
+//                                    "Error creating Receiver", e3);
+//                                statusBar.setMessage(
+//                                    "An error occurred creating your Receiver");
+//                            }
+//                        } else if (receiverConfigurationPanel.getModel().isLog4jConfig()) {
+//                            File log4jConfigFile = receiverConfigurationPanel.getModel().getLog4jConfigFile();
+//                            if (log4jConfigFile != null) {
+//                                try {
+//                                    Map<String, Map<String, String>> entries = LogFilePatternLayoutBuilder.getAppenderConfiguration(log4jConfigFile);
+//                                    for (Object o : entries.entrySet()) {
+//                                        try {
+//                                            Map.Entry entry = (Map.Entry) o;
+//                                            String name = (String) entry.getKey();
+//                                            Map values = (Map) entry.getValue();
+//                                            //values: conversion, file
+//                                            String conversionPattern = values.get("conversion").toString();
+//                                            File file = new File(values.get("file").toString());
+//                                            URL fileURL = file.toURI().toURL();
+//                                            String timestampFormat = LogFilePatternLayoutBuilder.getTimeStampFormat(conversionPattern);
+//                                            String receiverPattern = LogFilePatternLayoutBuilder.getLogFormatFromPatternLayout(conversionPattern);
+//                                            VFSLogFilePatternReceiver fileReceiver = new VFSLogFilePatternReceiver();
+//                                            fileReceiver.setName(name);
+//                                            fileReceiver.setAutoReconnect(true);
+//                                            fileReceiver.setContainer(LogUI.this);
+//                                            fileReceiver.setAppendNonMatches(true);
+//                                            fileReceiver.setFileURL(fileURL.toURI().toString());
+//                                            fileReceiver.setTailing(true);
+//                                            fileReceiver.setLogFormat(receiverPattern);
+//                                            fileReceiver.setTimestampFormat(timestampFormat);
+////                                            fileReceiver.setThreshold(Level.TRACE);
+////                                            pluginRegistry.addPlugin(fileReceiver);
+//                                            fileReceiver.activateOptions();
+//                                            receiversPanel.updateReceiverTreeInDispatchThread();
+//                                        } catch (URISyntaxException e1) {
+//                                            e1.printStackTrace();
+//                                        }
+//                                    }
+//                                } catch (IOException e1) {
+//                                    e1.printStackTrace();
+//                                }
+//                            }
+//                        } else if (receiverConfigurationPanel.getModel().isLoadConfig()) {
+//                            configURL = receiverConfigurationPanel.getModel().getConfigToLoad();
+//                        } else if (receiverConfigurationPanel.getModel().isLogFileReceiverConfig()) {
+//                            try {
+//                                URL fileURL = receiverConfigurationPanel.getModel().getLogFileURL();
+//                                if (fileURL != null) {
+//                                    VFSLogFilePatternReceiver fileReceiver = new VFSLogFilePatternReceiver();
+//                                    fileReceiver.setName(fileURL.getFile());
+//                                    fileReceiver.setAutoReconnect(true);
+//                                    fileReceiver.setContainer(LogUI.this);
+//                                    fileReceiver.setAppendNonMatches(true);
+//                                    fileReceiver.setFileURL(fileURL.toURI().toString());
+//                                    fileReceiver.setTailing(true);
+//                                    if (receiverConfigurationPanel.getModel().isPatternLayoutLogFormat()) {
+//                                        fileReceiver.setLogFormat(LogFilePatternLayoutBuilder.getLogFormatFromPatternLayout(receiverConfigurationPanel.getModel().getLogFormat()));
+//                                    } else {
+//                                        fileReceiver.setLogFormat(receiverConfigurationPanel.getModel().getLogFormat());
+//                                    }
+//                                    fileReceiver.setTimestampFormat(receiverConfigurationPanel.getModel().getLogFormatTimestampFormat());
+////                                    fileReceiver.setThreshold(Level.TRACE);
+////
+////                                    pluginRegistry.addPlugin(fileReceiver);
+//                                    fileReceiver.activateOptions();
+//                                    receiversPanel.updateReceiverTreeInDispatchThread();
+//                                }
+//                            } catch (Exception e2) {
+//                                logger.error(
+//                                    "Error creating Receiver", e2);
+//                                statusBar.setMessage(
+//                                    "An error occurred creating your Receiver");
+//                            }
+//                        }
+//                        if (configURL == null && receiverConfigurationPanel.isDontWarnMeAgain()) {
+//                            //use the saved config file as the config URL if defined
+//                            if (receiverConfigurationPanel.getModel().getSaveConfigFile() != null) {
+//                                try {
+//                                    configURL = receiverConfigurationPanel.getModel().getSaveConfigFile().toURI().toURL();
+//                                } catch (MalformedURLException e1) {
+//                                    e1.printStackTrace();
+//                                }
+//                            } else {
+//                                //no saved config defined but don't warn me is checked - use default config
+//                                configURL = receiverConfigurationPanel.getModel().getDefaultConfigFileURL();
+//                            }
+//                        }
+//                        if (configURL != null) {
+////                            MessageCenter.getInstance().getLogger().debug(
+////                                "Initialiazing Log4j with " + configURL.toExternalForm());
+//                            final URL finalURL = configURL;
+//                            new Thread(
+//                                () -> {
+//                                    if (receiverConfigurationPanel.isDontWarnMeAgain()) {
+//                                        applicationPreferenceModel.setConfigurationURL(finalURL.toExternalForm());
+//                                    } else {
+//                                        try {
+//                                            if (new File(finalURL.toURI()).exists()) {
+//                                                loadConfigurationUsingPluginClassLoader(finalURL);
+//                                            }
+//                                        } catch (URISyntaxException e12) {
+//                                            //ignore
+//                                        }
+//                                    }
+//
+//                                    receiversPanel.updateReceiverTreeInDispatchThread();
+//                                }).start();
+//                        }
+//                        File saveConfigFile = receiverConfigurationPanel.getModel().getSaveConfigFile();
+//                        if (saveConfigFile != null) {
+//                            saveReceiversToFile(saveConfigFile);
+//                        }
+//                    });
+//
+//                receiverConfigurationPanel.setDialog(dialog);
+//                dialog.getContentPane().add(receiverConfigurationPanel);
+//
+//                dialog.pack();
+//
+//                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+//                dialog.setLocation(
+//                    (screenSize.width / 2) - (dialog.getWidth() / 2),
+//                    (screenSize.height / 2) - (dialog.getHeight() / 2));
+//
+//                dialog.setVisible(true);
+//            });
     }
 
     /**
@@ -1484,7 +1464,9 @@
 
                     Thread.sleep(delay);
 
-                    pluginRegistry.stopAllPlugins();
+                    for( ChainsawReceiver rx : m_receivers ){
+                        rx.shutdown();
+                    }
                     panel.setProgress(progress++);
 
                     Thread.sleep(delay);
diff --git a/src/test/java/org/apache/log4j/db/FullCycleDBTest.java b/src/test/java/org/apache/log4j/db/FullCycleDBTest.java
index 7107f11..1cfc62b 100644
--- a/src/test/java/org/apache/log4j/db/FullCycleDBTest.java
+++ b/src/test/java/org/apache/log4j/db/FullCycleDBTest.java
@@ -1,319 +1,318 @@
-/*
- * 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.log4j.db;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-import org.apache.log4j.Hierarchy;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.apache.log4j.MDC;
-import org.apache.log4j.VectorAppender;
-import org.apache.log4j.LoggerRepositoryExImpl;
-import org.apache.log4j.helpers.Constants;
-import org.apache.log4j.xml.DOMConfigurator;
-import org.apache.log4j.spi.LocationInfo;
-import org.apache.log4j.spi.LoggingEvent;
-import org.apache.log4j.spi.RootLogger;
-import org.apache.log4j.spi.LoggerRepository;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Map;
-import java.util.Vector;
-import java.util.HashMap;
-import java.io.InputStream;
-import java.io.IOException;
-
-
-/**
- * This test case writes a few events into a databases and reads them
- * back comparing the event written and read back.
- * 
- * <p>It relies heavily on the proper configuration of its environment
- * in joran config files as well system properties.
- * </p>
- * 
- * <p>See also the Ant build file in the tests/ directory.</p> 
- * 
- * @author Ceki G&uuml;lc&uuml;
- */
-public class FullCycleDBTest
-       extends TestCase {
-  
-  Vector<LoggingEvent> witnessEvents;
-  Hierarchy lrWrite;
-  LoggerRepository lrRead;
-  String appendConfigFile = null;
-  String readConfigFile = null;
-  
-  
-  /*
-   * @see TestCase#setUp()
-   */
-  protected void setUp()
-         throws Exception {
-    super.setUp();
-    appendConfigFile = "append-with-drivermanager1.xml";
-    readConfigFile = "read-with-drivermanager1.xml";
-
-    witnessEvents = new Vector<LoggingEvent>();
-    lrWrite = new Hierarchy(new RootLogger(Level.DEBUG));
-    lrRead = new LoggerRepositoryExImpl(new Hierarchy(new RootLogger(Level.DEBUG)));
-
-
-    //
-    //   attempt to define tables in in-memory database
-    //      will throw exception if already defined.
-    //
-        Class.forName("org.hsqldb.jdbcDriver");
-      try (Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:testdb")) {
-          Statement s = connection.createStatement();
-          s.executeUpdate("CREATE TABLE logging_event " +
-                  "( sequence_number   BIGINT NOT NULL, " +
-                  " timestamp         BIGINT NOT NULL, " +
-                  " rendered_message  LONGVARCHAR NOT NULL, " +
-                  " logger_name       VARCHAR NOT NULL, " +
-                  " level_string      VARCHAR NOT NULL, " +
-                  " ndc               LONGVARCHAR, " +
-                  " thread_name       VARCHAR, " +
-                  " reference_flag    SMALLINT, " +
-                  " caller_filename   VARCHAR, " +
-                  " caller_class      VARCHAR, " +
-                  " caller_method     VARCHAR, " +
-                  " caller_line       CHAR(4), " +
-                  " event_id          INT NOT NULL IDENTITY)");
-          s.executeUpdate("CREATE TABLE logging_event_property " +
-                  "( event_id	      INT NOT NULL, " +
-                  " mapped_key        VARCHAR(254) NOT NULL, " +
-                  " mapped_value      LONGVARCHAR, " +
-                  " PRIMARY KEY(event_id, mapped_key), " +
-                  " FOREIGN KEY (event_id) REFERENCES logging_event(event_id))");
-          s.executeUpdate("CREATE TABLE logging_event_exception" +
-                  "  ( event_id         INT NOT NULL, " +
-                  "    i                SMALLINT NOT NULL," +
-                  "    trace_line       VARCHAR NOT NULL," +
-                  "    PRIMARY KEY(event_id, i)," +
-                  "    FOREIGN KEY (event_id) REFERENCES logging_event(event_id))");
-      } catch (SQLException ex) {
-          String s = ex.toString();
-      }
-
-  }
-
-
-  /*
-   * @see TestCase#tearDown()
-   */
-  protected void tearDown()
-         throws Exception {
-    super.tearDown();
-    lrRead.shutdown();
-    witnessEvents = null;
-  }
-
-  public FullCycleDBTest(String arg0) {
-    super(arg0);
-  }
-
-  
-  /**
-   * This test starts by writing a single event to a DB using DBAppender
-   * and then reads it back using DBReceiver.
-   * 
-   * DB related information is specified within the configuration files.
-   * @throws Exception on error
-   */
-  public void testSingleOutput()
-         throws Exception {
-    DOMConfigurator jc1 = new DOMConfigurator();
-    InputStream is = FullCycleDBTest.class.getResourceAsStream(appendConfigFile);
-    jc1.doConfigure(is, lrWrite);
-    is.close();
-  
-    long startTime = System.currentTimeMillis();
-    System.out.println("***startTime is  "+startTime);
-
-    // Write out just one log message
-    Logger out = lrWrite.getLogger("testSingleOutput.out");
-    out.debug("some message"+startTime);
-
-    VectorAppender witnessAppender = (VectorAppender) lrWrite.getRootLogger().getAppender("VECTOR");
-    witnessEvents = witnessAppender.getVector();
-    assertEquals(1, witnessEvents.size());    
-
-    // We have to close all appenders before starting to read
-    lrWrite.shutdown();
-
-    // now read it back
-    readBack(readConfigFile, startTime);
-
-  }
-
-  /**
-   * This test starts by writing a single event to a DB using DBAppender
-   * and then reads it back using DBReceiver.
-   * 
-   * The written event includes MDC and repository properties as well as
-   * exception info.
-   * 
-   * DB related information is specified within the configuration files.
-   * @throws IOException on error
-   */
-  public void testAllFields() throws IOException {
-    DOMConfigurator jc1 = new DOMConfigurator();
-    InputStream is = FullCycleDBTest.class.getResourceAsStream(appendConfigFile);
-    jc1.doConfigure(is, lrWrite);
-    is.close();
-  
-    long startTime = System.currentTimeMillis();
-    
-    // Write out just one log message
-    MDC.put("key1", "value1-"+startTime);
-    MDC.put("key2", "value2-"+startTime);
-    Map mdcMap = MDC.getContext();
-//    LogLog.info("**********"+mdcMap.size());
-    
-    // Write out just one log message
-    Logger out = lrWrite.getLogger("out"+startTime);
-
-    out.debug("some message"+startTime);
-    MDC.put("key3", "value2-"+startTime);
-    out.error("some error message"+startTime, new Exception("testing"));
-    
-    // we clear the MDC to avoid interference with the events read back from
-    // the db
-    MDC.remove("key1");
-    MDC.remove("key2");
-    MDC.remove("key3");
-
-    VectorAppender witnessAppender = (VectorAppender) lrWrite.getRootLogger().getAppender("VECTOR");
-    witnessEvents = witnessAppender.getVector();
-    assertEquals(2, witnessEvents.size());    
-
-    // We have to close all appenders just before starting to read
-    lrWrite.shutdown();
-    
-    readBack(readConfigFile, startTime);
-  }
-
-
-  void readBack(String configfile, long startTime) throws IOException {
-    DOMConfigurator jc2 = new DOMConfigurator();
-    InputStream is = FullCycleDBTest.class.getResourceAsStream(configfile);
-    jc2.doConfigure(is, lrRead);
-    is.close();
-    
-    // wait a little to allow events to be read
-    try { Thread.sleep(3100); } catch(Exception e) {}
-    VectorAppender va = (VectorAppender) lrRead.getRootLogger().getAppender("VECTOR");
-    Vector<LoggingEvent> returnedEvents = getRelevantEventsFromVA(va, startTime);
-    
-    compareEvents(witnessEvents, returnedEvents);
-    
-  }
-  
-  void compareEvents(Vector<LoggingEvent> l, Vector<LoggingEvent> r) {
-    assertNotNull("left vector of events should not be null");
-    assertEquals(l.size(), r.size());
-    
-    for(int i = 0; i < r.size(); i++) {
-      LoggingEvent le = l.get(i);
-      LoggingEvent re = r.get(i);
-      assertEquals(le.getMessage(),        re.getMessage());
-      assertEquals(le.getLoggerName(),     re.getLoggerName());
-      assertEquals(le.getLevel(),          re.getLevel());
-      assertEquals(le.getThreadName(), re.getThreadName());
-      if(re.getTimeStamp() < le.getTimeStamp()) {
-        fail("Returned event cannot preceed witness timestamp");
-      }
-
-      Map sourceMap = re.getProperties();
-      Map remap;
-      if (sourceMap == null) {
-          remap = new HashMap();
-      } else {
-          remap = new HashMap(sourceMap);
-          if (remap.containsKey(Constants.LOG4J_ID_KEY)) {
-              remap.remove(Constants.LOG4J_ID_KEY);
-          }
-      }
-      if(le.getProperties() == null || le.getProperties().size() == 0) {
-        if(remap.size() != 0) {
-          System.out.println("properties are "+remap);
-          fail("Returned event should have been empty");
-        }
-      } else {
-        assertEquals(le.getProperties(), remap);
-      }
-      comprareStringArrays( le.getThrowableStrRep(),  re.getThrowableStrRep());
-      compareLocationInfo(le, re);
-    } 
-  }
-  
-  void comprareStringArrays(String[] la, String[] ra) {
-    if((la == null) && (ra == null)) {
-      return;
-    }
-    assertEquals(la.length, ra.length);
-    for(int i = 0; i < la.length; i++) {
-      assertEquals(la[i], ra[i]);
-    }
-  }
-  
-  void compareLocationInfo(LoggingEvent l, LoggingEvent r) {
-    if(l.locationInformationExists()) {
-      assertEquals(l.getLocationInformation().fullInfo, r.getLocationInformation().fullInfo);
-    } else {
-      assertEquals(LocationInfo.NA_LOCATION_INFO, r.getLocationInformation());
-    }
-  }
-  
-  Vector<LoggingEvent> getRelevantEventsFromVA(VectorAppender va, long startTime) {
-    assertNotNull(va);
-    Vector<LoggingEvent> v = va.getVector();
-    Vector<LoggingEvent> r = new Vector<LoggingEvent>();
-    // remove all elements older than startTime
-      for (Object aV : v) {
-          LoggingEvent event = (LoggingEvent) aV;
-          if (startTime > event.getTimeStamp()) {
-              System.out.println("***Removing event with timestamp " + event.getTimeStamp());
-          } else {
-              System.out.println("***Keeping event with timestamo" + event.getTimeStamp());
-              r.add(event);
-          }
-      }
-    return r;
-  }
-
-  void dump(Vector v) {
-      for (Object aV : v) {
-          LoggingEvent le = (LoggingEvent) aV;
-          System.out.println("---" + le.getLevel() + " " + le.getLoggerName() + " " + le.getMessage());
-      }
-  }
-  
-  public static Test XXsuite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new FullCycleDBTest("testSingleOutput"));
-    suite.addTest(new FullCycleDBTest("testAllFields"));
-    return suite;
-  }
-}
+///*
+// * 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.log4j.db;
+//
+//import junit.framework.Test;
+//import junit.framework.TestCase;
+//import junit.framework.TestSuite;
+//import org.apache.log4j.Hierarchy;
+//import org.apache.log4j.Level;
+//import org.apache.log4j.Logger;
+//import org.apache.log4j.MDC;
+//import org.apache.log4j.VectorAppender;
+//import org.apache.log4j.helpers.Constants;
+//import org.apache.log4j.xml.DOMConfigurator;
+//import org.apache.log4j.spi.LocationInfo;
+//import org.apache.log4j.spi.LoggingEvent;
+//import org.apache.log4j.spi.RootLogger;
+//import org.apache.log4j.spi.LoggerRepository;
+//
+//import java.sql.Connection;
+//import java.sql.DriverManager;
+//import java.sql.SQLException;
+//import java.sql.Statement;
+//import java.util.Map;
+//import java.util.Vector;
+//import java.util.HashMap;
+//import java.io.InputStream;
+//import java.io.IOException;
+//
+//
+///**
+// * This test case writes a few events into a databases and reads them
+// * back comparing the event written and read back.
+// *
+// * <p>It relies heavily on the proper configuration of its environment
+// * in joran config files as well system properties.
+// * </p>
+// *
+// * <p>See also the Ant build file in the tests/ directory.</p>
+// *
+// * @author Ceki G&uuml;lc&uuml;
+// */
+//public class FullCycleDBTest
+//       extends TestCase {
+//
+//  Vector<LoggingEvent> witnessEvents;
+//  Hierarchy lrWrite;
+//  LoggerRepository lrRead;
+//  String appendConfigFile = null;
+//  String readConfigFile = null;
+//
+//
+//  /*
+//   * @see TestCase#setUp()
+//   */
+//  protected void setUp()
+//         throws Exception {
+//    super.setUp();
+//    appendConfigFile = "append-with-drivermanager1.xml";
+//    readConfigFile = "read-with-drivermanager1.xml";
+//
+//    witnessEvents = new Vector<LoggingEvent>();
+//    lrWrite = new Hierarchy(new RootLogger(Level.DEBUG));
+//    lrRead = new LoggerRepositoryExImpl(new Hierarchy(new RootLogger(Level.DEBUG)));
+//
+//
+//    //
+//    //   attempt to define tables in in-memory database
+//    //      will throw exception if already defined.
+//    //
+//        Class.forName("org.hsqldb.jdbcDriver");
+//      try (Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:testdb")) {
+//          Statement s = connection.createStatement();
+//          s.executeUpdate("CREATE TABLE logging_event " +
+//                  "( sequence_number   BIGINT NOT NULL, " +
+//                  " timestamp         BIGINT NOT NULL, " +
+//                  " rendered_message  LONGVARCHAR NOT NULL, " +
+//                  " logger_name       VARCHAR NOT NULL, " +
+//                  " level_string      VARCHAR NOT NULL, " +
+//                  " ndc               LONGVARCHAR, " +
+//                  " thread_name       VARCHAR, " +
+//                  " reference_flag    SMALLINT, " +
+//                  " caller_filename   VARCHAR, " +
+//                  " caller_class      VARCHAR, " +
+//                  " caller_method     VARCHAR, " +
+//                  " caller_line       CHAR(4), " +
+//                  " event_id          INT NOT NULL IDENTITY)");
+//          s.executeUpdate("CREATE TABLE logging_event_property " +
+//                  "( event_id	      INT NOT NULL, " +
+//                  " mapped_key        VARCHAR(254) NOT NULL, " +
+//                  " mapped_value      LONGVARCHAR, " +
+//                  " PRIMARY KEY(event_id, mapped_key), " +
+//                  " FOREIGN KEY (event_id) REFERENCES logging_event(event_id))");
+//          s.executeUpdate("CREATE TABLE logging_event_exception" +
+//                  "  ( event_id         INT NOT NULL, " +
+//                  "    i                SMALLINT NOT NULL," +
+//                  "    trace_line       VARCHAR NOT NULL," +
+//                  "    PRIMARY KEY(event_id, i)," +
+//                  "    FOREIGN KEY (event_id) REFERENCES logging_event(event_id))");
+//      } catch (SQLException ex) {
+//          String s = ex.toString();
+//      }
+//
+//  }
+//
+//
+//  /*
+//   * @see TestCase#tearDown()
+//   */
+//  protected void tearDown()
+//         throws Exception {
+//    super.tearDown();
+//    lrRead.shutdown();
+//    witnessEvents = null;
+//  }
+//
+//  public FullCycleDBTest(String arg0) {
+//    super(arg0);
+//  }
+//
+//
+//  /**
+//   * This test starts by writing a single event to a DB using DBAppender
+//   * and then reads it back using DBReceiver.
+//   *
+//   * DB related information is specified within the configuration files.
+//   * @throws Exception on error
+//   */
+//  public void testSingleOutput()
+//         throws Exception {
+//    DOMConfigurator jc1 = new DOMConfigurator();
+//    InputStream is = FullCycleDBTest.class.getResourceAsStream(appendConfigFile);
+//    jc1.doConfigure(is, lrWrite);
+//    is.close();
+//
+//    long startTime = System.currentTimeMillis();
+//    System.out.println("***startTime is  "+startTime);
+//
+//    // Write out just one log message
+//    Logger out = lrWrite.getLogger("testSingleOutput.out");
+//    out.debug("some message"+startTime);
+//
+//    VectorAppender witnessAppender = (VectorAppender) lrWrite.getRootLogger().getAppender("VECTOR");
+//    witnessEvents = witnessAppender.getVector();
+//    assertEquals(1, witnessEvents.size());
+//
+//    // We have to close all appenders before starting to read
+//    lrWrite.shutdown();
+//
+//    // now read it back
+//    readBack(readConfigFile, startTime);
+//
+//  }
+//
+//  /**
+//   * This test starts by writing a single event to a DB using DBAppender
+//   * and then reads it back using DBReceiver.
+//   *
+//   * The written event includes MDC and repository properties as well as
+//   * exception info.
+//   *
+//   * DB related information is specified within the configuration files.
+//   * @throws IOException on error
+//   */
+//  public void testAllFields() throws IOException {
+//    DOMConfigurator jc1 = new DOMConfigurator();
+//    InputStream is = FullCycleDBTest.class.getResourceAsStream(appendConfigFile);
+//    jc1.doConfigure(is, lrWrite);
+//    is.close();
+//
+//    long startTime = System.currentTimeMillis();
+//
+//    // Write out just one log message
+//    MDC.put("key1", "value1-"+startTime);
+//    MDC.put("key2", "value2-"+startTime);
+//    Map mdcMap = MDC.getContext();
+////    LogLog.info("**********"+mdcMap.size());
+//
+//    // Write out just one log message
+//    Logger out = lrWrite.getLogger("out"+startTime);
+//
+//    out.debug("some message"+startTime);
+//    MDC.put("key3", "value2-"+startTime);
+//    out.error("some error message"+startTime, new Exception("testing"));
+//
+//    // we clear the MDC to avoid interference with the events read back from
+//    // the db
+//    MDC.remove("key1");
+//    MDC.remove("key2");
+//    MDC.remove("key3");
+//
+//    VectorAppender witnessAppender = (VectorAppender) lrWrite.getRootLogger().getAppender("VECTOR");
+//    witnessEvents = witnessAppender.getVector();
+//    assertEquals(2, witnessEvents.size());
+//
+//    // We have to close all appenders just before starting to read
+//    lrWrite.shutdown();
+//
+//    readBack(readConfigFile, startTime);
+//  }
+//
+//
+//  void readBack(String configfile, long startTime) throws IOException {
+//    DOMConfigurator jc2 = new DOMConfigurator();
+//    InputStream is = FullCycleDBTest.class.getResourceAsStream(configfile);
+//    jc2.doConfigure(is, lrRead);
+//    is.close();
+//
+//    // wait a little to allow events to be read
+//    try { Thread.sleep(3100); } catch(Exception e) {}
+//    VectorAppender va = (VectorAppender) lrRead.getRootLogger().getAppender("VECTOR");
+//    Vector<LoggingEvent> returnedEvents = getRelevantEventsFromVA(va, startTime);
+//
+//    compareEvents(witnessEvents, returnedEvents);
+//
+//  }
+//
+//  void compareEvents(Vector<LoggingEvent> l, Vector<LoggingEvent> r) {
+//    assertNotNull("left vector of events should not be null");
+//    assertEquals(l.size(), r.size());
+//
+//    for(int i = 0; i < r.size(); i++) {
+//      LoggingEvent le = l.get(i);
+//      LoggingEvent re = r.get(i);
+//      assertEquals(le.getMessage(),        re.getMessage());
+//      assertEquals(le.getLoggerName(),     re.getLoggerName());
+//      assertEquals(le.getLevel(),          re.getLevel());
+//      assertEquals(le.getThreadName(), re.getThreadName());
+//      if(re.getTimeStamp() < le.getTimeStamp()) {
+//        fail("Returned event cannot preceed witness timestamp");
+//      }
+//
+//      Map sourceMap = re.getProperties();
+//      Map remap;
+//      if (sourceMap == null) {
+//          remap = new HashMap();
+//      } else {
+//          remap = new HashMap(sourceMap);
+//          if (remap.containsKey(Constants.LOG4J_ID_KEY)) {
+//              remap.remove(Constants.LOG4J_ID_KEY);
+//          }
+//      }
+//      if(le.getProperties() == null || le.getProperties().size() == 0) {
+//        if(remap.size() != 0) {
+//          System.out.println("properties are "+remap);
+//          fail("Returned event should have been empty");
+//        }
+//      } else {
+//        assertEquals(le.getProperties(), remap);
+//      }
+//      comprareStringArrays( le.getThrowableStrRep(),  re.getThrowableStrRep());
+//      compareLocationInfo(le, re);
+//    }
+//  }
+//
+//  void comprareStringArrays(String[] la, String[] ra) {
+//    if((la == null) && (ra == null)) {
+//      return;
+//    }
+//    assertEquals(la.length, ra.length);
+//    for(int i = 0; i < la.length; i++) {
+//      assertEquals(la[i], ra[i]);
+//    }
+//  }
+//
+//  void compareLocationInfo(LoggingEvent l, LoggingEvent r) {
+//    if(l.locationInformationExists()) {
+//      assertEquals(l.getLocationInformation().fullInfo, r.getLocationInformation().fullInfo);
+//    } else {
+//      assertEquals(LocationInfo.NA_LOCATION_INFO, r.getLocationInformation());
+//    }
+//  }
+//
+//  Vector<LoggingEvent> getRelevantEventsFromVA(VectorAppender va, long startTime) {
+//    assertNotNull(va);
+//    Vector<LoggingEvent> v = va.getVector();
+//    Vector<LoggingEvent> r = new Vector<LoggingEvent>();
+//    // remove all elements older than startTime
+//      for (Object aV : v) {
+//          LoggingEvent event = (LoggingEvent) aV;
+//          if (startTime > event.getTimeStamp()) {
+//              System.out.println("***Removing event with timestamp " + event.getTimeStamp());
+//          } else {
+//              System.out.println("***Keeping event with timestamo" + event.getTimeStamp());
+//              r.add(event);
+//          }
+//      }
+//    return r;
+//  }
+//
+//  void dump(Vector v) {
+//      for (Object aV : v) {
+//          LoggingEvent le = (LoggingEvent) aV;
+//          System.out.println("---" + le.getLevel() + " " + le.getLoggerName() + " " + le.getMessage());
+//      }
+//  }
+//
+//  public static Test XXsuite() {
+//    TestSuite suite = new TestSuite();
+//    suite.addTest(new FullCycleDBTest("testSingleOutput"));
+//    suite.addTest(new FullCycleDBTest("testAllFields"));
+//    return suite;
+//  }
+//}
