class AesGcmStreamEncryptionService implements StreamEncryptionService {

  @Override
  public byte[] decrypt(final SharedSecret sharedSecret, final byte[] cipherMessage) {
    Objects.requireNonNull(sharedSecret);
    Objects.requireNonNull(cipherMessage);

    if (this.encryptionMode == EncryptionMode.ENCRYPT_NON_STANDARD) {
      try {
        return this.nonStandardModeDecrypt(sharedSecret, cipherMessage);
      } catch (EncryptionException e) {
        logger.warn(
            "Unable to decrypt payload in {} mode. Attempting {} mode as a fallback.",
            EncryptionMode.ENCRYPT_NON_STANDARD,
            EncryptionMode.ENCRYPT_STANDARD,
            e
        );
        return this.standardModeDecrypt(sharedSecret, cipherMessage);
      }
    } else {
      try {
        return this.standardModeDecrypt(sharedSecret, cipherMessage);
      } catch (EncryptionException e) {
        logger.warn(
            "Unable to decrypt payload in {} mode. Attempting {} mode as a fallback.",
            EncryptionMode.ENCRYPT_STANDARD,
            EncryptionMode.ENCRYPT_NON_STANDARD,
            e
        );
        return this.nonStandardModeDecrypt(sharedSecret, cipherMessage);
      }
    }
  }

  public  AesGcmStreamEncryptionService();
  public  AesGcmStreamEncryptionService(final EncryptionMode encryptionMode);

}