docs: public JTree getTreeSite() {
  		if (treeSite == null) {
  			treeSite = new JTree(new DefaultTreeModel(new DefaultMutableTreeNode()));
  			treeSite.setShowsRootHandles(true);
  			treeSite.setName("treeSite");
  			treeSite.setToggleClickCount(1);
  
  			// Force macOS L&F to query the row height from SiteMapTreeCellRenderer to hide the filtered nodes.
  			// Other L&Fs hide the filtered nodes by default.
  			LookAndFeel laf = UIManager.getLookAndFeel();
  			if (laf != null && Constant.isMacOsX()
  					&& UIManager.getSystemLookAndFeelClassName().equals(laf.getClass().getName())) {
  				treeSite.setRowHeight(0);
  			}
  
  			treeSite.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() { 
  
  				@Override
  				public void valueChanged(javax.swing.event.TreeSelectionEvent e) {    
  
  				    SiteNode node = (SiteNode) treeSite.getLastSelectedPathComponent();
  				    if (node == null) {
  				        return;
  				    }
  				    if (!node.isRoot()) {
  				    	HttpMessage msg = null;
                          try {
                              msg = node.getHistoryReference().getHttpMessage();
                          } catch (Exception e1) {
                          	// ZAP: Log exceptions
                          	log.warn(e1.getMessage(), e1);
                              return;
                              
                          }
  
                          getView().displayMessage(msg);
  
  			        	// ZAP: Call SiteMapListenners
  			            for (SiteMapListener listener : listeners) {
  			            	listener.nodeSelected(node);
  			            }
  				    } else {
  				    	// ZAP: clear the views when the root is selected
  				        getView().displayMessage(null);
  				    }
  	
  				}
  			});
  	        treeSite.setComponentPopupMenu(new SitesCustomPopupMenu());
  
  			// ZAP: Add custom tree cell renderer.
  	        DefaultTreeCellRenderer renderer = new SiteMapTreeCellRenderer(listeners);
  			treeSite.setCellRenderer(renderer);
  
  			String deleteSiteNode = "zap.delete.sitenode";
  			treeSite.getInputMap().put(getView().getDefaultDeleteKeyStroke(), deleteSiteNode);
  			treeSite.getActionMap().put(deleteSiteNode, new AbstractAction() {
  
  				private static final long serialVersionUID = 1L;
  
  				@Override
  				public void actionPerformed(ActionEvent e) {
  					ExtensionHistory extHistory = Control.getSingleton().getExtensionLoader().getExtension(
  							ExtensionHistory.class);
  					if (extHistory == null || treeSite.getSelectionCount() == 0) {
  						return;
  					}
  
  					int result = View.getSingleton().showConfirmDialog(Constant.messages.getString("sites.purge.warning"));
  					if (result != JOptionPane.YES_OPTION) {
  						return;
  					}
  
  					SiteMap siteMap = Model.getSingleton().getSession().getSiteTree();
  					for (TreePath path : treeSite.getSelectionPaths()) {
  						extHistory.purge(siteMap, (SiteNode) path.getLastPathComponent());
  					}
  				}
  			});
  		}
  		return treeSite;
  	}