/**
   * Register an Agent with the server. This method calls out to verify it can talk to the agent,
   * and then adds it to the database. With all the connection info used to make further
   * connections.
   */
  private RegisterAgent_result cmdRegisterAgent(LatherContext ctx, RegisterAgent_args args)
      throws LatherRemoteException {
    try {
      checkUserCanManageAgent(ctx, args.getUser(), args.getPword(), "register");
    } catch (PermissionException exc) {
      return new RegisterAgent_result("Permission denied");
    }
    Collection<Integer> ids = new ArrayList<Integer>();

    RegisterAgent_result result = registerAgent(args, ids);

    /**
     * Reschedule all metrics on a platform when it is started for the first time. This allows the
     * schedule to be updated immediately on either agent updates, or if the user removes the agent
     * data directory.
     */
    if (!ids.isEmpty()) {
      try {
        List<ResourceRefreshZevent> zevents = new ArrayList<ResourceRefreshZevent>();
        ResourceRefreshZevent zevent;
        AuthzSubject overlord = authzSubjectManager.getOverlordPojo();
        for (Integer id : ids) {

          Platform platform = platformManager.findPlatformById(id);

          zevent = new ResourceRefreshZevent(overlord, platform.getEntityId());
          zevents.add(zevent);

          Collection<Server> servers = platform.getServers();
          for (Server server : servers) {

            zevent = new ResourceRefreshZevent(overlord, server.getEntityId());
            zevents.add(zevent);

            Collection<Service> services = server.getServices();
            for (Service service : services) {

              zevent = new ResourceRefreshZevent(overlord, service.getEntityId());
              zevents.add(zevent);
            }
          }
        }

        zeventManager.enqueueEventsAfterCommit(zevents);

      } catch (Exception e) {
        // Not fatal, the metrics will eventually be rescheduled...
        log.error("Unable to refresh agent schedule", e);
      }
    }
    return result;
  }