/*
 * 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.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
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.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
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 <psmith@apache.org>
 */
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();

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

    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(new Runnable() {

                public void run()
                {
                    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 (Iterator iter = hiddenSet.iterator();iter.hasNext();) {
      String hiddenLoggerEntry = iter.next().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", (Object) null, (Object) 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();
      StringBuffer buf = new StringBuffer();

      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 (int i = 0; i < paths.length; i++)
    {
      TreePath path = paths[i];
      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();

              String parentPathString = "";
              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 = parentPathString + ".";
                      }
                      parentPathString = parentPathString + path[i].toString();
                  }
                  if (!(parentPathString.equals(""))) {
                      parentPathString = parentPathString + ".";
                  }
              }
              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(new Runnable()
      {
        public void run()
        {
          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 (int i = 0; i < paths.length; i++)
    {
      TreePath path = paths[i];

      /**
       * 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(
          new Integer(
            ((DefaultMutableTreeNode) depthEnum.nextElement()).getDepth()));
      }

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

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

      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 =
      (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
    ChangeEvent e = null;

    for (int i = 0; i < listeners.length; i++)
    {
      if (e == null)
      {
        e = new ChangeEvent(this);
      }

      listeners[i].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(new TreeSelectionListener()
      {
        public void valueChanged(TreeSelectionEvent 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(new PropertyChangeListener()
      {
        public void propertyChange(PropertyChangeEvent evt)
        {
          popupMenu.focusOnCheck.setSelected(isFocusOnSelected());
          focusOnLoggerButton.setSelected(isFocusOnSelected());

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

    hideAction.addPropertyChangeListener(new PropertyChangeListener()
      {
        public void propertyChange(PropertyChangeEvent 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(new ChangeListener()
      {
        public void stateChanged(ChangeEvent evt)
        {
          visibilityRuleDelegate.firePropertyChange("rule", null, null);
          updateDisplay();
        }
      });

    visibilityRuleDelegate.addPropertyChangeListener(new PropertyChangeListener()
      {
        public void propertyChange(PropertyChangeEvent 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 (Iterator iter = sortedIgnoreList.iterator(); iter.hasNext();)
      {
        String string = (String) iter.next();
        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(new Runnable() {
            public void run() {
                setFocusOn(logger);
            }
        });
    }

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

  /**
   * DOCUMENT ME!
   *
   * @author $author$
   * @version $Revision$, $Date$
   *
   * @author Paul Smith <psmith@apache.org>
        *
        */
  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);
        }
    }

}
