long outOfSpec = lastHbTime - lastHbDue;
long outOfSpec = lastHbDue - lastHbTime;
  private void prepareHealthReports() {    long timeUntilNextAlarm = Long.MAX_VALUE; // milliseconds until next call to prepareHealthReports    Iterator iter = heartbeatRequestSub.getCollection().iterator();    while (iter.hasNext()) {      HeartbeatRequest req = (HeartbeatRequest)iter.next();      int status = req.getStatus();      if (status == HeartbeatRequest.ACCEPTED) {        // Is it time yet to send a health report for this request?        // first, calculate when last heartbeat should have arrived        long start = req.getTimeReceived().getTime(); //baseline for heartbeats for this request        long now = System.currentTimeMillis();        long hbFreq = req.getHbFrequency();        long lastHbDue = start + ((now - start)/hbFreq)*hbFreq;        // now calculate when to send report         float percentOutOfSpec = req.getPercentOutOfSpec();        long reportDue = lastHbDue + (long)(hbFreq * (percentOutOfSpec / 100));        if (reportDue > now){ // report isn't due yet, so just set next wakeup time          long timeUntilReportDue = reportDue - now;              if (timeUntilNextAlarm > timeUntilReportDue) timeUntilNextAlarm = timeUntilReportDue;       } else { // now is the time to send the report, if needed          // first, set next wakeup time          long nextReportDue = reportDue + hbFreq;          long timeUntilNextReportDue = nextReportDue - now;            if (timeUntilNextAlarm > timeUntilNextReportDue) timeUntilNextAlarm = timeUntilNextReportDue;          // now check to see how late the heartbeats are          Iterator targets = req.getTargets().iterator();          Vector entries = null;          while (targets.hasNext()) {            MessageAddress target = (MessageAddress)targets.next();            Date lastHbDate = (Date)hbTable.get(target);            long lastHbTime = lastHbDate.getTime();            long outOfSpec = lastHbTime - lastHbDue;            float thisPercentOutOfSpec =  ((float)outOfSpec / (float)hbFreq) * 100.0f;            // send report if requester wants report whether in or out of spec            // or if the heartbeat is enough out of spec            if ( req.getOnlyOutOfSpec() == false ||                   thisPercentOutOfSpec > percentOutOfSpec ) {              if (entries == null) entries = new Vector();              entries.add(new HeartbeatEntry(target, lastHbDate, thisPercentOutOfSpec));            }          }          // if no entries, don't send report          if ((entries != null) && (entries.size() > 0)) {            HeartbeatEntry[] entryArray = (HeartbeatEntry[])entries.toArray(new HeartbeatEntry[entries.size()]);            HeartbeatHealthReport report = new HeartbeatHealthReport(entryArray);            bb.publishAdd(report);            System.out.println("\nHeartbeatRequesterPlugin.prepareHealthReports:" +                               " published new HeartbeatHealthReport = " + report);          }           }          }    }     if (timeUntilNextAlarm != Long.MAX_VALUE) {      nextAlarm = new SendHealthReportsAlarm(timeUntilNextAlarm);      alarmService.addRealTimeAlarm(nextAlarm);    }  }