private void setUpMockitoRules() throws Exception {

    when(mockDatabase.getDatabaseFactory()).thenReturn(mockDatabaseFactory);
    when(mockDatabaseTable.getEmptyRecord()).thenReturn(mockDatabaseTableRecord);
    when(mockDatabase.getTable(
            AssetIssuingTransactionDatabaseConstants.DIGITAL_ASSET_TRANSACTION_TABLE_NAME))
        .thenReturn(mockDatabaseTable);
    when(mockDatabase.getTable(
            AssetIssuingTransactionDatabaseConstants
                .DIGITAL_ASSET_TRANSACTION_ASSET_ISSUING_TABLE_NAME))
        .thenReturn(mockDatabaseTable2);
    when(mockDatabaseTable2.getEmptyRecord()).thenReturn(mockDatabaseTableRecord);
    when(mockDatabaseTable2.getRecords()).thenReturn(records);
    when(pluginDatabaseSystem.openDatabase(
            pluginId, AssetIssuingTransactionDatabaseConstants.DIGITAL_ASSET_TRANSACTION_DATABASE))
        .thenReturn(mockDatabase);

    when(deviceUser.getPublicKey()).thenReturn("myPublicKey");
    when(deviceUserManager.getLoggedInDeviceUser()).thenReturn(deviceUser);

    when(actorAssetIssuerManager.getActorAssetIssuer()).thenReturn(actorAssetIssuer);

    when(eventManager.getNewListener(
            EventType.INCOMING_ASSET_ON_CRYPTO_NETWORK_WAITING_TRANSFERENCE_ASSET_ISSUER))
        .thenReturn(fermatEventListener1);
    when(eventManager.getNewListener(
            EventType.INCOMING_ASSET_ON_BLOCKCHAIN_WAITING_TRANSFERENCE_ASSET_ISSUER))
        .thenReturn(fermatEventListener2);
    when(eventManager.getNewListener(
            EventType.INCOMING_ASSET_REVERSED_ON_BLOCKCHAIN_WAITING_TRANSFERENCE_ASSET_ISSUER))
        .thenReturn(fermatEventListener3);
    when(eventManager.getNewListener(
            EventType.INCOMING_ASSET_REVERSED_ON_CRYPTO_NETWORK_WAITING_TRANSFERENCE_ASSET_ISSUER))
        .thenReturn(fermatEventListener4);

    when(pluginFileSystem.createTextFile(
            this.pluginId,
            "digital-asset-issuing/publicKey",
            "name.xml",
            FilePrivacy.PUBLIC,
            FileLifeSpan.PERMANENT))
        .thenReturn(pluginTextFile);
    when(bitcoinWalletManager.loadWallet(this.walletPublicKey)).thenReturn(bitcoinWalletWallet);
    when(bitcoinWalletWallet.getBalance(BalanceType.AVAILABLE)).thenReturn(bitcoinWalletBalance);
    when(bitcoinWalletBalance.getBalance()).thenReturn(bitcoinWalletAvailableBalance);
    when(assetVaultManager.getNewAssetVaultCryptoAddress(this.blockchainNetworkType))
        .thenReturn(cryptoAddress);
    //        doNothing().when(assetIssuingPluginRoot).issueAssets(digitalAsset, 1, walletPublicKey,
    // blockchainNetworkType);
  }
  private void doTheMainTask() {
    /*
     * TODO: The first thing to do is to ask the crypto vault
     *       the source address, transaction hash and then the
     *       timestamp of the event ON_CRYPTO_NETWORK
     */

    /* TODO: Reemplazar por el que se lee de la transacción
     *       Esto se va a poder hacer cuando nos pasen todos los parámetros
     *       necesarios.
     */
    List<
            com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.outgoing_extra_user.developer
                .bitdubai.version_1.util.TransactionWrapper>
        transactionList;

    // We first check for the new transactions to apply
    try {
      transactionList = dao.getNewTransactions();
    } catch (Exception e) {
      this.reportUnexpectedError(e);
      return;
    }

    /* For each transaction:
     1. We check that we can apply it
     2. We apply it in the bitcoin wallet available balance
    */

    long funds;
    for (com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.outgoing_extra_user.developer
            .bitdubai.version_1.util.TransactionWrapper
        transaction : transactionList) {

      try {
        BitcoinWalletWallet bitcoinWalletWallet =
            bitcoinWalletManager.loadWallet(transaction.getWalletPublicKey());
        funds = bitcoinWalletWallet.getBalance(BalanceType.AVAILABLE).getBalance();
        if (funds < transaction.getAmount()) {
          dao.cancelTransaction(transaction, "Insufficient founds.");
          // TODO: Lanzar un evento de fondos insuficientes
        } else {
          // If we have enough funds we debit them from the available balance
          bitcoinWalletWallet.getBalance(BalanceType.AVAILABLE).debit(transaction);
          // The we set that we register that we have executed the debit
          dao.setToPIA(transaction);
        }

      } catch (Exception e) {

        this.reportUnexpectedError(e);
      }
    }

    // Now we check for all the transactions that have been discounted from the available amount
    // but bot applied to vault
    try {
      transactionList = dao.getPersistedInAvailable();
    } catch (Exception e) {
      this.reportUnexpectedError(e);
      return;
    }

    for (com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.outgoing_extra_user.developer
            .bitdubai.version_1.util.TransactionWrapper
        transaction : transactionList) {
      // Now we apply it in the vault
      try {
        String hash =
            this.cryptoVaultManager.sendBitcoins(
                transaction.getWalletPublicKey(),
                transaction.getTransactionId(),
                transaction.getAddressTo(),
                transaction.getAmount());
        dao.setTransactionHash(transaction, hash);
        dao.setToSTCV(transaction);

      } catch (InsufficientCryptoFundsException e) {

        // TODO: THEN RAISE EVENT TO INFORM THE SITUATION

        try {
          dao.cancelTransaction(transaction, "Insufficient founds.");
        } catch (CantUpdateRecordException
            | InconsistentTableStateException
            | CantLoadTableToMemoryException e2) {
          reportUnexpectedError(e2);
          continue;
        } catch (Exception exception) {
          reportUnexpectedError(exception);
          continue;
        }
        // And we finally report the error
        Exception ez =
            new InconsistentFundsException(
                "Basic wallet balance and crypto vault funds are inconsistent", e, "", "");
        reportUnexpectedError(ez);

      } catch (InvalidSendToAddressException | CouldNotSendMoneyException e) {

        try {

          dao.cancelTransaction(transaction, "There was a problem and the money was not sent.");

        } catch (Exception exception) {
          reportUnexpectedError(exception);
          continue;
        }

        reportUnexpectedError(e);

      } catch (Exception exception) {

        reportUnexpectedError(exception);
      }
    }

    /*
     * Now we proceed to apply the transactions sent to the bitcoin network to the wallet book
     * balance. We need to check the state of the transaction in the crypto vault before
     * discounting it
     */
    try {
      transactionList = dao.getSentToCryptoVaultTransactions();

    } catch (Exception exception) {
      reportUnexpectedError(exception);
      return;
    }

    for (com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.outgoing_extra_user.developer
            .bitdubai.version_1.util.TransactionWrapper
        transaction : transactionList) {

      try {
        BitcoinWalletWallet bitcoinWalletWallet =
            bitcoinWalletManager.loadWallet(transaction.getWalletPublicKey());
        CryptoStatus cryptoStatus =
            this.bitcoinNetworkManager.getCryptoStatus(transaction.getTransactionId());
        com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.outgoing_extra_user.developer
            .bitdubai.version_1.util.TransactionHandler.handleTransaction(
            transaction,
            bitcoinNetworkManager,
            cryptoStatus,
            bitcoinWalletWallet,
            this.dao,
            this.errorManager);

      } catch (Exception exception) {
        reportUnexpectedError(exception);
      }
    }
  }