public NegotiationTransmission getNotificationById(final UUID transactionId) {

    NegotiationTransmission negotiationTransmission = null;
    if (transactionId == null) return null;

    try {

      DatabaseTable cryptoPaymentRequestTable = getDatabaseTable();

      cryptoPaymentRequestTable.addUUIDFilter(
          NegotiationTransmissionNetworkServiceDatabaseConstants
              .OUTGOING_NOTIFICATION_TRANSACTION_ID_COLUMN_NAME,
          transactionId,
          DatabaseFilterType.EQUAL);

      cryptoPaymentRequestTable.loadToMemory();

      List<DatabaseTableRecord> records = cryptoPaymentRequestTable.getRecords();

      if (!records.isEmpty()) {
        negotiationTransmission = buildNegotiationTransmission(records.get(0));
      }

    } catch (CantLoadTableToMemoryException e) {

      e.printStackTrace();
    } catch (InvalidParameterException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }

    return negotiationTransmission;
  }
  /**
   * @param record with values from the table
   * @return FermatMessage setters the values from table
   */
  private FermatMessage constructFrom(DatabaseTableRecord record) {

    FermatMessageCommunication incomingTemplateNetworkServiceMessage =
        new FermatMessageCommunication();

    try {

      incomingTemplateNetworkServiceMessage.setId(
          UUID.fromString(
              record.getStringValue(
                  CommunicationNetworkServiceDatabaseConstants.INCOMING_MESSAGES_ID_COLUMN_NAME)));
      incomingTemplateNetworkServiceMessage.setSender(
          record.getStringValue(
              CommunicationNetworkServiceDatabaseConstants
                  .INCOMING_MESSAGES_SENDER_ID_COLUMN_NAME));
      incomingTemplateNetworkServiceMessage.setReceiver(
          record.getStringValue(
              CommunicationNetworkServiceDatabaseConstants
                  .INCOMING_MESSAGES_RECEIVER_ID_COLUMN_NAME));

      incomingTemplateNetworkServiceMessage.setContent(
          record.getStringValue(
              CommunicationNetworkServiceDatabaseConstants
                  .INCOMING_MESSAGES_TEXT_CONTENT_COLUMN_NAME));
      incomingTemplateNetworkServiceMessage.setFermatMessageContentType(
          (FermatMessageContentType.getByCode(
              record.getStringValue(
                  CommunicationNetworkServiceDatabaseConstants
                      .INCOMING_MESSAGES_TYPE_COLUMN_NAME))));
      incomingTemplateNetworkServiceMessage.setShippingTimestamp(
          new Timestamp(
              record.getLongValue(
                  CommunicationNetworkServiceDatabaseConstants
                      .INCOMING_MESSAGES_SHIPPING_TIMESTAMP_COLUMN_NAME)));
      incomingTemplateNetworkServiceMessage.setDeliveryTimestamp(
          new Timestamp(
              record.getLongValue(
                  CommunicationNetworkServiceDatabaseConstants
                      .INCOMING_MESSAGES_DELIVERY_TIMESTAMP_COLUMN_NAME)));

      incomingTemplateNetworkServiceMessage.setFermatMessagesStatus(
          FermatMessagesStatus.getByCode(
              record.getStringValue(
                  CommunicationNetworkServiceDatabaseConstants
                      .INCOMING_MESSAGES_STATUS_COLUMN_NAME)));

    } catch (InvalidParameterException e) {
      // TODO METODO CON RETURN NULL - OJO: solo INFORMATIVO de ayuda VISUAL para DEBUG - Eliminar
      // si molesta
      // this should not happen, but if it happens return null
      e.printStackTrace();
      return null;
    }

    return incomingTemplateNetworkServiceMessage;
  }
  /**
   * Creates a incoming or outgoing CryptoTransaction object from a database record
   *
   * @param transactionType
   * @param record
   * @return
   */
  private CryptoTransaction getCryptoTransactionFromRecord(
      TransactionTypes transactionType, DatabaseTableRecord record) {
    String addressFromColumnName,
        addressToColumnName,
        transactionHashColumnName,
        valueColumnName,
        cryptoStatusColumnName;
    if (transactionType == TransactionTypes.INCOMING) {
      transactionHashColumnName =
          BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_HASH_COLUMN_NAME;
      addressFromColumnName =
          BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_ADDRESS_FROM_COLUMN_NAME;
      addressToColumnName =
          BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_ADDRESS_TO_COLUMN_NAME;
      valueColumnName =
          BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_VALUE_COLUMN_NAME;
      cryptoStatusColumnName =
          BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_CRYPTO_STATUS_COLUMN_NAME;
    } else {
      transactionHashColumnName =
          BitcoinCryptoNetworkDatabaseConstants.OUTGOING_TRANSACTIONS_HASH_COLUMN_NAME;
      addressFromColumnName =
          BitcoinCryptoNetworkDatabaseConstants.OUTGOING_TRANSACTIONS_ADDRESS_FROM_COLUMN_NAME;
      addressToColumnName =
          BitcoinCryptoNetworkDatabaseConstants.OUTGOING_TRANSACTIONS_ADDRESS_TO_COLUMN_NAME;
      valueColumnName =
          BitcoinCryptoNetworkDatabaseConstants.OUTGOING_TRANSACTIONS_VALUE_COLUMN_NAME;
      cryptoStatusColumnName =
          BitcoinCryptoNetworkDatabaseConstants.OUTGOING_TRANSACTIONS_CRYPTO_STATUS_COLUMN_NAME;
    }

    CryptoTransaction cryptoTransaction = new CryptoTransaction();
    cryptoTransaction.setTransactionHash(record.getStringValue(transactionHashColumnName));
    cryptoTransaction.setCryptoCurrency(CryptoCurrency.BITCOIN);
    try {
      cryptoTransaction.setCryptoStatus(
          CryptoStatus.getByCode(record.getStringValue(cryptoStatusColumnName)));
    } catch (InvalidParameterException e) {
      e.printStackTrace();
    }
    cryptoTransaction.setCryptoAmount(record.getLongValue(valueColumnName));
    cryptoTransaction.setAddressFrom(
        new CryptoAddress(record.getStringValue(addressFromColumnName), CryptoCurrency.BITCOIN));
    cryptoTransaction.setAddressTo(
        new CryptoAddress(record.getStringValue(addressToColumnName), CryptoCurrency.BITCOIN));

    // todo define how to get the Op_Return value
    return cryptoTransaction;
  }
 @Override
 public void updateLanguage(WalletLanguage walletLanguage)
     throws CantUpdateLanguageException, LanguageNotFoundException {
   try {
     walletLanguageMiddlewareDao.updateLanguage(walletLanguage);
   } catch (CantUpdateLanguageException | LanguageNotFoundException e) {
     errorManager.reportUnexpectedPluginException(
         Plugins.BITDUBAI_WALLET_LANGUAGE_MIDDLEWARE,
         UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
         e);
     throw e;
   } catch (InvalidParameterException e) {
     // TODO METODO NO IMPLEMENTADO AUN - OJO: solo INFORMATIVO de ayuda VISUAL para DEBUG -
     // Eliminar si molesta
     e.printStackTrace();
   }
 }
  /**
   * Gets the crypto Status list that are in pending status from the specified table.
   *
   * @param transactionType
   * @return
   */
  public Set<CryptoStatus> getPendingCryptoStatus(TransactionTypes transactionType)
      throws CantExecuteDatabaseOperationException {
    DatabaseTable databaseTable;
    String cryptoStatusColumnName;
    Set<CryptoStatus> cryptoStatuses = new HashSet<>();

    /** Will set up filters and column names depending on the transaction type. */
    if (transactionType == TransactionTypes.OUTGOING) {
      databaseTable =
          database.getTable(BitcoinCryptoNetworkDatabaseConstants.OUTGOING_TRANSACTIONS_TABLE_NAME);
      databaseTable.setStringFilter(
          BitcoinCryptoNetworkDatabaseConstants.OUTGOING_TRANSACTIONS_PROTOCOL_STATUS_COLUMN_NAME,
          ProtocolStatus.TO_BE_NOTIFIED.getCode(),
          DatabaseFilterType.EQUAL);
      cryptoStatusColumnName =
          BitcoinCryptoNetworkDatabaseConstants.OUTGOING_TRANSACTIONS_CRYPTO_STATUS_COLUMN_NAME;
    } else {
      databaseTable =
          database.getTable(BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_TABLE_NAME);
      databaseTable.setStringFilter(
          BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_PROTOCOL_STATUS_COLUMN_NAME,
          ProtocolStatus.TO_BE_NOTIFIED.getCode(),
          DatabaseFilterType.EQUAL);
      cryptoStatusColumnName =
          BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_CRYPTO_STATUS_COLUMN_NAME;
    }

    try {
      databaseTable.loadToMemory();
    } catch (CantLoadTableToMemoryException e) {
      throwLoadToMemoryException(e, databaseTable.getTableName());
    }

    /** get all the CryptoStatus and remove duplicates as Im storing them in a set. */
    for (DatabaseTableRecord record : databaseTable.getRecords()) {
      try {
        CryptoStatus cryptoStatus =
            CryptoStatus.getByCode(record.getStringValue(cryptoStatusColumnName));
        cryptoStatuses.add(cryptoStatus);
      } catch (InvalidParameterException e) {
        e.printStackTrace();
      }
    }

    return cryptoStatuses;
  }
 @Override
 public WalletLanguage getLanguageById(UUID id)
     throws CantGetWalletLanguageException, LanguageNotFoundException {
   try {
     return walletLanguageMiddlewareDao.findLanguageById(id);
   } catch (CantGetWalletLanguageException | LanguageNotFoundException e) {
     errorManager.reportUnexpectedPluginException(
         Plugins.BITDUBAI_WALLET_LANGUAGE_MIDDLEWARE,
         UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
         e);
     throw e;
   } catch (InvalidParameterException e) {
     // TODO METODO NO IMPLEMENTADO AUN - OJO: solo INFORMATIVO de ayuda VISUAL para DEBUG -
     // Eliminar si molesta
     e.printStackTrace();
   }
   // TODO METODO CON RETURN NULL - OJO: solo INFORMATIVO de ayuda VISUAL para DEBUG - Eliminar si
   // molesta
   return null;
 }
  /**
   * Gets the incoming transaction data and forms the CryptoTransaction object
   *
   * @param txHash
   * @return
   * @throws CantExecuteDatabaseOperationException
   */
  public List<CryptoTransaction> getIncomingCryptoTransaction(String txHash)
      throws CantExecuteDatabaseOperationException {
    DatabaseTable databaseTable =
        database.getTable(BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_TABLE_NAME);
    databaseTable.setStringFilter(
        BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_HASH_COLUMN_NAME,
        txHash,
        DatabaseFilterType.EQUAL);

    try {
      databaseTable.loadToMemory();
    } catch (CantLoadTableToMemoryException e) {
      throwLoadToMemoryException(e, databaseTable.getTableName());
    }

    List<CryptoTransaction> cryptoTransactions = new ArrayList<>();
    for (DatabaseTableRecord record : databaseTable.getRecords()) {

      /** Gets all the values */
      CryptoAddress addressFrom = new CryptoAddress();
      addressFrom.setAddress(
          record.getStringValue(
              BitcoinCryptoNetworkDatabaseConstants
                  .INCOMING_TRANSACTIONS_ADDRESS_FROM_COLUMN_NAME));
      addressFrom.setCryptoCurrency(CryptoCurrency.BITCOIN);

      CryptoAddress addressTo = new CryptoAddress();
      addressFrom.setAddress(
          record.getStringValue(
              BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_ADDRESS_TO_COLUMN_NAME));
      addressFrom.setCryptoCurrency(CryptoCurrency.BITCOIN);

      long amount =
          record.getLongValue(
              BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_VALUE_COLUMN_NAME);

      CryptoStatus cryptoStatus = null;
      try {
        cryptoStatus =
            CryptoStatus.getByCode(
                record.getStringValue(
                    BitcoinCryptoNetworkDatabaseConstants
                        .INCOMING_TRANSACTIONS_CRYPTO_STATUS_COLUMN_NAME));
      } catch (InvalidParameterException e) {
        e.printStackTrace();
      }

      String op_Return =
          record.getStringValue(
              BitcoinCryptoNetworkDatabaseConstants.INCOMING_TRANSACTIONS_OP_RETURN_COLUMN_NAME);

      /** Forms the CryptoTransaction object */
      CryptoTransaction cryptoTransaction = new CryptoTransaction();
      cryptoTransaction.setTransactionHash(txHash);
      cryptoTransaction.setAddressTo(addressTo);
      cryptoTransaction.setAddressFrom(addressFrom);
      cryptoTransaction.setCryptoAmount(amount);
      cryptoTransaction.setCryptoCurrency(CryptoCurrency.BITCOIN);
      cryptoTransaction.setCryptoStatus(cryptoStatus);
      cryptoTransaction.setOp_Return(op_Return);

      /** adds it to the list */
      cryptoTransactions.add(cryptoTransaction);
    }

    return cryptoTransactions;
  }
    private void doTheMainTask()
        throws CantExecuteQueryException, CantCheckAssetUserRedemptionProgressException {

      try {
        checkDeliveringTime();
        checkNetworkLayerEvents();
        checkPendingTransactions();

      } catch (CantSendAssetBitcoinsToUserException exception) {
        throw new CantCheckAssetUserRedemptionProgressException(
            exception,
            "Exception in ASSET USER REDEMPTION monitor agent",
            "Cannot send crypto currency to asset user");
      } catch (UnexpectedResultReturnedFromDatabaseException exception) {
        throw new CantCheckAssetUserRedemptionProgressException(
            exception,
            "Exception in ASSET USER REDEMPTION monitor agent",
            "Unexpected result in database query");
      } catch (CantGetCryptoTransactionException exception) {
        throw new CantCheckAssetUserRedemptionProgressException(
            exception,
            "Exception in ASSET USER REDEMPTION monitor agent",
            "Cannot get genesis transaction from asset vault");
      } catch (CantDeliverPendingTransactionsException exception) {
        throw new CantCheckAssetUserRedemptionProgressException(
            exception,
            "Exception in ASSET USER REDEMPTION monitor agent",
            "Cannot deliver pending transactions");
      } catch (CantDistributeDigitalAssetsException
          | CantCreateDigitalAssetFileException exception) {
        throw new CantCheckAssetUserRedemptionProgressException(
            exception,
            "Exception in ASSET USER REDEMPTION monitor agent",
            "Cannot distribute digital asset");
      } catch (CantConfirmTransactionException exception) {
        throw new CantCheckAssetUserRedemptionProgressException(
            exception,
            "Exception in ASSET USER REDEMPTION monitor agent",
            "Cannot confirm transaction");
      } catch (CantGetDigitalAssetFromLocalStorageException exception) {
        throw new CantCheckAssetUserRedemptionProgressException(
            exception,
            "Exception in ASSET USER REDEMPTION monitor agent",
            "Cannot get DigitalAssetMetadata from local storage");
      } catch (CantDeliverDigitalAssetToAssetWalletException
          | CantGetAssetUserActorsException
          | CantGetBroadcastStatusException
          | CantAssetUserActorNotFoundException
          | CantBroadcastTransactionException
          | CantCancellBroadcastTransactionException
          | RecordsNotFoundException
          | CantGetTransactionCryptoStatusException
          | CantRegisterCreditException
          | CantExecuteDatabaseOperationException
          | CantGetAssetIssuerActorsException
          | CantLoadWalletException
          | CantGetTransactionsException
          | CantSendTransactionNewStatusNotificationException
          | CantRegisterDebitException exception) {
        throw new CantCheckAssetUserRedemptionProgressException(
            exception,
            "Exception in ASSET USER REDEMPTION monitor agent",
            "Cannot set Credit in asset issuer wallet");
      } catch (InvalidParameterException e) {
        e.printStackTrace();
      }
    }