@Override
  public boolean process(String type, String message, Object object) {
    Applications applications = (Applications) object;

    if (GroupInstanceTerminatingEvent.class.getName().equals(type)) {
      // Return if applications has not been initialized
      if (!applications.isInitialized()) return false;

      // Parse complete message and build event
      GroupInstanceTerminatingEvent event =
          (GroupInstanceTerminatingEvent)
              MessagingUtil.jsonToObject(message, GroupInstanceTerminatingEvent.class);

      ApplicationsUpdater.acquireWriteLockForApplication(event.getAppId());

      try {
        return doProcess(event, applications);

      } finally {
        ApplicationsUpdater.releaseWriteLockForApplication(event.getAppId());
      }

    } else {
      if (nextProcessor != null) {
        // ask the next processor to take care of the message.
        return nextProcessor.process(type, message, applications);
      } else {
        throw new RuntimeException(
            String.format(
                "Failed to process message using available message processors: [type] %s [body] %s",
                type, message));
      }
    }
  }
  private boolean doProcess(GroupInstanceTerminatingEvent event, Applications applications) {

    // Validate event against the existing applications
    Application application = applications.getApplication(event.getAppId());
    if (application == null) {
      if (log.isWarnEnabled()) {
        log.warn(String.format("Application does not exist: [service] %s", event.getAppId()));
      }
      return false;
    }
    Group group = application.getGroupRecursively(event.getGroupId());

    if (group == null) {
      if (log.isWarnEnabled()) {
        log.warn(
            String.format(
                "Group not exists in service: [AppId] %s [groupId] %s",
                event.getAppId(), event.getGroupId()));
        return false;
      }
    } else {
      // Apply changes to the applications
      GroupInstance context = group.getInstanceContexts(event.getInstanceId());
      if (context == null) {
        if (log.isWarnEnabled()) {
          log.warn(
              String.format(
                  "Group Instance not exists in Group: [AppId] %s [groupId] %s "
                      + "[instanceId] %s",
                  event.getAppId(), event.getGroupId(), event.getInstanceId()));
          return false;
        }
      }
      // Apply changes to the topology
      GroupStatus status = GroupStatus.Terminating;
      if (!context.isStateTransitionValid(status)) {
        log.error("Invalid State Transition from " + context.getStatus() + " to " + status);
        return false;
      }
      context.setStatus(status);
    }

    // Notify event listeners
    notifyEventListeners(event);
    return true;
  }