Grouper.Callback callback = new Grouper.Callback() { private DefaultMutableTreeNode currentGroupNode;  public void startGroup(Object member_) { BugInstance member = (BugInstance) member_; String groupName; if (sortOrder == BY_CLASS) groupName = member.getPrimaryClass().getClassName(); else if (sortOrder == BY_PACKAGE) groupName = member.getPrimaryClass().getPackageName(); else if (sortOrder == BY_CATEGORY) { String desc = member.toString(); groupName = desc.substring(0, desc.indexOf(':')); } else throw new IllegalStateException("Unknown sort order: " + sortOrder); BugInstanceGroup currentGroup = new BugInstanceGroup(sortOrder, groupName); currentGroupNode = new DefaultMutableTreeNode(currentGroup); bugTreeModel.insertNodeInto(currentGroupNode, bugRootNode, bugRootNode.getChildCount());  insertIntoGroup(member); }  public void addToGroup(Object member_) { BugInstance member = (BugInstance) member_; insertIntoGroup(member); }  private void insertIntoGroup(BugInstance member) { if (currentGroupNode == null) throw new IllegalStateException("Why?"); DefaultMutableTreeNode bugNode = new DefaultMutableTreeNode(member); bugTreeModel.insertNodeInto(bugNode, currentGroupNode, currentGroupNode.getChildCount());   Iterator j = member.annotationIterator(); while (j.hasNext()) { BugAnnotation annotation = (BugAnnotation) j.next(); DefaultMutableTreeNode annotationNode = new DefaultMutableTreeNode(annotation); bugTreeModel.insertNodeInto(annotationNode, bugNode,  bugNode.getChildCount()); }  } };  Grouper grouper = new Grouper(callback);
    private void populateAnalysisRunTreeModel(AnalysisRun analysisRun, String sortOrder) {	// Set busy cursor - this is potentially a time-consuming operation	Cursor orig = this.getCursor();	this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));		DefaultTreeModel bugTreeModel = analysisRun.getTreeModel();	DefaultMutableTreeNode bugRootNode = (DefaultMutableTreeNode) bugTreeModel.getRoot();		// Delete all children from root node	bugRootNode.removeAllChildren();		// Sort the instances	TreeSet sortedCollection = new TreeSet(getBugInstanceComparator(sortOrder));	sortedCollection.addAll(analysisRun.getBugInstances());		// Create an appropriate grouper object//	Grouper grouper = getGrouper(sortOrder);		// Add all instances as children of the root, in sorted order	Iterator i = sortedCollection.iterator();	while (i.hasNext()) {	    BugInstance bugInstance = (BugInstance) i.next();	    DefaultMutableTreeNode bugNode = new DefaultMutableTreeNode(bugInstance);	    bugTreeModel.insertNodeInto(bugNode, bugRootNode, bugRootNode.getChildCount());	    	    // Insert annotations	    Iterator j = bugInstance.annotationIterator();	    while (j.hasNext()) {		BugAnnotation annotation = (BugAnnotation) j.next();		DefaultMutableTreeNode annotationNode = new DefaultMutableTreeNode(annotation);		bugTreeModel.insertNodeInto(annotationNode, bugNode,  bugNode.getChildCount());	    }	}		// Sort order is up to date now	analysisRun.setSortOrder(sortOrder);		// Let the tree know it needs to update itself	bugTreeModel.nodeStructureChanged(bugRootNode);		// Now we're done	this.setCursor(orig);    }