public boolean process(FSMState state) {
    AspImpl causeAsp = (AspImpl) this.fsm.getAttribute(AsImpl.ATTRIBUTE_ASP);

    try {
      FSM aspLocalFSM = causeAsp.getLocalFSM();
      aspLocalFSM.signal(TransitionState.OTHER_ALTERNATE_ASP_ACTIVE);
    } catch (UnknownTransitionException e) {
      logger.error(e.getMessage(), e);
    }
    return true;
  }
  private void handleAspInactiveAck(AspImpl aspImpl, ASPInactiveAck aspInactiveAck) {
    FSM aspLocalFSM = aspImpl.getLocalFSM();
    if (aspLocalFSM == null) {
      logger.error(
          String.format(
              "Received ASPINACTIVE_ACK=%s for ASP=%s. But local FSM is null.",
              aspInactiveAck, this.aspFactoryImpl.getName()));
      return;
    }

    AsImpl asImpl = (AsImpl) aspImpl.getAs();

    try {
      aspLocalFSM.signal(TransitionState.ASP_INACTIVE_ACK);

      if (this.aspFactoryImpl.getFunctionality() == Functionality.IPSP) {
        // If its IPSP, we know NTFY will not be received,
        // so transition AS FSM here
        FSM asPeerFSM = asImpl.getPeerFSM();

        if (asPeerFSM == null) {
          logger.error(
              String.format(
                  "Received ASPINACTIVE_ACK=%s for ASP=%s. But Peer FSM of AS=%s is null.",
                  aspInactiveAck, this.aspFactoryImpl.getName(), asImpl));
          return;
        }

        if (asImpl.getTrafficModeType().getMode() == TrafficModeType.Loadshare) {
          // If it is loadshare and if there is atleast one other ASP
          // who ACTIVE, dont transition AS to INACTIVE

          for (Asp asp : asImpl.applicationServerProcesses) {

            AspImpl remAspImpl = (AspImpl) asp;

            FSM aspPeerFSM = remAspImpl.getPeerFSM();
            AspState aspState = AspState.getState(aspPeerFSM.getState().getName());

            if (aspState == AspState.ACTIVE) {
              return;
            }
          }
        }

        // TODO : Check if other ASP are INACTIVE, if yes ACTIVATE them
        asPeerFSM.setAttribute(AsImpl.ATTRIBUTE_ASP, aspImpl);
        asPeerFSM.signal(TransitionState.AS_STATE_CHANGE_PENDING);
      }
    } catch (UnknownTransitionException e) {
      logger.error(e.getMessage(), e);
    }
  }
  private void handleAspActiveAck(
      AspImpl aspImpl, ASPActiveAck aspActiveAck, TrafficModeType trMode) {
    AsImpl asImpl = (AsImpl) aspImpl.getAs();

    if (trMode == null) {
      trMode = aspImpl.getAs().getDefaultTrafficModeType();
    }

    asImpl.setTrafficModeType(trMode);

    FSM aspLocalFSM = aspImpl.getLocalFSM();
    if (aspLocalFSM == null) {
      logger.error(
          String.format(
              "Received ASPACTIVE_ACK=%s for ASP=%s. But local FSM is null.",
              aspActiveAck, this.aspFactoryImpl.getName()));
      return;
    }

    try {
      aspLocalFSM.signal(TransitionState.ASP_ACTIVE_ACK);

      if (aspFactoryImpl.getFunctionality() == Functionality.IPSP) {
        // If its IPSP, we know NTFY will not be received,
        // so transition AS FSM here
        FSM asPeerFSM = asImpl.getPeerFSM();

        if (asPeerFSM == null) {
          logger.error(
              String.format(
                  "Received ASPACTIVE_ACK=%s for ASP=%s. But Peer FSM of AS=%s is null.",
                  aspActiveAck, this.aspFactoryImpl.getName(), asImpl));
          return;
        }

        asPeerFSM.setAttribute(AsImpl.ATTRIBUTE_ASP, aspImpl);
        asPeerFSM.signal(TransitionState.AS_STATE_CHANGE_ACTIVE);
      }
    } catch (UnknownTransitionException e) {
      logger.error(e.getMessage(), e);
    }
  }
  private Notify createNotify(AspImpl remAsp, int type, int info) {
    Notify msg =
        (Notify)
            this.asImpl
                .getMessageFactory()
                .createMessage(MessageClass.MANAGEMENT, MessageType.NOTIFY);

    Status status = this.asImpl.getParameterFactory().createStatus(type, info);
    msg.setStatus(status);

    if (remAsp.getASPIdentifier() != null) {
      msg.setASPIdentifier(remAsp.getASPIdentifier());
    }

    if (this.asImpl.getRoutingContext() != null) {
      msg.setRoutingContext(this.asImpl.getRoutingContext());
    }

    return msg;
  }
  private void handleAspInactive(AspImpl aspImpl, ASPInactive aspInactive) {
    AsImpl appServer = (AsImpl) aspImpl.getAs();

    FSM aspPeerFSM = aspImpl.getPeerFSM();
    if (aspPeerFSM == null) {
      logger.error(
          String.format(
              "Received ASPINACTIVE=%s for ASP=%s. But peer FSM for ASP is null.",
              aspInactive, this.aspFactoryImpl.getName()));
      return;
    }

    FSM asLocalFSM = appServer.getLocalFSM();
    if (asLocalFSM == null) {
      logger.error(
          String.format(
              "Received ASPINACTIVE=%s for ASP=%s. But local FSM for AS is null.",
              aspInactive, this.aspFactoryImpl.getName()));
      return;
    }

    ASPInactiveAck aspInactAck =
        (ASPInactiveAck)
            this.aspFactoryImpl.messageFactory.createMessage(
                MessageClass.ASP_TRAFFIC_MAINTENANCE, MessageType.ASP_INACTIVE_ACK);
    aspInactAck.setRoutingContext(appServer.getRoutingContext());

    this.aspFactoryImpl.write(aspInactAck);

    try {
      aspPeerFSM.setAttribute(FSM.ATTRIBUTE_MESSAGE, aspInactive);
      aspPeerFSM.signal(TransitionState.ASP_INACTIVE);

      // Signal AS to transition
      asLocalFSM.setAttribute(AsImpl.ATTRIBUTE_ASP, aspImpl);
      asLocalFSM.signal(TransitionState.ASP_INACTIVE);

    } catch (UnknownTransitionException e) {
      logger.error(e.getMessage(), e);
    }
  }
  public boolean process(FSMState state) {
    try {
      AspImpl remAsp = (AspImpl) this.fsm.getAttribute(AsImpl.ATTRIBUTE_ASP);

      if (this.asImpl.getTrafficModeType().getMode() == TrafficModeType.Broadcast) {
        // We don't support this
        return false;
      }

      if (this.asImpl.getTrafficModeType().getMode() == TrafficModeType.Loadshare) {
        this.lbCount = 0;

        for (FastList.Node<Asp> n = this.asImpl.appServerProcs.head(),
                end = this.asImpl.appServerProcs.tail();
            (n = n.getNext()) != end; ) {
          AspImpl remAspImpl = (AspImpl) n.getValue();

          FSM aspPeerFSM = remAspImpl.getPeerFSM();
          AspState aspState = AspState.getState(aspPeerFSM.getState().getName());

          if (aspState == AspState.ACTIVE) {
            this.lbCount++;
          }
        } // for

        if (this.lbCount >= this.asImpl.getMinAspActiveForLb()) {
          // we still have more ASP's ACTIVE for lb. Don't change
          // state
          return false;
        }

        // We are below minAspActiveForLb required for LB
        if (this.lbCount > 0) {
          // But In any case if we have at least one ASP that can take
          // care of traffic, don't change state but send the "Ins.
          // ASPs" to INACTIVE ASP's

          if (asImpl.getFunctionality() != Functionality.IPSP) {
            // In any case send Notify only for ASP or SGW

            for (FastList.Node<Asp> n = this.asImpl.appServerProcs.head(),
                    end = this.asImpl.appServerProcs.tail();
                (n = n.getNext()) != end; ) {
              remAsp = (AspImpl) n.getValue();

              FSM aspPeerFSM = remAsp.getPeerFSM();
              AspState aspState = AspState.getState(aspPeerFSM.getState().getName());

              if (aspState == AspState.INACTIVE) {
                Notify notify =
                    this.createNotify(
                        remAsp, Status.STATUS_Other, Status.INFO_Insufficient_ASP_Resources_Active);
                remAsp.getAspFactory().write(notify);
              }
            }
          }

          return false;
        }
      } // If Loadshare

      // We have reached here means AS is transitioning to be PENDING.
      // Send new AS STATUS to all INACTIVE APS's

      if (asImpl.getFunctionality() != Functionality.IPSP) {
        // Send Notify only for ASP or SGW

        for (FastList.Node<Asp> n = this.asImpl.appServerProcs.head(),
                end = this.asImpl.appServerProcs.tail();
            (n = n.getNext()) != end; ) {
          remAsp = (AspImpl) n.getValue();

          FSM aspPeerFSM = remAsp.getPeerFSM();
          AspState aspState = AspState.getState(aspPeerFSM.getState().getName());

          if (aspState == AspState.INACTIVE) {
            Notify notify =
                this.createNotify(remAsp, Status.STATUS_AS_State_Change, Status.INFO_AS_PENDING);
            remAsp.getAspFactory().write(notify);
          }
        }
      }
    } catch (Exception e) {
      logger.error(
          String.format("Error while translating Rem AS to PENDING. %s", this.fsm.toString()), e);
    }
    return true;
  }
  private void handleAspActive(AspImpl aspImpl, ASPActive aspActive) {
    AsImpl appServer = (AsImpl) aspImpl.getAs();

    TrafficModeType trfModType = aspActive.getTrafficModeType();

    if (appServer.getTrafficModeType() != null) {
      // AppServer has Traffic Mode Type defined check if it
      // matches with sent ASP ACTIVE Message
      if (trfModType != null && appServer.getTrafficModeType().getMode() != trfModType.getMode()) {

        // Traffic Mode Type mismatch. Send Error.
        // TODO should send error or drop message?
        ErrorCode errorCodeObj =
            this.aspFactoryImpl.parameterFactory.createErrorCode(
                ErrorCode.Unsupported_Traffic_Mode_Type);
        this.sendError(appServer.getRoutingContext(), errorCodeObj);
        return;
      }

      // message doesn't have Traffic Mode Type
    } else {

      // AppServer Traffic Mode Type is optionally configured via
      // management config. If not select the first available in
      // AspUp message

      if (trfModType == null) {
        // Asp UP didn't specify the Traffic Mode either. use
        // default which is loadshare
        appServer.setDefaultTrafficModeType();
      } else {
        // Set the Traffic Mode Type passed in ASP ACTIVE
        appServer.setTrafficModeType(trfModType);
      }
    }

    FSM aspPeerFSM = aspImpl.getPeerFSM();
    if (aspPeerFSM == null) {
      logger.error(
          String.format(
              "Received ASPACTIVE=%s for ASP=%s. But peer FSM for ASP is null.",
              aspActive, this.aspFactoryImpl.getName()));
      return;
    }

    FSM asLocalFSM = appServer.getLocalFSM();
    if (asLocalFSM == null) {
      logger.error(
          String.format(
              "Received ASPACTIVE=%s for ASP=%s. But local FSM for AS is null.",
              aspActive, this.aspFactoryImpl.getName()));
      return;
    }

    ASPActiveAck aspActAck =
        (ASPActiveAck)
            this.aspFactoryImpl.messageFactory.createMessage(
                MessageClass.ASP_TRAFFIC_MAINTENANCE, MessageType.ASP_ACTIVE_ACK);
    aspActAck.setTrafficModeType(appServer.getTrafficModeType());
    aspActAck.setRoutingContext(appServer.getRoutingContext());

    this.aspFactoryImpl.write(aspActAck);

    try {
      aspPeerFSM.setAttribute(FSM.ATTRIBUTE_MESSAGE, aspActive);
      aspPeerFSM.signal(TransitionState.ASP_ACTIVE);

      // Signal AS to transition
      asLocalFSM.setAttribute(AsImpl.ATTRIBUTE_ASP, aspImpl);
      asLocalFSM.signal(TransitionState.ASP_ACTIVE);

    } catch (UnknownTransitionException e) {
      logger.error(e.getMessage(), e);
    }
  }