/**
     * Overrides the TickerBehaviour, defining how to update the location on the df (registration to
     * DF has already been performed during agent setup). Three properties are defined for storing
     * latitude/longitude/altitude. Only latitude and longitude are used, though.
     */
    protected void onTick() {

      try {
        MsnAgent agent = (MsnAgent) myAgent;
        DFAgentDescription description = agent.getAgentDescription();

        ServiceDescription serviceDescription =
            (ServiceDescription) description.getAllServices().next();
        serviceDescription.clearAllProperties();

        // retrieve
        ContactLocation curMyLoc = ContactManager.getInstance().getMyContactLocation();
        if (!curMyLoc.equals(myContactLocation)) {

          Property p = new Property(PROPERTY_NAME_LOCATION_LAT, new Double(curMyLoc.getLatitude()));
          serviceDescription.addProperties(p);
          p = new Property(PROPERTY_NAME_LOCATION_LONG, new Double(curMyLoc.getLongitude()));
          serviceDescription.addProperties(p);
          p = new Property(PROPERTY_NAME_LOCATION_ALT, new Double(curMyLoc.getAltitude()));
          serviceDescription.addProperties(p);
          DFService.modify(myAgent, description);
          myContactLocation = curMyLoc;
        }

      } catch (FIPAException fe) {
        myLogger.log(Logger.SEVERE, "Error in updating DF", fe);
      } catch (Exception e) {
        myLogger.log(
            Logger.SEVERE,
            "***  Uncaught Exception for agent " + myAgent.getLocalName() + "  ***",
            e);
      }
    }
  private synchronized void registerAgent(DFAgentDescription dfad) throws Exception {

    log.info("Start wsigs's registration from agent: " + dfad.getName());

    // Loop all services of agent
    ServiceDescription sd;
    WSIGService wsigService;

    AID agentId = dfad.getName();
    Iterator it = dfad.getAllServices();
    while (it.hasNext()) {
      sd = (ServiceDescription) it.next();

      // Create wsdl & wsig service
      wsigService = createWSIGService(agentId, sd);

      // Register new service
      registerService(wsigService);
    }

    log.info("End wsigs's registration from agent: " + dfad.getName());
  }
    /**
     * Overrides SubscriptionInitiator.handleInform(), defining what to do each time the DF is
     * modified by a contact Basically it adds/removes/updates contacts from ContactList according
     * to what has happened to DF. It also fires events on the GUI any time a view refresh is
     * needed.
     *
     * @param inform the message from DF containing a list of changes
     */
    protected void handleInform(ACLMessage inform) {

      myLogger.log(
          Logger.FINE,
          "Thread " + Thread.currentThread().getId() + ": Notification received from DF");
      ContactManager.getInstance().resetModifications();

      try {

        DFAgentDescription[] results = DFService.decodeNotification(inform.getContent());

        if (results.length > 0) {

          for (int i = 0; i < results.length; ++i) {
            DFAgentDescription dfd = results[i];
            AID contactAID = dfd.getName();
            // Do something only if the notification deals with an agent different from the current
            // one
            if (!contactAID.equals(myAgent.getAID())) {

              myLogger.log(
                  Logger.INFO,
                  "Thread "
                      + Thread.currentThread().getId()
                      + ":df says that agent "
                      + myAgent.getAID().getLocalName()
                      + " updates or registers");
              Iterator serviceIter = dfd.getAllServices();

              // Registered or updated
              if (serviceIter.hasNext()) {
                ServiceDescription serviceDesc = (ServiceDescription) serviceIter.next();
                Iterator propertyIt = serviceDesc.getAllProperties();
                Location loc = Helper.extractLocation(propertyIt);
                String phoneNum = contactAID.getLocalName();
                ContactManager.getInstance().addOrUpdateOnlineContact(phoneNum, loc);
              } else {
                myLogger.log(
                    Logger.INFO,
                    "Thread "
                        + Thread.currentThread().getId()
                        + ":df says that agent "
                        + myAgent.getAID().getLocalName()
                        + " deregisters");
                String phoneNumber = contactAID.getLocalName();
                Contact c = ContactManager.getInstance().getContact(phoneNumber);
                ContactManager.getInstance().setContactOffline(phoneNumber);
                MsnEvent event =
                    MsnEventMgr.getInstance().createEvent(MsnEvent.CONTACT_DISCONNECT_EVENT);
                event.addParam(MsnEvent.CONTACT_DISCONNECT_PARAM_CONTACTNAME, c.getName());
                MsnEventMgr.getInstance().fireEvent(event);
              }

              MsnEvent event = MsnEventMgr.getInstance().createEvent(MsnEvent.VIEW_REFRESH_EVENT);
              ContactListChanges changes = ContactManager.getInstance().getModifications();
              Map<String, Contact> cMap = ContactManager.getInstance().getAllContacts();
              Map<String, ContactLocation> cLocMap =
                  ContactManager.getInstance().getAllContactLocations();

              myLogger.log(
                  Logger.FINE,
                  "Thread "
                      + Thread.currentThread().getId()
                      + ":Adding to VIEW_REFRESH_EVENT this list of changes: "
                      + changes.toString());
              event.addParam(MsnEvent.VIEW_REFRESH_PARAM_LISTOFCHANGES, changes);
              event.addParam(MsnEvent.VIEW_REFRESH_CONTACTSMAP, cMap);
              event.addParam(MsnEvent.VIEW_REFRESH_PARAM_LOCATIONMAP, cLocMap);
              MsnEventMgr.getInstance().fireEvent(event);
            }
          }
        }

      } catch (Exception e) {
        myLogger.log(Logger.WARNING, "See printstack for Exception.", e);
        e.printStackTrace();
      }
    }