@Override
    public Log[] supplyLogsForDrag() {
      ArrayList<Log> refs = new ArrayList<>();
      for (TreePath tp : display.logTree.getSelectionPaths()) {
        if (tp.getPathCount() == 3) {
          LogReference reference = (LogReference) tp.getLastPathComponent();
          refs.add(reference.get());
        }
      }

      return refs.toArray(new Log[0]);
    }
    @Override
    public void valueChanged(TreeSelectionEvent e) {
      if (!e.isAddedPath()) {
        // path unselected, ignore
        return;
      }

      TreePath[] selected = display.logTree.getSelectionPaths();
      switch (selected[0].getPathCount()) {
        case 0:
          Debug.error("null selection!");
          break;
        case 1:
          Debug.error("root selected!");
          break;
        case 2:
          {
            Group group = (Group) selected[0].getLastPathComponent();
            displayGroup(group);
            Events.GGroupSelected.generate(this, group);
          }
          return;
        case 3:
          {
            List<Log> all = new LinkedList<>();
            for (TreePath path : selected) {
              if (path.getPathCount() != 3) continue; // it isn't a Log selection

              LogReference ref = (LogReference) path.getLastPathComponent();
              all.add(ref.get());
            }

            Log first = all.remove(0);
            displayLog(first, all);
            Events.GLogSelected.generate(outerClassThis, first, all);
          }
          return;
        default:
          Debug.error(
              "selection count %d %s",
              selected[0].getPathCount(), selected[0].getLastPathComponent());
      }
    }