private MoteTracker createMoteTracker(Mote mote) {
    final Radio moteRadio = mote.getInterfaces().getRadio();
    if (moteRadio == null) {
      return null;
    }

    /* Radio observer */
    MoteTracker tracker = new MoteTracker(mote);
    tracker.update(null, null);
    return tracker;
  }
  private void removeMote(Mote mote) {
    /* Remove mote tracker(s) */
    MoteTracker[] trackers = moteTrackers.toArray(new MoteTracker[0]);
    for (MoteTracker t : trackers) {
      if (t.getMote() == mote) {
        t.dispose();
        moteTrackers.remove(t);
      }
    }

    setTitle("PowerTracker: " + moteTrackers.size() + " motes");
  }
  public String radioStatistics(boolean radioHW, boolean radioRXTX, boolean onlyAverage) {
    StringBuilder sb = new StringBuilder();

    /* Average */
    long radioOn = 0;
    long radioTx = 0;
    long radioRx = 0;
    long radioInterfered = 0;
    long duration = 0;
    for (MoteTracker mt : moteTrackers) {
      radioOn += mt.radioOn;
      radioTx += mt.radioTx;
      radioRx += mt.radioRx;
      radioInterfered += mt.radioInterfered;

      duration += mt.duration;
    }
    if (radioHW) {
      sb.append(
          String.format(
                  "AVG" + " ON " + (radioOn + " us ") + "%2.2f %%", 100.0 * radioOn / duration)
              + "\n");
    }
    if (radioRXTX) {
      sb.append(
          String.format(
                  "AVG" + " TX " + (radioTx + " us ") + "%2.2f %%", 100.0 * radioTx / duration)
              + "\n");
      sb.append(
          String.format(
                  "AVG" + " RX " + (radioRx + " us ") + "%2.2f %%", 100.0 * radioRx / duration)
              + "\n");
      sb.append(
          String.format(
                  "AVG" + " INT " + (radioInterfered + " us ") + "%2.2f %%",
                  100.0 * radioInterfered / duration)
              + "\n");
    }

    if (onlyAverage) {
      return sb.toString();
    }

    for (MoteTracker mt : moteTrackers) {
      sb.append(mt.toString(radioHW, radioRXTX));
    }
    return sb.toString();
  }
            public void actionPerformed(ActionEvent e) {
              /* Identify max radio on */
              double maxRadioOn = 0;
              int maxRadioOnIndex = -1;
              for (int i = 0; i < moteTrackers.size(); i++) {
                MoteTracker mt = moteTrackers.get(i);
                if (mt.getRadioOnRatio() > maxRadioOn) {
                  maxRadioOn = mt.getRadioOnRatio();
                  maxRadioOnIndex = i;
                }
              }
              if (maxRadioOnIndex >= 0) {
                tableMaxRadioOnIndex = maxRadioOnIndex;
              }

              table.repaint();
            }
  public void closePlugin() {
    /* Remove repaint timer */
    repaintTimer.stop();

    simulation.getEventCentral().removeMoteCountListener(moteCountListener);

    /* Remove mote trackers */
    for (Mote m : simulation.getMotes()) {
      removeMote(m);
    }
    if (!moteTrackers.isEmpty()) {
      logger.fatal("Mote observers not cleaned up correctly");
      for (MoteTracker t : moteTrackers.toArray(new MoteTracker[0])) {
        t.dispose();
      }
    }
  }