/** for client display: current state */
  public List<String> getObjectiveStatus() {
    lock.lock();
    try {
      List<String> l = new LinkedList<String>();

      Iterator<CollectionGoalStatus> iter = goalsStatus.iterator();
      while (iter.hasNext()) {
        CollectionGoalStatus status = iter.next();
        String itemName = status.getTemplateName();
        int numNeeded = status.targetCount;
        int cur = Math.min(status.currentCount, numNeeded);

        String objective = itemName + ": " + cur + "/" + numNeeded;
        l.add(objective);
      }
      return l;
    } finally {
      lock.unlock();
    }
  }
  public void handlePerception(PerceptionMessage perceptionMessage) {
    long targetOid = perceptionMessage.getTarget();
    List<PerceptionMessage.ObjectNote> gain = perceptionMessage.getGainObjects();
    List<PerceptionMessage.ObjectNote> lost = perceptionMessage.getLostObjects();

    if (Log.loggingDebug)
      Log.debug(
          "ProximityTracker.handlePerception: targetOid + "
              + targetOid
              + ", instanceOid="
              + instanceOid
              + " "
              + ((gain == null) ? 0 : gain.size())
              + " gain and "
              + ((lost == null) ? 0 : lost.size())
              + " lost");

    if (gain != null) for (PerceptionMessage.ObjectNote note : gain) maybeAddPerceivedObject(note);

    if (lost != null)
      for (PerceptionMessage.ObjectNote note : lost)
        maybeRemovePerceivedObject(note.getSubject(), note, targetOid);
  }