/*
 * 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.chainsaw;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.chainsaw.color.RuleColorizer;
import org.apache.log4j.chainsaw.filter.FilterModel;
import org.apache.log4j.chainsaw.icons.ChainsawIcons;
import org.apache.log4j.chainsaw.icons.LineIconFactory;
import org.apache.log4j.rule.AbstractRule;
import org.apache.log4j.rule.ColorRule;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.LoggingEvent;


/**
 * A panel that encapsulates the Logger Name tree, with associated actions
 * and implements the Rule interface so that it can filter in/out events
 * that do not match the users request for refining the view based on Loggers.
 *
 * @author Paul Smith &lt;psmith@apache.org&gt;
 */
final class LoggerNameTreePanel extends JPanel implements LoggerNameListener
{
  //~ Static fields/initializers ==============================================

  private static final int WARN_DEPTH = 4;

  //~ Instance fields =========================================================

  private LoggerNameTreeCellRenderer cellRenderer =
    new LoggerNameTreeCellRenderer();
  private final Action clearIgnoreListAction;
  private final Action closeAction;
  private final JButton closeButton = new SmallButton();
  private final Action collapseAction;
  private final JButton collapseButton = new SmallButton();
  private final Action editLoggerAction;
  private final JButton editLoggerButton = new SmallButton();
  private final Action expandAction;
  private final Action findAction;
  private final Action clearFindNextAction;
  private final Action defineColorRuleForLoggerAction;
  private final Action setRefineFocusAction;
  private final Action updateRefineFocusAction;
  private final Action updateFindAction;
  private final JButton expandButton = new SmallButton();
  private final Action focusOnAction;
  private final Action clearRefineFocusAction;
  private final SmallToggleButton focusOnLoggerButton =
    new SmallToggleButton();
  private final Set hiddenSet = new HashSet();
  private final Action hideAction;
  private final Action hideSubLoggersAction;
  private final LogPanelPreferenceModel preferenceModel;

  private final JList ignoreList = new JList();
  private final JEditorPane ignoreExpressionEntryField = new JEditorPane();
  private final JEditorPane alwaysDisplayExpressionEntryField = new JEditorPane();
  private final JScrollPane ignoreListScroll = new JScrollPane(ignoreList);
  private final JDialog ignoreDialog = new JDialog();
  private final JDialog ignoreExpressionDialog = new JDialog();
  private final JDialog alwaysDisplayExpressionDialog = new JDialog();
  private final JLabel ignoreSummary = new JLabel("0 hidden loggers");
  private final JLabel ignoreExpressionSummary = new JLabel("Ignore expression");
  private final JLabel alwaysDisplayExpressionSummary = new JLabel("Always displayed expression");
  private final SmallToggleButton ignoreLoggerButton = new SmallToggleButton();
  private final EventListenerList listenerList = new EventListenerList();
  private final JTree logTree;
  private final Logger logger = LogManager.getLogger(LoggerNameTreePanel.class);

  //  private final EventListenerList focusOnActionListeners =
  //    new EventListenerList();
  private final LogPanelLoggerTreeModel logTreeModel;
  private final PopupListener popupListener;
  private final LoggerTreePopupMenu popupMenu;
  private final VisibilityRuleDelegate visibilityRuleDelegate;
  private Rule colorRuleDelegate; 
  private final JScrollPane scrollTree;
  private final JToolBar toolbar = new JToolBar();
  private final LogPanel logPanel;
  private final RuleColorizer colorizer;
  private Rule ignoreExpressionRule;
  private Rule alwaysDisplayExpressionRule;
  private boolean expandRootLatch = false;
  private String currentlySelectedLoggerName;

    //~ Constructors ============================================================

  /**
   * Creates a new LoggerNameTreePanel object.
   *
   * @param logTreeModel
   */
  LoggerNameTreePanel(LogPanelLoggerTreeModel logTreeModel, LogPanelPreferenceModel preferenceModel, LogPanel logPanel, RuleColorizer colorizer, FilterModel filterModel)
  {
    super();
    this.logTreeModel = logTreeModel;
    this.preferenceModel = preferenceModel;
    this.logPanel = logPanel;
    this.colorizer = colorizer;

    setLayout(new BorderLayout());
    ignoreExpressionEntryField.setPreferredSize(new Dimension(300, 150));
    alwaysDisplayExpressionEntryField.setPreferredSize(new Dimension(300, 150));
    alwaysDisplayExpressionSummary.setMinimumSize(new Dimension(10, alwaysDisplayExpressionSummary.getHeight()));
    ignoreExpressionSummary.setMinimumSize(new Dimension(10, ignoreExpressionSummary.getHeight()));
    ignoreSummary.setMinimumSize(new Dimension(10, ignoreSummary.getHeight()));

    JTextComponentFormatter.applySystemFontAndSize(ignoreExpressionEntryField);
    JTextComponentFormatter.applySystemFontAndSize(alwaysDisplayExpressionEntryField);

    visibilityRuleDelegate = new VisibilityRuleDelegate();
    colorRuleDelegate = 
        new AbstractRule()
        {
          public boolean evaluate(LoggingEvent e, Map matches) {
            boolean hiddenLogger = e.getLoggerName() != null && isHiddenLogger(e.getLoggerName());
            boolean hiddenExpression = (ignoreExpressionRule != null && ignoreExpressionRule.evaluate(e, null));
            boolean alwaysDisplayExpression = (alwaysDisplayExpressionRule != null && alwaysDisplayExpressionRule.evaluate(e, null));
            boolean hidden = (!alwaysDisplayExpression) && (hiddenLogger || hiddenExpression);
            String currentlySelectedLoggerName = getCurrentlySelectedLoggerName();

            return !isFocusOnSelected() && !hidden && currentlySelectedLoggerName != null && !"".equals(currentlySelectedLoggerName) && (e.getLoggerName().startsWith(currentlySelectedLoggerName + ".") || e.getLoggerName().endsWith(currentlySelectedLoggerName));
          }
        };

    logTree =
    new JTree(logTreeModel)
      {
        public String getToolTipText(MouseEvent ev)
        {
          if (ev == null)
          {
            return null;
          }

          TreePath path = logTree.getPathForLocation(ev.getX(), ev.getY());

          String loggerName = getLoggerName(path);

          if (hiddenSet.contains(loggerName))
          {
            loggerName += " (you are ignoring this logger)";
          }

          return loggerName;
        }
      };

    ToolTipManager.sharedInstance().registerComponent(logTree);
    logTree.setCellRenderer(cellRenderer);

    //	============================================
    logTreeModel.addTreeModelListener(new TreeModelListener()
      {
        public void treeNodesChanged(TreeModelEvent e)
        {
        }

        public void treeNodesInserted(TreeModelEvent e)
        {
          if (!expandRootLatch)
          {
            ensureRootExpanded();
            expandRootLatch = true;
          }
        }

        public void treeNodesRemoved(TreeModelEvent e)
        {
        }

        public void treeStructureChanged(TreeModelEvent e)
        {
        }
      });

    logTree.setEditable(false);

    //	TODO decide if Multi-selection is useful, and how it would work	
    TreeSelectionModel selectionModel = new DefaultTreeSelectionModel();
    selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    logTree.setSelectionModel(selectionModel);

    logTree.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
    scrollTree = new JScrollPane(logTree);
    toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS));

    expandAction = createExpandAction();
    findAction = createFindNextAction();
    clearFindNextAction = createClearFindNextAction();
    defineColorRuleForLoggerAction = createDefineColorRuleForLoggerAction();
    clearRefineFocusAction = createClearRefineFocusAction();
    setRefineFocusAction = createSetRefineFocusAction();
    updateRefineFocusAction = createUpdateRefineFocusAction();
    updateFindAction = createUpdateFindAction();
    editLoggerAction = createEditLoggerAction();
    closeAction = createCloseAction();
    collapseAction = createCollapseAction();
    focusOnAction = createFocusOnAction();
    hideAction = createIgnoreAction();
    hideSubLoggersAction = createIgnoreAllAction();
    clearIgnoreListAction = createClearIgnoreListAction();

    popupMenu = new LoggerTreePopupMenu();
    popupListener = new PopupListener(popupMenu);

    setupListeners();
    configureToolbarPanel();

    add(toolbar, BorderLayout.NORTH);
    add(scrollTree, BorderLayout.CENTER);

    ignoreDialog.setTitle("Hidden/Ignored Loggers");
    ignoreDialog.setModal(true);

    ignoreExpressionDialog.setTitle("Hidden/Ignored Expression");
    ignoreExpressionDialog.setModal(true);

    alwaysDisplayExpressionDialog.setTitle("Always displayed Expression");
    alwaysDisplayExpressionDialog.setModal(true);

    JPanel ignorePanel = new JPanel();
    ignorePanel.setLayout(new BoxLayout(ignorePanel, BoxLayout.Y_AXIS));
    JPanel ignoreSummaryPanel = new JPanel();
    ignoreSummaryPanel.setLayout(new BoxLayout(ignoreSummaryPanel, BoxLayout.X_AXIS));
    ignoreSummaryPanel.add(ignoreSummary);
    
    Action showIgnoreDialogAction = new AbstractAction("...") {
        public void actionPerformed(ActionEvent e) {
            LogPanel.centerAndSetVisible(ignoreDialog);
        }
    };

    Action showIgnoreExpressionDialogAction = new AbstractAction("...") {
      public void actionPerformed(ActionEvent e) {
          LogPanel.centerAndSetVisible(ignoreExpressionDialog);
      }
    };


    Action showAlwaysDisplayExpressionDialogAction = new AbstractAction("...") {
      public void actionPerformed(ActionEvent e) {
          LogPanel.centerAndSetVisible(alwaysDisplayExpressionDialog);
      }
    };

    showIgnoreDialogAction.putValue(Action.SHORT_DESCRIPTION, "Click to view and manage your hidden/ignored loggers");
    JButton btnShowIgnoreDialog = new SmallButton(showIgnoreDialogAction);
    
    ignoreSummaryPanel.add(btnShowIgnoreDialog);
    ignorePanel.add(ignoreSummaryPanel);

    JPanel ignoreExpressionPanel = new JPanel();
    ignoreExpressionPanel.setLayout(new BoxLayout(ignoreExpressionPanel, BoxLayout.X_AXIS));
    ignoreExpressionPanel.add(ignoreExpressionSummary);
    showIgnoreExpressionDialogAction.putValue(Action.SHORT_DESCRIPTION, "Click to view and manage your hidden/ignored expression");
    JButton btnShowIgnoreExpressionDialog = new SmallButton(showIgnoreExpressionDialogAction);
    ignoreExpressionPanel.add(btnShowIgnoreExpressionDialog);

    ignorePanel.add(ignoreExpressionPanel);

    JPanel alwaysDisplayExpressionPanel = new JPanel();
    alwaysDisplayExpressionPanel.setLayout(new BoxLayout(alwaysDisplayExpressionPanel, BoxLayout.X_AXIS));
    alwaysDisplayExpressionPanel.add(alwaysDisplayExpressionSummary);
    showAlwaysDisplayExpressionDialogAction.putValue(Action.SHORT_DESCRIPTION, "Click to view and manage your always-displayed expression");
    JButton btnShowAlwaysDisplayExpressionDialog = new SmallButton(showAlwaysDisplayExpressionDialogAction);
    alwaysDisplayExpressionPanel.add(btnShowAlwaysDisplayExpressionDialog);

    ignorePanel.add(alwaysDisplayExpressionPanel);

    add(ignorePanel, BorderLayout.SOUTH);

    ignoreList.setModel(new DefaultListModel());
    ignoreList.addMouseListener(new MouseAdapter()
      {
        public void mouseClicked(MouseEvent e)
        {
          if (
            (e.getClickCount() > 1)
              && ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0))
          {
            int index = ignoreList.locationToIndex(e.getPoint());

            if (index >= 0)
            {
              String string =
                ignoreList.getModel().getElementAt(index).toString();
              toggleHiddenLogger(string);
              fireChangeEvent();

              /**
               * TODO this needs to get the node that has this logger and fire a visual update
               */
              LoggerNameTreePanel.this.logTreeModel.nodeStructureChanged(
                (TreeNode) LoggerNameTreePanel.this.logTreeModel.getRoot());
            }
          }
        }
      });
    
    JPanel ignoreListPanel = new JPanel(new BorderLayout());
    ignoreListScroll.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),"Double click an entry to unhide it"));
    ignoreListPanel.add(ignoreListScroll, BorderLayout.CENTER);

    JPanel ignoreExpressionDialogPanel = new JPanel(new BorderLayout());
    ignoreExpressionEntryField.addKeyListener(new ExpressionRuleContext(filterModel, ignoreExpressionEntryField));

    ignoreExpressionDialogPanel.add(new JScrollPane(ignoreExpressionEntryField), BorderLayout.CENTER);
    JButton ignoreExpressionCloseButton = new JButton(new AbstractAction(" Close ") {
          public void actionPerformed(ActionEvent e)
          {
              String ignoreText = ignoreExpressionEntryField.getText();

              if (updateIgnoreExpression(ignoreText)) {
                ignoreExpressionDialog.setVisible(false);
              }
          }});


    JPanel alwaysDisplayExpressionDialogPanel = new JPanel(new BorderLayout());
    alwaysDisplayExpressionEntryField.addKeyListener(new ExpressionRuleContext(filterModel, alwaysDisplayExpressionEntryField));

    alwaysDisplayExpressionDialogPanel.add(new JScrollPane(alwaysDisplayExpressionEntryField), BorderLayout.CENTER);
    JButton alwaysDisplayExpressionCloseButton = new JButton(new AbstractAction(" Close ") {
          public void actionPerformed(ActionEvent e)
          {
              String alwaysDisplayText = alwaysDisplayExpressionEntryField.getText();

              if (updateAlwaysDisplayExpression(alwaysDisplayText)) {
                alwaysDisplayExpressionDialog.setVisible(false);
              }
          }});

    JPanel closeAlwaysDisplayExpressionPanel = new JPanel();
    closeAlwaysDisplayExpressionPanel.add(alwaysDisplayExpressionCloseButton);
    alwaysDisplayExpressionDialogPanel.add(closeAlwaysDisplayExpressionPanel, BorderLayout.SOUTH);

    JPanel closeIgnoreExpressionPanel = new JPanel();
    closeIgnoreExpressionPanel.add(ignoreExpressionCloseButton);
    ignoreExpressionDialogPanel.add(closeIgnoreExpressionPanel, BorderLayout.SOUTH);

    Box ignoreListButtonPanel = Box.createHorizontalBox();
    
    JButton unhideAll = new JButton(new AbstractAction(" Unhide All ") {

        public void actionPerformed(final ActionEvent e)
        {
             SwingUtilities.invokeLater(() -> clearIgnoreListAction.actionPerformed(e));
            
        }});
    ignoreListButtonPanel.add(unhideAll);
    
    ignoreListButtonPanel.add(Box.createHorizontalGlue());
    JButton ignoreCloseButton = new JButton(new AbstractAction(" Close ") {

        public void actionPerformed(ActionEvent e)
        {
            ignoreDialog.setVisible(false);
            
        }});
    ignoreListButtonPanel.add(ignoreCloseButton);
    
    
    ignoreListPanel.add(ignoreListButtonPanel, BorderLayout.SOUTH);
    
    
    ignoreDialog.getContentPane().add(ignoreListPanel);
    ignoreDialog.pack();

    ignoreExpressionDialog.getContentPane().add(ignoreExpressionDialogPanel);
    ignoreExpressionDialog.pack();

    alwaysDisplayExpressionDialog.getContentPane().add(alwaysDisplayExpressionDialogPanel);
    alwaysDisplayExpressionDialog.pack();
  }

    private boolean updateIgnoreExpression(String ignoreText)
    {
        try {
            if (ignoreText != null && !ignoreText.trim().equals("")) {
                ignoreExpressionRule = ExpressionRule.getRule(ignoreText);
            } else {
                ignoreExpressionRule = null;
            }
            visibilityRuleDelegate.firePropertyChange("hiddenSet", null, null);

            updateDisplay();
            ignoreExpressionEntryField.setBackground(UIManager.getColor("TextField.background"));
            return true;
        } catch (IllegalArgumentException iae) {
            ignoreExpressionEntryField.setToolTipText(iae.getMessage());
            ignoreExpressionEntryField.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND);
            return false;
        }
    }

    private boolean updateAlwaysDisplayExpression(String alwaysDisplayText)
    {
        try {
            if (alwaysDisplayText != null && !alwaysDisplayText.trim().equals("")) {
                alwaysDisplayExpressionRule = ExpressionRule.getRule(alwaysDisplayText);
            } else {
                alwaysDisplayExpressionRule = null;
            }
            visibilityRuleDelegate.firePropertyChange("alwaysDisplayedSet", null, null);

            updateDisplay();
            alwaysDisplayExpressionEntryField.setBackground(UIManager.getColor("TextField.background"));
            return true;
        } catch (IllegalArgumentException iae) {
            alwaysDisplayExpressionEntryField.setToolTipText(iae.getMessage());
            alwaysDisplayExpressionEntryField.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND);
            return false;
        }
    }

    //~ Methods =================================================================

  /**
   * Adds a change Listener to this LoggerNameTreePanel to be notfied
   * when the State of the Focus or Hidden details have changed.
   *
   * @param l
   */
  public void addChangeListener(ChangeListener l)
  {
    listenerList.add(ChangeListener.class, l);
  }

  public Rule getLoggerColorRule() {
  	return colorRuleDelegate;
  }

  public Rule getLoggerVisibilityRule() {
      return visibilityRuleDelegate;
  }

  /**
   * DOCUMENT ME!
   *
   * @param l DOCUMENT ME!
   */
  public void removeChangeListener(ChangeListener l)
  {
    listenerList.remove(ChangeListener.class, l);
  }

  /**
   * Ensures the Focus is set to a specific logger name
   * @param
   */
  public void setFocusOn(String newLogger)
  {
    DefaultMutableTreeNode node = logTreeModel.lookupLogger(newLogger);

    if (node != null)
    {
      TreeNode[] nodes = node.getPath();
      TreePath treePath = new TreePath(nodes);
      logTree.setSelectionPath(treePath);

      if (!focusOnLoggerButton.isSelected())
      {
        focusOnLoggerButton.doClick();
      }
    }
    else
    {
      logger.error("failed to lookup logger " + newLogger);
    }
  }

  private boolean isHiddenLogger(String loggerName) {
    for (Object aHiddenSet : hiddenSet) {
      String hiddenLoggerEntry = aHiddenSet.toString();
      if (loggerName.startsWith(hiddenLoggerEntry + ".") || loggerName.endsWith(hiddenLoggerEntry)) {
        return true;
      }
    }
    return false;
  }



  /**
   * DOCUMENT ME!
   *
   * @param logger
   */
  protected void toggleHiddenLogger(String logger)
  {
    if (!hiddenSet.contains(logger))
    {
      hiddenSet.add(logger);
    }
    else
    {
      hiddenSet.remove(logger);
    }

    visibilityRuleDelegate.firePropertyChange("hiddenSet", null, null);
  }

  /**
   * Returns the full name of the Logger that is represented by
   * the currently selected Logger node in the tree.
   *
   * This is the dotted name, of the current node including all it's parents.
   *
   * If multiple Nodes are selected, the first path is used
   * @return Logger Name or null if nothing selected
   */
  String getCurrentlySelectedLoggerName()
  {
    TreePath[] paths = logTree.getSelectionPaths();

    if ((paths == null) || (paths.length == 0))
    {
      return null;
    }

    TreePath firstPath = paths[0];

    return getLoggerName(firstPath);
  }

  /**
   * Returns the full
   * @param path DOCUMENT ME!
   * @return
   */
  String getLoggerName(TreePath path)
  {
    if (path != null)
    {
      Object[] objects = path.getPath();
      StringBuilder buf = new StringBuilder();

      for (int i = 1; i < objects.length; i++)
      {
        buf.append(objects[i].toString());

        if (i < (objects.length - 1))
        {
          buf.append(".");
        }
      }

      return buf.toString();
    }

    return null;
  }

  /**
   * adds a Collection of Strings to the ignore List and notifise all listeners of
   * both the "hiddenSet" property and those expecting the Rule to change
   * via the ChangeListener interface 
   * @param fqnLoggersToIgnore
   */
  void ignore(Collection fqnLoggersToIgnore)
  {
    hiddenSet.addAll(fqnLoggersToIgnore);
    visibilityRuleDelegate.firePropertyChange("hiddenSet", null, null);
    fireChangeEvent();
  }

  /**
   * Returns true if the FocusOn element has been selected
   * @return true if the FocusOn action/lement has been selected
   */
  boolean isFocusOnSelected()
  {
    return focusOnAction.getValue("checked") != null;
  }

  void setFocusOnSelected(boolean selected)
  {
    if (selected)
    {
      focusOnAction.putValue("checked", Boolean.TRUE);
    }
    else
    {
      focusOnAction.putValue("checked", null);
    }
  }

  /**
   * Given the currently selected nodes
   * collapses all the children of those nodes.
   *
   */
  private void collapseCurrentlySelectedNode()
  {
    TreePath[] paths = logTree.getSelectionPaths();

    if (paths == null)
    {
      return;
    }

      logger.debug("Collapsing all children of selected node");

    for (TreePath path : paths) {
      DefaultMutableTreeNode node =
              (DefaultMutableTreeNode) path.getLastPathComponent();
      Enumeration enumeration = node.depthFirstEnumeration();

      while (enumeration.hasMoreElements()) {
        DefaultMutableTreeNode child =
                (DefaultMutableTreeNode) enumeration.nextElement();

        if ((child.getParent() != null) && (child != node)) {
          TreeNode[] nodes =
                  ((DefaultMutableTreeNode) child.getParent()).getPath();

          TreePath treePath = new TreePath(nodes);
          logTree.collapsePath(treePath);
        }
      }
    }

    ensureRootExpanded();
  }

  /**
     * configures all the components that are used in the mini-toolbar of this
     * component
     */
  private void configureToolbarPanel()
  {
    toolbar.setFloatable(false);

    expandButton.setAction(expandAction);
    expandButton.setText(null);
    collapseButton.setAction(collapseAction);
    collapseButton.setText(null);
    focusOnLoggerButton.setAction(focusOnAction);
    focusOnLoggerButton.setText(null);
    ignoreLoggerButton.setAction(hideAction);
    ignoreLoggerButton.setText(null);

    expandButton.setFont(expandButton.getFont().deriveFont(Font.BOLD));
    collapseButton.setFont(collapseButton.getFont().deriveFont(Font.BOLD));

    editLoggerButton.setAction(editLoggerAction);
    editLoggerButton.setText(null);
    closeButton.setAction(closeAction);
    closeButton.setText(null);

    toolbar.add(expandButton);
    toolbar.add(collapseButton);
    toolbar.addSeparator();
    toolbar.add(focusOnLoggerButton);
    toolbar.add(ignoreLoggerButton);

    //    toolbar.add(editLoggerButton);
    toolbar.addSeparator();

    toolbar.add(Box.createHorizontalGlue());
    toolbar.add(closeButton);
    toolbar.add(Box.createHorizontalStrut(5));
  }

  /**
   * DOCUMENT ME!
   *
   * @return
  */
  private Action createClearIgnoreListAction()
  {
    Action action = new AbstractAction("Clear Ignore list", null)
      {
        public void actionPerformed(ActionEvent e)
        {
          ignoreLoggerButton.setSelected(false);
          logTreeModel.reload();
          hiddenSet.clear();
          fireChangeEvent();
        }
      };

    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Removes all entries from the Ignore list so you can see their events in the view");

    return action;
  }

  /**
     * An action that closes (hides) this panel
    * @return
    */
  private Action createCloseAction()
  {
    Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
            preferenceModel.setLogTreePanelVisible(false);
        }
      };

    action.putValue(Action.NAME, "Close");
    action.putValue(Action.SHORT_DESCRIPTION, "Closes the Logger panel");
    action.putValue(Action.SMALL_ICON, LineIconFactory.createCloseIcon());

    return action;
  }

  /**
   * DOCUMENT ME!
   *
   * @return
  */
  private Action createCollapseAction()
  {
    Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
          collapseCurrentlySelectedNode();
        }
      };

    action.putValue(Action.SMALL_ICON, LineIconFactory.createCollapseIcon());
    action.putValue(Action.NAME, "Collapse Branch");
    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Collapses all the children of the currently selected node");
    action.setEnabled(false);

    return action;
  }

  private Action createEditLoggerAction()
  {
    Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
          // TODO Auto-generated method stub
        }
      };

    //    TODO enable this when it's ready.
    action.putValue("enabled", Boolean.FALSE);

    action.putValue(Action.NAME, "Edit filters/colors");
    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Allows you to specify filters and coloring for this Logger");
    action.putValue(
      Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_EDIT_RECEIVER));
    action.setEnabled(false);

    return action;
  }

  /**
   * Creates an action that is used to expand the selected node
   * and all children
   * @return an Action
   */
  private Action createExpandAction()
  {
    Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
          expandCurrentlySelectedNode();
        }
      };

    action.putValue(Action.SMALL_ICON, LineIconFactory.createExpandIcon());
    action.putValue(Action.NAME, "Expand branch");
    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Expands all the child nodes of the currently selected node, recursively");
    action.setEnabled(false);

    return action;
  }

    /**
     * Creates an action that is used to find the next match of the selected node (similar to default selection behavior
     * except the search field is populated and the next match is selected.
     * @return an Action
     */
    private Action createFindNextAction()
    {
      Action action = new AbstractAction()
        {
          public void actionPerformed(ActionEvent e)
          {
            findNextUsingCurrentlySelectedNode();
          }
        };

      action.putValue(Action.NAME, "Find next");
      action.putValue(
        Action.SHORT_DESCRIPTION,
        "Find using the selected node");
      action.setEnabled(false);

      return action;
    }

    private Action createSetRefineFocusAction()
    {
      Action action = new AbstractAction()
        {
          public void actionPerformed(ActionEvent e)
          {
            setRefineFocusUsingCurrentlySelectedNode();
          }
        };

      action.putValue(Action.NAME, "Set 'refine focus' to selected logger");
      action.putValue(
        Action.SHORT_DESCRIPTION,
        "Refine focus on the selected node");
      action.setEnabled(false);

      return action;
    }

    private Action createUpdateRefineFocusAction()
    {
      Action action = new AbstractAction()
        {
          public void actionPerformed(ActionEvent e)
          {
            updateRefineFocusUsingCurrentlySelectedNode();
          }
        };

      action.putValue(Action.NAME, "Update 'refine focus' to include selected logger");
      action.putValue(
        Action.SHORT_DESCRIPTION,
        "Add selected node to 'refine focus' field");
      action.setEnabled(false);

      return action;
    }

  private Action createUpdateFindAction()
  {
    Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
          updateFindUsingCurrentlySelectedNode();
        }
      };

    action.putValue(Action.NAME, "Update 'find' to include selected logger");
    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Add selected node to 'find' field");
    action.setEnabled(false);

    return action;
  }

  private void updateFindUsingCurrentlySelectedNode()
  {
      String selectedLogger = getCurrentlySelectedLoggerName();
      TreePath[] paths = logTree.getSelectionPaths();

      if (paths == null)
      {
        return;
      }
      String currentFindText = logPanel.getFindText();
      logPanel.setFindText(currentFindText + " || logger ~= " + selectedLogger);
  }

    private void updateRefineFocusUsingCurrentlySelectedNode()
    {
        String selectedLogger = getCurrentlySelectedLoggerName();
        TreePath[] paths = logTree.getSelectionPaths();

        if (paths == null)
        {
          return;
        }
        String currentFilterText = logPanel.getRefineFocusText();
        logPanel.setRefineFocusText(currentFilterText + " || logger ~= " + selectedLogger);
    }

    private void setRefineFocusUsingCurrentlySelectedNode()
    {
        String selectedLogger = getCurrentlySelectedLoggerName();
        TreePath[] paths = logTree.getSelectionPaths();

        if (paths == null)
        {
          return;
        }
        logPanel.setRefineFocusText("logger ~= " + selectedLogger);
    }

    private Action createDefineColorRuleForLoggerAction() {
        Action action = new AbstractAction()
          {
            public void actionPerformed(ActionEvent e)
            {
                String selectedLogger = getCurrentlySelectedLoggerName();
                TreePath[] paths = logTree.getSelectionPaths();

                if (paths == null)
                {
                  return;
                }
            Color c = JColorChooser.showDialog(getRootPane(), "Choose a color", Color.red);
            if (c != null) {
                String expression = "logger like '^" + selectedLogger + ".*'";
                colorizer.addRule(ChainsawConstants.DEFAULT_COLOR_RULE_NAME, new ColorRule(expression,
                        ExpressionRule.getRule(expression), c, ChainsawConstants.COLOR_DEFAULT_FOREGROUND));
            }
        }};

        action.putValue(Action.NAME, "Define color rule for selected logger");
        action.putValue(
          Action.SHORT_DESCRIPTION,
          "Define color rule for logger");
        action.setEnabled(false);
        return action;
    }

    /**
     * Creates an action that is used to find the next match of the selected node (similar to default selection behavior
     * except the search field is populated and the next match is selected.
     * @return an Action
     */
    private Action createClearFindNextAction()
    {
      Action action = new AbstractAction()
        {
          public void actionPerformed(ActionEvent e)
          {
            clearFindNext();
          }
        };

      action.putValue(Action.NAME, "Clear find field");
      action.putValue(
        Action.SHORT_DESCRIPTION,
        "Clear the find field");
      action.setEnabled(false);

      return action;
    }

    private Action createClearRefineFocusAction()
    {
      Action action = new AbstractAction()
        {
          public void actionPerformed(ActionEvent e)
          {
            clearRefineFocus();
          }
        };

      action.putValue(Action.NAME, "Clear 'refine focus' field");
      action.putValue(
        Action.SHORT_DESCRIPTION,
        "Clear the refine focus field");
      action.setEnabled(false);

      return action;
    }

  /**
   * DOCUMENT ME!
   *
   * @return
  */
  private Action createFocusOnAction()
  {
    final Action action = new AbstractAction()
      {
        public void actionPerformed(ActionEvent e)
        {
          toggleFocusOnState();
        }
      };

    action.putValue(Action.NAME, "Focus");
    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Allows you to Focus on the selected logger by setting a filter that discards all but this Logger");
    action.putValue(
      Action.SMALL_ICON, new ImageIcon(ChainsawIcons.WINDOW_ICON));

    action.setEnabled(false);

    return action;
  }

    /**
     * DOCUMENT ME!
     *
     * @return
      */
    private Action createIgnoreAllAction()
    {
      Action action =
        new AbstractAction(
          "Ignore loggers below selection")
        {
          public void actionPerformed(ActionEvent e)
          {
            //add all top level loggers as hidden loggers
              TreePath[] paths = logTree.getSelectionPaths();

              StringBuilder parentPathString = new StringBuilder();
              DefaultMutableTreeNode root;
              if ((paths == null) || (paths.length == 0))
              {
                  root = (DefaultMutableTreeNode) logTreeModel.getRoot();
              } else {
                  root = (DefaultMutableTreeNode) logTree.getSelectionPath().getLastPathComponent();
                  TreeNode[] path = root.getPath();
                  //don't add 'root logger' to path string
                  for (int i=1;i<path.length;i++) {
                      if (i > 1) {
                          parentPathString.append(".");
                      }
                      parentPathString.append(path[i].toString());
                  }
                  if (!(parentPathString.toString().equals(""))) {
                      parentPathString.append(".");
                  }
              }
              Enumeration topLevelLoggersEnumeration = root.children();
              Set topLevelLoggersSet = new HashSet();
              while (topLevelLoggersEnumeration.hasMoreElements()) {
                  String thisLogger = topLevelLoggersEnumeration.nextElement().toString();
                  topLevelLoggersSet.add(parentPathString + thisLogger);
              }
              if (topLevelLoggersSet.size() > 0) {
                  ignore(topLevelLoggersSet);
              }

              logTreeModel.nodeChanged(root);
              ignoreLoggerButton.setSelected(false);
              focusOnAction.setEnabled(false);
              popupMenu.hideCheck.setSelected(false);
              fireChangeEvent();
          }
        };

      action.putValue(
        Action.SHORT_DESCRIPTION,
        "Adds all loggers to your Ignore list (unhide loggers you want to see in the view)");

      return action;
    }

  /**
   * DOCUMENT ME!
   *
   * @return
    */
  private Action createIgnoreAction()
  {
    Action action =
      new AbstractAction(
        "Ignore this Logger", new ImageIcon(ChainsawIcons.ICON_COLLAPSE))
      {
        public void actionPerformed(ActionEvent e)
        {
          String logger = getCurrentlySelectedLoggerName();

          if (logger != null)
          {
            toggleHiddenLogger(logger);
            logTreeModel.nodeChanged(
              (TreeNode) logTree.getSelectionPath().getLastPathComponent());
            ignoreLoggerButton.setSelected(hiddenSet.contains(logger));
            focusOnAction.setEnabled(!hiddenSet.contains(logger));
            popupMenu.hideCheck.setSelected(hiddenSet.contains(logger));
          }

          fireChangeEvent();
        }
      };

    action.putValue(
      Action.SHORT_DESCRIPTION,
      "Adds the selected Logger to your Ignore list, filtering those events from view");

    return action;
  }

  private void ensureRootExpanded()
  {
      logger.debug("Ensuring Root node is expanded.");

    final DefaultMutableTreeNode root =
      (DefaultMutableTreeNode) logTreeModel.getRoot();
    SwingUtilities.invokeLater(() -> logTree.expandPath(new TreePath(root)));
  }

  private void findNextUsingCurrentlySelectedNode()
  {
      String selectedLogger = getCurrentlySelectedLoggerName();
      TreePath[] paths = logTree.getSelectionPaths();

      if (paths == null)
      {
        return;
      }
      logPanel.setFindText("logger like '^" + selectedLogger + ".*'");
  }

  private void clearFindNext()
  {
      logPanel.setFindText("");
  }

  private void clearRefineFocus()
  {
      logPanel.setRefineFocusText("");
  }

  /**
   * Expands the currently selected node (if any)
   * including all the children.
   *
   */
  private void expandCurrentlySelectedNode()
  {
    TreePath[] paths = logTree.getSelectionPaths();

    if (paths == null)
    {
      return;
    }

      logger.debug("Expanding all children of selected node");

    for (TreePath path : paths) {
      /**
       * TODO this is commented out, right now it expands all nodes including the root, so if there is a large tree..... look out.
       */

      //      /**
      //       * Handle an expansion of the Root node by only doing the first level.
      //       * Safe...
      //       */
      //      if (path.getPathCount() == 1) {
      //        logTree.expandPath(path);
      //
      //        return;
      //      }

      DefaultMutableTreeNode treeNode =
              (DefaultMutableTreeNode) path.getLastPathComponent();

      Enumeration depthEnum = treeNode.depthFirstEnumeration();

      if (!depthEnum.hasMoreElements()) {
        break;
      }

      List depths = new ArrayList();

      while (depthEnum.hasMoreElements()) {
        depths.add(
                ((DefaultMutableTreeNode) depthEnum.nextElement()).getDepth());
      }

      Collections.sort(depths);
      Collections.reverse(depths);

      int maxDepth = (Integer) depths.get(0);

      if (maxDepth > WARN_DEPTH) {
        logger.warn("Should warn user, depth=" + maxDepth);
      }

      depthEnum = treeNode.depthFirstEnumeration();

      while (depthEnum.hasMoreElements()) {
        DefaultMutableTreeNode node =
                (DefaultMutableTreeNode) depthEnum.nextElement();

        if (node.isLeaf() && node.getParent() != null) {
          TreeNode[] nodes =
                  ((DefaultMutableTreeNode) node.getParent()).getPath();
          TreePath treePath = new TreePath(nodes);

          logger.debug("Expanding path:" + treePath);

          logTree.expandPath(treePath);
        }
      }
    }
  }

  private void fireChangeEvent()
  {
    ChangeListener[] listeners =
            listenerList.getListeners(ChangeListener.class);
    ChangeEvent e = null;

    for (ChangeListener listener : listeners) {
      if (e == null) {
        e = new ChangeEvent(this);
      }

      listener.stateChanged(e);
    }
  }

  private void reconfigureMenuText()
  {
    String logger = getCurrentlySelectedLoggerName();

    if ((logger == null) || (logger.length() == 0))
    {
      focusOnAction.putValue(Action.NAME, "Focus On...");
      hideAction.putValue(Action.NAME, "Ignore...");
      findAction.putValue(Action.NAME, "Find...");
      setRefineFocusAction.putValue(Action.NAME, "Set refine focus field");
      updateRefineFocusAction.putValue(Action.NAME, "Add to refine focus field");
      updateFindAction.putValue(Action.NAME, "Add to find field");
      defineColorRuleForLoggerAction.putValue(Action.NAME, "Define color rule");
    }
    else
    {
      focusOnAction.putValue(Action.NAME, "Focus On '" + logger + "'");
      hideAction.putValue(Action.NAME, "Ignore '" + logger + "'");
      findAction.putValue(Action.NAME, "Find '" + logger + "'");
      setRefineFocusAction.putValue(Action.NAME, "Set refine focus field to '" + logger + "'");
      updateRefineFocusAction.putValue(Action.NAME, "Add '" + logger + "' to 'refine focus' field");
      updateFindAction.putValue(Action.NAME, "Add '" + logger + "' to 'find' field");
      defineColorRuleForLoggerAction.putValue(Action.NAME, "Define color rule for '" + logger + "'");
    }

    // need to ensure the button doens't update itself with the text, looks stupid otherwise
    hideSubLoggersAction.putValue(Action.NAME, "Ignore loggers below selection");
    focusOnLoggerButton.setText(null);
    ignoreLoggerButton.setText(null);
  }

  /**
    * Configures varoius listeners etc for the components within
    * this Class.
    */
  private void setupListeners()
  {
    logTree.addMouseMotionListener(new MouseKeyIconListener());

    /**
       * Enable the actions depending on state of the tree selection
       */
    logTree.addTreeSelectionListener(e -> {
      TreePath path = e.getNewLeadSelectionPath();
      TreeNode node = null;

      if (path != null)
      {
        node = (TreeNode) path.getLastPathComponent();
      }
      boolean focusOnSelected = isFocusOnSelected();
      //          editLoggerAction.setEnabled(path != null);
      currentlySelectedLoggerName = getCurrentlySelectedLoggerName();
      focusOnAction.setEnabled(
        (path != null) && (node != null) && (node.getParent() != null)
        && !hiddenSet.contains(currentlySelectedLoggerName));
      hideAction.setEnabled(
        (path != null) && (node != null) && (node.getParent() != null));
      if (!focusOnAction.isEnabled())
      {
        setFocusOnSelected(false);
      }
      else
      {
      }

      expandAction.setEnabled(path != null);
      findAction.setEnabled(path != null);
      clearFindNextAction.setEnabled(true);
      defineColorRuleForLoggerAction.setEnabled(path != null);
      setRefineFocusAction.setEnabled(path != null);
      updateRefineFocusAction.setEnabled(path != null);
      updateFindAction.setEnabled(path != null);
      clearRefineFocusAction.setEnabled(true);

      if (currentlySelectedLoggerName != null)
      {
        boolean isHidden = hiddenSet.contains(currentlySelectedLoggerName);
        popupMenu.hideCheck.setSelected(isHidden);
        ignoreLoggerButton.setSelected(isHidden);
      }

      collapseAction.setEnabled(path != null);

      reconfigureMenuText();
      if (isFocusOnSelected()) {
          fireChangeEvent();
      }
      //fire change event if we toggled focus off
      if (focusOnSelected && !isFocusOnSelected()) {
          fireChangeEvent();
      }
      //trigger a table repaint
      logPanel.repaint();
    });

    logTree.addMouseListener(popupListener);

    /**
     * This listener ensures the Tool bar toggle button and popup menu check box
     * stay in sync, plus notifies all the ChangeListeners that
     * an effective filter criteria has been modified
     */
    focusOnAction.addPropertyChangeListener(evt -> {
      popupMenu.focusOnCheck.setSelected(isFocusOnSelected());
      focusOnLoggerButton.setSelected(isFocusOnSelected());

      if (logTree.getSelectionPath() != null)
      {
        logTreeModel.nodeChanged(
          (TreeNode) logTree.getSelectionPath().getLastPathComponent());
      }
    });

    hideAction.addPropertyChangeListener(evt -> {
      if (logTree.getSelectionPath() != null)
      {
        logTreeModel.nodeChanged(
          (TreeNode) logTree.getSelectionPath().getLastPathComponent());
      }
    });

    //    /**
    //     * Now add a MouseListener that fires the expansion
    //     * action if CTRL + DBL CLICK is done.
    //     */
    //    logTree.addMouseListener(
    //      new MouseAdapter() {
    //        public void mouseClicked(MouseEvent e) {
    //          if (
    //            (e.getClickCount() > 1)
    //              && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
    //              && ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0)) {
    //            expandCurrentlySelectedNode();
    //            e.consume();
    //          } else if (e.getClickCount() > 1) {
    //            super.mouseClicked(e);
    //            logger.debug("Ignoring dbl click event " + e);
    //          }
    //        }
    //      });

    logTree.addMouseListener(new MouseFocusOnListener());

    /**
     * We listen for when the FocusOn action changes, and then  translate
     * that to a RuleChange
     */
    addChangeListener(evt -> {
      visibilityRuleDelegate.firePropertyChange("rule", null, null);
      updateDisplay();
    });

    visibilityRuleDelegate.addPropertyChangeListener(event -> {
      if (event.getPropertyName().equals("hiddenSet")) {
        updateDisplay();
      }
    });
  }

  private void updateDisplay() {
      updateHiddenSetModels();
      updateIgnoreSummary();
      updateIgnoreExpressionSummary();
      updateAlwaysDisplayExpressionSummary();
  }
  
  private void updateHiddenSetModels() {
      DefaultListModel model = (DefaultListModel) ignoreList.getModel();
      model.clear();
      List sortedIgnoreList = new ArrayList(hiddenSet);
      Collections.sort(sortedIgnoreList);

    for (Object aSortedIgnoreList : sortedIgnoreList) {
      String string = (String) aSortedIgnoreList;
      model.addElement(string);
    }

//      ignoreList.setModel(model);

  }
  private void updateIgnoreSummary() {
      ignoreSummary.setText(ignoreList.getModel().getSize() + " hidden loggers");
  }

  private void updateIgnoreExpressionSummary() {
    ignoreExpressionSummary.setText(ignoreExpressionRule != null?"Ignore (set)":"Ignore (unset)");
  }
  
  private void updateAlwaysDisplayExpressionSummary() {
    alwaysDisplayExpressionSummary.setText(alwaysDisplayExpressionRule != null?"Always displayed (set)":"Always displayed (unset)");
  }

  private void toggleFocusOnState()
  {
    setFocusOnSelected(!isFocusOnSelected());
    fireChangeEvent();
  }

    public Collection getHiddenSet() {
        return Collections.unmodifiableSet(hiddenSet);
    }

    public String getHiddenExpression() {
        String text = ignoreExpressionEntryField.getText();
        if (text == null || text.trim().equals("")) {
            return null;
        }
        return text.trim();
    }

    public void setHiddenExpression(String hiddenExpression) {
        ignoreExpressionEntryField.setText(hiddenExpression);
        updateIgnoreExpression(hiddenExpression);
    }

    public String getAlwaysDisplayExpression() {
        String text = alwaysDisplayExpressionEntryField.getText();
        if (text == null || text.trim().equals("")) {
            return null;
        }
        return text.trim();
    }

    public void setAlwaysDisplayExpression(String alwaysDisplayExpression) {
        alwaysDisplayExpressionEntryField.setText(alwaysDisplayExpression);
        updateAlwaysDisplayExpression(alwaysDisplayExpression);
    }

    public void loggerNameAdded(String loggerName)
    {
        //no-op
    }

    public void reset()
    {
        expandRootLatch = false;
        //keep track if focuson was active when we were reset
        final String logger = currentlySelectedLoggerName;
        final boolean focusOnSelected = isFocusOnSelected();
        if (logger == null || !focusOnSelected) {
            return;
        }

        //loggernameAdded runs on EDT
        logTreeModel.loggerNameAdded(logger);
        EventQueue.invokeLater(() -> setFocusOn(logger));
    }

    //~ Inner Classes ===========================================================

  /**
   * DOCUMENT ME!
   *
   * @author $author$
   * @version $Revision$, $Date$
   *
   * @author Paul Smith &lt;psmith@apache.org&gt;
        *
        */
  private class LoggerNameTreeCellRenderer extends DefaultTreeCellRenderer
  {
    //~ Constructors ==========================================================

    //    private JPanel panel = new JPanel();
    private LoggerNameTreeCellRenderer()
    {
      super();

      //      panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
      //      panel.add(this);
      setLeafIcon(null);
      setOpaque(false);
    }

    //~ Methods ===============================================================

    /* (non-Javadoc)
     * @see javax.swing.tree.TreeCellRenderer#getTreeCellRendererComponent(javax.swing.JTree, java.lang.Object, boolean, boolean, boolean, int, boolean)
     */
    /**
     * DOCUMENT ME!
     *
     * @param tree DOCUMENT ME!
     * @param value DOCUMENT ME!
     * @param sel DOCUMENT ME!
     * @param expanded DOCUMENT ME!
     * @param leaf DOCUMENT ME!
     * @param row DOCUMENT ME!
     * @param focus DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public Component getTreeCellRendererComponent(
      JTree tree, Object value, boolean sel, boolean expanded, boolean leaf,
      int row, boolean focus)
    {
      JLabel component =
        (JLabel) super.getTreeCellRendererComponent(
          tree, value, sel, expanded, leaf, row, focus);

      Font originalFont = new Font(component.getFont().getName(), component.getFont().getStyle(), component.getFont().getSize());

      int style = Font.PLAIN;

      if (sel && focusOnLoggerButton.isSelected())
      {
        style = style | Font.BOLD;
      }

      String logger =
        getLoggerName(
          new TreePath(((DefaultMutableTreeNode) value).getPath()));

      if (hiddenSet.contains(logger))
      {
        //        component.setEnabled(false);
        //        component.setIcon(leaf?null:getDefaultOpenIcon());
        style = style | Font.ITALIC;

        //        logger.debug("TreeRenderer: '" + logger + "' is in hiddenSet, italicizing");
      }
      else
      {
        //          logger.debug("TreeRenderer: '" + logger + "' is NOT in hiddenSet, leaving plain");
        //        component.setEnabled(true);
      }

      if (originalFont != null)
      {
        Font font2 = originalFont.deriveFont(style);

        if (font2 != null)
        {
          component.setFont(font2);
        }
      }

      return component;
    }
  }

  private class LoggerTreePopupMenu extends JPopupMenu
  {
    //~ Instance fields =======================================================

    JCheckBoxMenuItem focusOnCheck = new JCheckBoxMenuItem();
    JCheckBoxMenuItem hideCheck = new JCheckBoxMenuItem();

    //~ Constructors ==========================================================

    private LoggerTreePopupMenu()
    {
      initMenu();
    }

    //~ Methods ===============================================================

    /* (non-Javadoc)
     * @see javax.swing.JPopupMenu#show(java.awt.Component, int, int)
     */
    /**
     * DOCUMENT ME!
     *
     * @param invoker DOCUMENT ME!
     * @param x DOCUMENT ME!
     * @param y DOCUMENT ME!
     */
    public void show(Component invoker, int x, int y)
    {
      DefaultMutableTreeNode node =
        (DefaultMutableTreeNode) logTree.getLastSelectedPathComponent();

      if (node == null)
      {
        return;
      }

      super.show(invoker, x, y);
    }

    /**
     * DOCUMENT ME!
    */
    private void initMenu()
    {
      focusOnCheck.setAction(focusOnAction);
      hideCheck.setAction(hideAction);
      add(expandAction);
      add(collapseAction);
      addSeparator();
      add(focusOnCheck);
      add(hideCheck);
      addSeparator();
      add(setRefineFocusAction);
      add(updateRefineFocusAction);
      add(clearRefineFocusAction);
      addSeparator();
      add(findAction);
      add(updateFindAction);
      add(clearFindNextAction);

      addSeparator();
      add(defineColorRuleForLoggerAction);
      addSeparator();

      add(hideSubLoggersAction);
      add(clearIgnoreListAction);
    }
  }

  private final class MouseFocusOnListener extends MouseAdapter
  {
    //~ Methods ===============================================================

    /* (non-Javadoc)
     * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
     */
    /**
     * DOCUMENT ME!
     *
     * @param e DOCUMENT ME!
     */
    public void mouseClicked(MouseEvent e)
    {
      if (
        (e.getClickCount() > 1)
          && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
          && ((e.getModifiers() & InputEvent.SHIFT_MASK) > 0))
      {
        ignoreLoggerAtPoint(e.getPoint());
        e.consume();
        fireChangeEvent();
      }
      else if (
        (e.getClickCount() > 1)
          && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0))
      {
        focusAnLoggerAtPoint(e.getPoint());
        e.consume();
        fireChangeEvent();
      }
    }

    /**
     * DOCUMENT ME!
     *
     * @param point
     */
    private void focusAnLoggerAtPoint(Point point)
    {
      String logger = getLoggerAtPoint(point);

      if (logger != null)
      {
        toggleFocusOnState();
      }
    }

    /**
     * DOCUMENT ME!
     *
     * @param point
     * @return
     */
    private String getLoggerAtPoint(Point point)
    {
      TreePath path = logTree.getPathForLocation(point.x, point.y);

      if (path != null)
      {
        return getLoggerName(path);
      }

      return null;
    }

    /**
     * DOCUMENT ME!
     *
     * @param point
     */
    private void ignoreLoggerAtPoint(Point point)
    {
      String logger = getLoggerAtPoint(point);

      if (logger != null)
      {
        toggleHiddenLogger(logger);
        fireChangeEvent();
      }
    }
  }

  private final class MouseKeyIconListener extends MouseMotionAdapter
    implements MouseMotionListener
  {
    //~ Instance fields =======================================================

    Cursor focusOnCursor =
      Toolkit.getDefaultToolkit().createCustomCursor(
        ChainsawIcons.FOCUS_ON_ICON.getImage(), new Point(10, 10), "");
    Cursor ignoreCursor =
      Toolkit.getDefaultToolkit().createCustomCursor(
        ChainsawIcons.IGNORE_ICON.getImage(), new Point(10, 10), "");

    //~ Methods ===============================================================

    /* (non-Javadoc)
     * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
     */
    /**
     * DOCUMENT ME!
     *
     * @param e DOCUMENT ME!
     */
    public void mouseMoved(MouseEvent e)
    {
      //      logger.debug(e.toString());
      if (
        ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
          && ((e.getModifiers() & InputEvent.SHIFT_MASK) > 0))
      {
        logTree.setCursor(ignoreCursor);
      }
      else if ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
      {
        logTree.setCursor(focusOnCursor);
      }
      else
      {
        logTree.setCursor(Cursor.getDefaultCursor());
      }
    }
  }

  class VisibilityRuleDelegate extends AbstractRule {
    	public boolean evaluate(LoggingEvent e, Map matches)
        {
          String currentlySelectedLoggerName = getCurrentlySelectedLoggerName();
          boolean hiddenLogger = e.getLoggerName() != null && isHiddenLogger(e.getLoggerName());
          boolean hiddenExpression = (ignoreExpressionRule != null && ignoreExpressionRule.evaluate(e, null));
          boolean alwaysDisplayExpression = (alwaysDisplayExpressionRule != null && alwaysDisplayExpressionRule.evaluate(e, null));
          boolean hidden = (!alwaysDisplayExpression) && (hiddenLogger || hiddenExpression);
          if (currentlySelectedLoggerName == null) {
          	//if there is no selected logger, pass if not hidden
          	return !hidden;
          }
          boolean result = (e.getLoggerName() != null) && !hidden;

          if (result && isFocusOnSelected())
          {
            result = (e.getLoggerName() != null && (e.getLoggerName().startsWith(currentlySelectedLoggerName+".") || e.getLoggerName().endsWith(currentlySelectedLoggerName)));
          }

          return result;
        }

        public void firePropertyChange(String propertyName, Object oldVal, Object newVal)
        {
            super.firePropertyChange(propertyName, oldVal, newVal);
        }
    }

}
