/**
   * If NF_HEADER_LOCATION_PROP exists in context use as the header to forward to Gateway. If
   * IS_ASYNCHRONOUS_PROP exists in context then use that value to call either processAsync or
   * processSync
   *
   * @param input MessageObject containing the value to be processed *
   * @param mpcontext The context
   * @return Optional NVPair containing a Destination name and a MessageObject, or null if none.
   * @exception ProcessingException Thrown if processing fails.
   * @exception MessageException Thrown if bad message.
   */
  public NVPair[] process(MessageProcessorContext ctx, MessageObject input)
      throws MessageException, ProcessingException {
    if (input == null) return null;

    try {
      serverName = getRequiredProperty(ctx, input, SERVER_NAME_PROP);
    } catch (MessageException me) {
      throw new ProcessingException(me.getMessage());
    }

    if (StringUtils.hasValue(headerLocation)) {
      try {
        header = getString(headerLocation, ctx, input);
      } catch (MessageException me) {
        throw new ProcessingException(me.getMessage());
      }
    }

    if (StringUtils.hasValue(isAsyncLocation)) {
      try {
        isAsync = StringUtils.getBoolean(getString(isAsyncLocation, ctx, input));
      } catch (FrameworkException fe) {
        throw new ProcessingException(
            "Value of " + IS_ASYNCHRONOUS_LOCATION_PROP + " is not TRUE/FALSE. " + fe.getMessage());
      }
    }

    // Fetch the alternate Orb Address, if one exists at the specified context location
    if (StringUtils.hasValue(orbAgentAddrLocation)) {
      try {
        if (exists(orbAgentAddrLocation, ctx, input, true)) {
          orbAgentAddr = getString(orbAgentAddrLocation, ctx, input);
          if (Debug.isLevelEnabled(Debug.MSG_STATUS))
            Debug.log(
                Debug.MSG_STATUS,
                "RequestHandlerClient:: alternate orb exists with orb agent address ["
                    + orbAgentAddr
                    + "]");
        }
      } catch (MessageException me) {
        throw new ProcessingException(me.getMessage());
      }
    }

    // Fetch the alternate Orb Port, if one exists at the specified context location
    if (StringUtils.hasValue(orbAgentPortLocation)) {
      try {
        if (exists(orbAgentPortLocation, ctx, input, true)) {
          orbAgentPort = getString(orbAgentPortLocation, ctx, input);
          if (Debug.isLevelEnabled(Debug.MSG_STATUS))
            Debug.log(
                Debug.MSG_STATUS,
                "RequestHandlerClient:: alternate orb exists with orb agent port ["
                    + orbAgentPort
                    + "]");
        }
      } catch (MessageException me) {
        throw new ProcessingException(me.getMessage());
      }
    }

    String msg = input.getString();

    try {
      try {
        return (formatNVPair(makeClientCall(serverName, false, header, msg)));
      } catch (Exception e) {
        // Any of the following exceptions indicate that the failure might be due to
        // a CORBA communications issue (stale object reference) that should be retried.
        if ((e instanceof org.omg.CORBA.OBJECT_NOT_EXIST)
            || (e instanceof org.omg.CORBA.TRANSIENT)
            || (e instanceof org.omg.CORBA.COMM_FAILURE)
            || (e instanceof org.omg.CORBA.INV_OBJREF)
            || (e instanceof org.omg.CORBA.UNKNOWN)) {
          Debug.warning(
              "Caught the following CORBA communication error, so retrying:\n"
                  + e.toString()
                  + "\n"
                  + Debug.getStackTrace(e));

          return (formatNVPair(makeClientCall(serverName, true, header, msg)));
        } else {
          // It's not a communication exception indicating that retry is recommended,
          // so just re-throw it.
          throw e;
        }
      }
    } catch (Exception e) {
      if (e instanceof InvalidDataException) {
        Debug.error(e.toString() + "\n" + Debug.getStackTrace(e));

        throw new MessageException(((InvalidDataException) e).errorMessage);
      } else {
        Debug.error(e.toString() + "\n" + Debug.getStackTrace(e));

        throw new ProcessingException(e.toString());
      }
    }
  }