/*
 * 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 &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();

            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", 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();
      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 =
            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 &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);
        }
    }

}
