  DiameterMessage createS6aMessage(DiameterHeader diameterHeader, DiameterAvp[] avps, int _commandCode, ApplicationId appId) throws InternalException {
    boolean creatingRequest = diameterHeader == null;
    Message msg = null;
    if (!creatingRequest) {
      Message raw = createMessage(diameterHeader, avps, 0, appId);
      raw.setProxiable(diameterHeader.isProxiable());
      raw.setRequest(false);
      raw.getAvps().removeAvp(Avp.AUTH_APPLICATION_ID);
      msg = raw;
    }
    else {
      Message raw = createMessage(diameterHeader, avps, _commandCode, appId);
      raw.setProxiable(true);
      raw.setRequest(true);
      msg = raw;
    }
    if (msg.getAvps().getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID) == null) {
      try {
        DiameterAvp avpVendorId = this.baseAvpFactory.createAvp(Avp.VENDOR_ID, _S6A_VENDOR);
        DiameterAvp avpAuthApplicationId = this.baseAvpFactory.createAvp(Avp.AUTH_APPLICATION_ID, _S6A_AUTH_APP_ID);
        DiameterAvp vendorSpecific = this.baseAvpFactory.createAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, new DiameterAvp[]{avpVendorId, avpAuthApplicationId});
        msg.getAvps().addAvp(vendorSpecific.getCode(), vendorSpecific.byteArrayValue());
      }
      catch (NoSuchAvpException nsae) {
        logger.error("Failed to create AVPs", nsae);
      }
    }
    int commandCode = creatingRequest ? _commandCode : diameterHeader.getCommandCode();
    DiameterMessage diamMessage = null;
    switch (commandCode) {
      case UpdateLocationRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new UpdateLocationRequestImpl(msg) : new UpdateLocationAnswerImpl(msg);
        break;
      case AuthenticationInformationRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new AuthenticationInformationRequestImpl(msg) : new AuthenticationInformationAnswerImpl(msg);
        break;
      case CancelLocationRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new CancelLocationRequestImpl(msg) : new CancelLocationAnswerImpl(msg);
        break;
      case InsertSubscriberDataRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new InsertSubscriberDataRequestImpl(msg) : new InsertSubscriberDataAnswerImpl(msg);
        break;
      case DeleteSubscriberDataRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new DeleteSubscriberDataRequestImpl(msg) : new DeleteSubscriberDataAnswerImpl(msg);
        break;
      case PurgeUERequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new PurgeUERequestImpl(msg) : new PurgeUEAnswerImpl(msg);
        break;
      case ResetRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new ResetRequestImpl(msg) : new ResetAnswerImpl(msg);
        break;
      case NotifyRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new NotifyRequestImpl(msg) : new NotifyAnswerImpl(msg);
        break;
      default:
        diamMessage = new ExtensionDiameterMessageImpl(msg);
    }
    if (!diamMessage.hasSessionId() && session != null) {
      diamMessage.setSessionId(session.getSessionId());
    }
    return diamMessage;
  }

  DiameterMessage createS6aMessage(DiameterHeader diameterHeader, DiameterAvp[] avps, int _commandCode, ApplicationId appId) throws InternalException {
    boolean creatingRequest = diameterHeader == null;
    Message msg = null;
    if (!creatingRequest) {
      Message raw = createMessage(diameterHeader, avps, 0, appId);
      raw.setProxiable(diameterHeader.isProxiable());
      raw.setRequest(false);
      raw.setReTransmitted(false); 
      raw.getAvps().removeAvp(Avp.AUTH_APPLICATION_ID);
      msg = raw;
    }
    else {
      Message raw = createMessage(diameterHeader, avps, _commandCode, appId);
      raw.setProxiable(true);
      raw.setRequest(true);
      msg = raw;
    }
    if (msg.getAvps().getAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID) == null) {
      try {
        DiameterAvp avpVendorId = this.baseAvpFactory.createAvp(Avp.VENDOR_ID, _S6A_VENDOR);
        DiameterAvp avpAuthApplicationId = this.baseAvpFactory.createAvp(Avp.AUTH_APPLICATION_ID, _S6A_AUTH_APP_ID);
        DiameterAvp vendorSpecific = this.baseAvpFactory.createAvp(Avp.VENDOR_SPECIFIC_APPLICATION_ID, new DiameterAvp[]{avpVendorId, avpAuthApplicationId});
        msg.getAvps().addAvp(vendorSpecific.getCode(), vendorSpecific.byteArrayValue());
      }
      catch (NoSuchAvpException nsae) {
        logger.error("Failed to create AVPs", nsae);
      }
    }
    int commandCode = creatingRequest ? _commandCode : diameterHeader.getCommandCode();
    DiameterMessage diamMessage = null;
    switch (commandCode) {
      case UpdateLocationRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new UpdateLocationRequestImpl(msg) : new UpdateLocationAnswerImpl(msg);
        break;
      case AuthenticationInformationRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new AuthenticationInformationRequestImpl(msg) : new AuthenticationInformationAnswerImpl(msg);
        break;
      case CancelLocationRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new CancelLocationRequestImpl(msg) : new CancelLocationAnswerImpl(msg);
        break;
      case InsertSubscriberDataRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new InsertSubscriberDataRequestImpl(msg) : new InsertSubscriberDataAnswerImpl(msg);
        break;
      case DeleteSubscriberDataRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new DeleteSubscriberDataRequestImpl(msg) : new DeleteSubscriberDataAnswerImpl(msg);
        break;
      case PurgeUERequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new PurgeUERequestImpl(msg) : new PurgeUEAnswerImpl(msg);
        break;
      case ResetRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new ResetRequestImpl(msg) : new ResetAnswerImpl(msg);
        break;
      case NotifyRequest.COMMAND_CODE:
        diamMessage = creatingRequest ? new NotifyRequestImpl(msg) : new NotifyAnswerImpl(msg);
        break;
      default:
        diamMessage = new ExtensionDiameterMessageImpl(msg);
    }
    if (!diamMessage.hasSessionId() && session != null) {
      diamMessage.setSessionId(session.getSessionId());
    }
    return diamMessage;
  }
