private BitcoinLossProtectedWalletTransactionRecord generateBitcoinTransaction(
      final Transaction<CryptoTransaction> transaction, final TransactionType transactionType)
      throws
          com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.incoming_extra_actor.developer
              .bitdubai.version_1.exceptions.CantGenerateTransactionException {

    try {
      CryptoTransaction cryptoTransaction = transaction.getInformation();

      CryptoAddressBookRecord cryptoAddressBookRecord =
          cryptoAddressBookManager.getCryptoAddressBookRecordByCryptoAddress(
              cryptoTransaction.getAddressTo());

      long timestamp = transaction.getTimestamp();
      com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.incoming_extra_actor.developer
              .bitdubai.version_1.util.LossProtectedTransactionWrapper
          bitcoinWalletTransactionRecord =
              new com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.incoming_extra_actor
                  .developer.bitdubai.version_1.util.LossProtectedTransactionWrapper();

      bitcoinWalletTransactionRecord.setIdTransaction(transaction.getTransactionID());
      bitcoinWalletTransactionRecord.setTransactionHash(cryptoTransaction.getTransactionHash());
      bitcoinWalletTransactionRecord.setAddressFrom(cryptoTransaction.getAddressFrom());
      bitcoinWalletTransactionRecord.setAddressTo(cryptoTransaction.getAddressTo());
      bitcoinWalletTransactionRecord.setAmount(cryptoTransaction.getCryptoAmount());
      bitcoinWalletTransactionRecord.setTimestamp(timestamp);
      bitcoinWalletTransactionRecord.setMemo("No information");

      bitcoinWalletTransactionRecord.setActorFromPublicKey(
          cryptoAddressBookRecord.getDeliveredByActorPublicKey());
      bitcoinWalletTransactionRecord.setActorFromType(
          cryptoAddressBookRecord.getDeliveredByActorType());
      bitcoinWalletTransactionRecord.setActorToPublicKey(
          cryptoAddressBookRecord.getDeliveredToActorPublicKey());
      bitcoinWalletTransactionRecord.setActorToType(
          cryptoAddressBookRecord.getDeliveredToActorType());
      bitcoinWalletTransactionRecord.setBlockchainNetworkType(
          cryptoTransaction.getBlockchainNetworkType());
      return bitcoinWalletTransactionRecord;

    } catch (CantGetCryptoAddressBookRecordException e) {
      throw new com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.incoming_extra_actor
          .developer.bitdubai.version_1.exceptions.CantGenerateTransactionException(
          "I couldn't get crypto address book record", e, "", "");
    } catch (CryptoAddressBookRecordNotFoundException e) {
      throw new com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.incoming_extra_actor
          .developer.bitdubai.version_1.exceptions.CantGenerateTransactionException(
          "I couldn't find the crypto address book record", e, "", "");
    }
  }
 @Override
 public void executeTransaction(Transaction<CryptoTransaction> transaction)
     throws CantRegisterCreditException, CantRegisterDebitException,
         com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.incoming_extra_actor.developer
             .bitdubai.version_1.exceptions.UnexpectedTransactionException {
   try {
     switch (transaction.getInformation().getCryptoStatus()) {
       case ON_CRYPTO_NETWORK:
         processOnCryptoNetworkTransaction(transaction);
         break;
       case ON_BLOCKCHAIN:
         processOnBlockChainTransaction(transaction);
         break;
         // todo ezequiel, cambie de Reversed a REVERSED_ON_CRYPTO_NETWORK
       case REVERSED_ON_CRYPTO_NETWORK:
         processReversedOnCryptoNetworkTransaction(transaction);
         break;
       case REVERSED_ON_BLOCKCHAIN:
         processReversedOnBlockchainTransaction(transaction);
         break;
       case IRREVERSIBLE:
         // define what to do here.
         break;
       default:
         throw new com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.incoming_extra_actor
             .developer.bitdubai.version_1.exceptions.UnexpectedTransactionException(
             "El crypto status no es esperado",
             null,
             "El cryptoStatus es: " + transaction.getInformation().getCryptoStatus().getCode(),
             "");
     }
   } catch (CantRegisterCreditException
       | CantRegisterDebitException
       | com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.incoming_extra_actor.developer
               .bitdubai.version_1.exceptions.UnexpectedTransactionException
           e) {
     throw e;
   } catch (Exception e) {
     throw new com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.incoming_extra_actor
         .developer.bitdubai.version_1.exceptions.UnexpectedTransactionException(
         "An Unexpected Exception Happened", FermatException.wrapException(e), "", "");
   }
 }
    private void processEvent(IncomingCryptoRegistry.EventWrapper eventWrapper) {
      System.out.println("TTF - INCOMING CRYPTO MONITOR: NEW EVENT READ");

      // We have here new pending transactions, we will check the source and ask for the right
      // TransactionSender

      TransactionProtocolManager<CryptoTransaction> source = null;
      try {
        source =
            this.sourceAdministrator.getSourceAdministrator(
                EventSource.getByCode(eventWrapper.eventSource));
      } catch (InvalidParameterException e) {
        errorManager.reportUnexpectedPluginException(
            Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
            UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
            e);
        return;
      } catch (CantIdentifyEventSourceException e) {
        errorManager.reportUnexpectedPluginException(
            Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
            UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
            e);
        return;
      }

      System.out.println("TTF - INCOMING CRYPTO MONITOR: Source Identified");

      // Now we ask for the pending transactions
      List<Transaction<CryptoTransaction>> transactionList = null;

      try {
        transactionList = source.getPendingTransactions(Specialist.CRYPTO_ROUTER_SPECIALIST);
      } catch (CantDeliverPendingTransactionsException e) {
        System.out.println(
            "TTF - INCOMING CRYPTO MONITOR: cryptoVault raised CantDeliverPendingTransactionsException");
        errorManager.reportUnexpectedPluginException(
            Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
            UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
            e);
        // if somethig wrong happenned we try in the next round
        return;
      }

      // Now we save the list in the registry
      if (transactionList != null) {
        this.registry.acknowledgeTransactions(transactionList);
        System.out.println(
            "TTF - INCOMING CRYPTO MONITOR: "
                + transactionList.size()
                + " TRANSACTION(S) ACKNOWLEDGE");

      } else {
        // if sombething failed we try in next round
        // errorManager.reportUnexpectedPluginException(Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION, UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN, );
        return;
      }

      // Now we take all the transactions in state (ACKNOWLEDGE,TO_BE_NOTIFIED)
      // Remember that this list can be more extensive than the one we saved, this is
      // because the system could have shut down in this step of the protocol making old
      // transactions to be stored but not precessed.
      List<Transaction<CryptoTransaction>> acknowledgedTransactions = null;
      try {
        acknowledgedTransactions = this.registry.getAcknowledgedTransactions();
      } catch (InvalidParameterException e) {
        this.errorManager.reportUnexpectedPluginException(
            Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
            UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
            e);
        return;
      }

      // An finally, for each transaction we confirm it and then register responsibility.
      for (Transaction<CryptoTransaction> transaction : acknowledgedTransactions) {
        try {
          source.confirmReception(transaction.getTransactionID());
          System.out.println("TTF - INCOMING CRYPTO MONITOR: RESPONSIBILITY ACQUIRED");
          this.registry.acquireResponsibility(transaction);
        } catch (CantConfirmTransactionException e) {
          // TODO: Consultar si esto hace lo que pienso, si falla no registra en base de datos
          //       la transacción
          // We will inform the exception and try again in the next round
          errorManager.reportUnexpectedPluginException(
              Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
              UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
              e);
        }
      }
      // After finishing all the steps we mark the event as seen.
      try {
        this.registry.disableEvent(eventWrapper.eventId);
        System.out.println("TTF - INCOMING CRYPTO MONITR: EVENT DISABLED");

      } catch (Exception e) { // There are two exceptions and we react in the same way to both
        // We will inform the exception and try again in the next round
        errorManager.reportUnexpectedPluginException(
            Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
            UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
            e);
      }
    }
    private void processEvent(EventWrapper eventWrapper) {
      try {
        TransactionProtocolManager<FermatCryptoTransaction> source =
            this.sourceAdministrator.getSourceAdministrator(
                EventSource.getByCode(eventWrapper.getEventSource()));
        List<Transaction<FermatCryptoTransaction>> transactionList =
            source.getPendingTransactions(Specialist.INTRA_USER_SPECIALIST);

        System.out.println(
            "TTF - INTRA USER METADATA MONITOR: "
                + transactionList.size()
                + " TRANSACTION(s) DETECTED");

        this.registry.acknowledgeFermatCryptoTransactions(transactionList);

        System.out.println(
            "TTF - INTRA USER METADATA MONITOR: "
                + transactionList.size()
                + " TRANSACTION(s) ACKNOWLEDGED");

        // Now we take all the transactions in state (ACKNOWLEDGE,TO_BE_NOTIFIED)
        // Remember that this list can be more extensive than the one we saved, this is
        // because the system could have shut down in this step of the protocol making old
        // transactions to be stored but not precessed.
        List<Transaction<FermatCryptoTransaction>> acknowledgedTransactions =
            this.registry.getAcknowledgedFermatCryptoTransactions();

        for (Transaction<FermatCryptoTransaction> transaction : acknowledgedTransactions) {
          try {
            source.confirmReception(transaction.getTransactionID());
            System.out.println(
                "TTF - INTRA USER MONITOR METADATA: TRANSACTION RESPONSIBILITY ACQUIRED");
            registry.acquireFermatCryptoTransactionResponsibility(transaction);

            // notified Transmission NS that transaction Seen By Vault
            //
            // cryptoTransmissionNetworkServiceManager.informTransactionSeenByVault(transaction.getTransactionID());

          } catch (CantConfirmTransactionException
              | com.bitdubai.fermat_ccp_plugin.layer.crypto_transaction.incoming_intra_user
                      .developer.bitdubai.version_1.exceptions
                      .IncomingIntraUserCantAcquireResponsibilityException
                  exception) {
            // TODO: Consultar si esto hace lo que pienso, si falla no registra en base de datos
            //       la transacción
            // We will inform the exception and try again in the next round
            errorManager.reportUnexpectedPluginException(
                Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
                UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
                exception);
          }
          //  catch(CantSetToSeenByCryptoVaultException e){
          // errorManager.reportUnexpectedPluginException(Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION, UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN, e);

          // }
        }

        registry.disableEvent(eventWrapper.getEventId());
        System.out.println("TTF - INTRA USER METADATA MONITOR: EVENT DISABLED");
      } catch (Exception e) {
        errorManager.reportUnexpectedPluginException(
            Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
            UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
            e);
      }
    }
    private void checkNetworkLayerEvents()
        throws CantConfirmTransactionException, CantExecuteQueryException,
            UnexpectedResultReturnedFromDatabaseException,
            CantCheckAssetUserRedemptionProgressException,
            CantGetDigitalAssetFromLocalStorageException, CantSendAssetBitcoinsToUserException,
            CantGetCryptoTransactionException, CantDeliverDigitalAssetToAssetWalletException,
            CantDistributeDigitalAssetsException, CantDeliverPendingTransactionsException,
            RecordsNotFoundException, CantBroadcastTransactionException,
            CantCreateDigitalAssetFileException, CantLoadWalletException {
      List<Transaction<DigitalAssetMetadataTransaction>> pendingEventsList =
          assetTransmissionManager.getPendingTransactions(Specialist.ASSET_ISSUER_SPECIALIST);
      if (!userRedemptionDao.getPendingNetworkLayerEvents().isEmpty()) {
        for (Transaction<DigitalAssetMetadataTransaction> transaction : pendingEventsList) {
          if (transaction.getInformation().getReceiverType()
                  == PlatformComponentType.ACTOR_ASSET_USER
              && transaction.getInformation().getSenderType()
                  == PlatformComponentType.ACTOR_ASSET_REDEEM_POINT) {
            DigitalAssetMetadataTransaction digitalAssetMetadataTransaction =
                transaction.getInformation();
            System.out.println(
                "ASSET USER REDEMPTION Digital Asset Metadata Transaction: "
                    + digitalAssetMetadataTransaction);
            DigitalAssetMetadataTransactionType digitalAssetMetadataTransactionType =
                digitalAssetMetadataTransaction.getType();
            System.out.println(
                "ASSET USER REDEMPTION Digital Asset Metadata Transaction Type: "
                    + digitalAssetMetadataTransactionType);
            String userId = digitalAssetMetadataTransaction.getSenderId();
            System.out.println("ASSET USER REDEMPTION User Id: " + userId);
            String genesisTransaction = digitalAssetMetadataTransaction.getGenesisTransaction();
            System.out.println("ASSET USER REDEMPTION Genesis Transaction: " + genesisTransaction);
            if (!userRedemptionDao.isGenesisTransactionRegistered(genesisTransaction)) {
              System.out.println("ASSET USET REDEMPTION THIS IS NOT FOR ME!!");
              break;
            }
            DistributionStatus distributionStatus =
                digitalAssetMetadataTransaction.getDistributionStatus();
            userRedemptionDao.updateDistributionStatusByGenesisTransaction(
                distributionStatus, genesisTransaction);
            assetTransmissionManager.confirmReception(transaction.getTransactionID());
          }
        }
        userRedemptionDao.updateEventStatus(
            userRedemptionDao.getPendingNetworkLayerEvents().get(0));
      }

      List<String> assetAcceptedGenesisTransactionList =
          userRedemptionDao.getGenesisTransactionByAssetAcceptedStatus();
      for (String assetAcceptedGenesisTransaction : assetAcceptedGenesisTransactionList) {
        String actorUserCryptoAddress =
            userRedemptionDao.getActorRedeemPointCryptoAddressByGenesisTransaction(
                assetAcceptedGenesisTransaction);
        System.out.println(
            "ASSET USER REDEMPTION actorUserCryptoAddress: " + actorUserCryptoAddress);
        // For now, I set the cryptoAddress for Bitcoins
        CryptoAddress cryptoAddressTo =
            new CryptoAddress(actorUserCryptoAddress, CryptoCurrency.BITCOIN);
        System.out.println("ASSET USER REDEMPTION cryptoAddressTo: " + cryptoAddressTo);
        updateDistributionStatus(
            DistributionStatus.SENDING_CRYPTO, assetAcceptedGenesisTransaction);
        DeliverRecord record = userRedemptionDao.getLastDelivering(assetAcceptedGenesisTransaction);
        switch (record.getState()) {
          case DELIVERING:
            DigitalAssetMetadata metadata =
                digitalAssetUserRedemptionVault.getDigitalAssetMetadataFromWallet(
                    assetAcceptedGenesisTransaction, record.getNetworkType());
            userRedemptionDao.sendingBitcoins(
                assetAcceptedGenesisTransaction, metadata.getLastTransactionHash());
            userRedemptionDao.updateDigitalAssetCryptoStatusByGenesisTransaction(
                assetAcceptedGenesisTransaction, CryptoStatus.PENDING_SUBMIT);
            sendCryptoAmountToRemoteActor(metadata);
            break;
          case DELIVERING_CANCELLED:
            userRedemptionDao.updateDistributionStatusByGenesisTransaction(
                DistributionStatus.SENDING_CRYPTO_FAILED, assetAcceptedGenesisTransaction);
            break;
          default:
            System.out.println("This transaction has already been updated.");
            break;
        }
      }

      // TODO CHANGE THIS!!!!!!!!!!!!!
      List<String> assetRejectedByContractGenesisTransactionList =
          userRedemptionDao.getGenesisTransactionByAssetRejectedByContractStatus();
      for (String assetRejectedGenesisTransaction : assetRejectedByContractGenesisTransactionList) {
        DigitalAssetMetadata digitalAssetMetadata =
            digitalAssetUserRedemptionVault
                .getUserWallet(BlockchainNetworkType.getDefaultBlockchainNetworkType())
                .getDigitalAssetMetadata(assetRejectedGenesisTransaction);
        String internalId =
            userRedemptionDao.getTransactionIdByGenesisTransaction(assetRejectedGenesisTransaction);
        List<CryptoTransaction> genesisTransactionList =
            bitcoinNetworkManager.getCryptoTransactions(
                digitalAssetMetadata.getLastTransactionHash());
        if (genesisTransactionList == null || genesisTransactionList.isEmpty()) {
          throw new CantCheckAssetUserRedemptionProgressException(
              "Cannot get the CryptoTransaction from Crypto Network for "
                  + assetRejectedGenesisTransaction);
        }
        System.out.println("ASSET REJECTED BY CONTRACT!! : " + digitalAssetMetadata);
        String userPublicKey =
            userRedemptionDao.getActorUserPublicKeyByGenesisTransaction(
                assetRejectedGenesisTransaction);
        digitalAssetUserRedemptionVault.setDigitalAssetMetadataAssetIssuerWalletTransaction(
            genesisTransactionList.get(0),
            digitalAssetMetadata,
            AssetBalanceType.AVAILABLE,
            TransactionType.CREDIT,
            DAPTransactionType.DISTRIBUTION,
            userPublicKey);
      }

      List<String> assetRejectedByHashGenesisTransactionList =
          userRedemptionDao.getGenesisTransactionByAssetRejectedByHashStatus();
      for (String assetRejectedGenesisTransaction : assetRejectedByHashGenesisTransactionList) {
        DigitalAssetMetadata digitalAssetMetadata =
            digitalAssetUserRedemptionVault
                .getUserWallet(BlockchainNetworkType.getDefaultBlockchainNetworkType())
                .getDigitalAssetMetadata(assetRejectedGenesisTransaction);
        String internalId =
            userRedemptionDao.getTransactionIdByGenesisTransaction(assetRejectedGenesisTransaction);
        List<CryptoTransaction> genesisTransactionList =
            bitcoinNetworkManager.getCryptoTransactions(
                digitalAssetMetadata.getLastTransactionHash());
        if (genesisTransactionList == null || genesisTransactionList.isEmpty()) {
          throw new CantCheckAssetUserRedemptionProgressException(
              "Cannot get the CryptoTransaction from Crypto Network for "
                  + assetRejectedGenesisTransaction);
        }
        System.out.println("ASSET REJECTED BY HASH!! : " + digitalAssetMetadata);
        String userPublicKey =
            userRedemptionDao.getActorUserPublicKeyByGenesisTransaction(
                assetRejectedGenesisTransaction);
        digitalAssetUserRedemptionVault.setDigitalAssetMetadataAssetIssuerWalletTransaction(
            genesisTransactionList.get(0),
            digitalAssetMetadata,
            AssetBalanceType.AVAILABLE,
            TransactionType.CREDIT,
            DAPTransactionType.DISTRIBUTION,
            userPublicKey);
      }
    }
    private void checkPendingEvent(String eventId)
        throws UnexpectedResultReturnedFromDatabaseException {
      try {
        String eventTypeCode = openContractBusinessTransactionDao.getEventType(eventId);
        String contractHash;
        String negotiationId;
        String negotiationIdFromDatabase;
        ContractType contractType;
        BusinessTransactionMetadata businessTransactionMetadata;
        ContractTransactionStatus contractTransactionStatus;
        if (eventTypeCode.equals(EventType.INCOMING_BUSINESS_TRANSACTION_CONTRACT_HASH.getCode())) {
          // Check if contract is created:
          List<Transaction<BusinessTransactionMetadata>> pendingTransactionList =
              transactionTransmissionManager.getPendingTransactions(Specialist.UNKNOWN_SPECIALIST);
          for (Transaction<BusinessTransactionMetadata> record : pendingTransactionList) {
            businessTransactionMetadata = record.getInformation();
            contractHash = businessTransactionMetadata.getContractHash();
            if (openContractBusinessTransactionDao.isContractHashExists(contractHash)) {
              negotiationId = businessTransactionMetadata.getNegotiationId();
              negotiationIdFromDatabase = businessTransactionMetadata.getNegotiationId();
              if (negotiationId.equals(negotiationIdFromDatabase)) {
                contractTransactionStatus = ContractTransactionStatus.PENDING_CONFIRMATION;
              } else {
                contractTransactionStatus = ContractTransactionStatus.HASH_REJECTED;
              }
              openContractBusinessTransactionDao.updateContractTransactionStatus(
                  contractHash, contractTransactionStatus);
              openContractBusinessTransactionDao.updateEventStatus(
                  contractHash, EventStatus.NOTIFIED);
              transactionTransmissionManager.confirmReception(record.getTransactionID());
            }
          }
        }

        if (eventTypeCode.equals(
            EventType.INCOMING_CONFIRM_BUSINESS_TRANSACTION_CONTRACT.getCode())) {
          // Check if contract hash was sent.
          List<Transaction<BusinessTransactionMetadata>> pendingTransactionList =
              transactionTransmissionManager.getPendingTransactions(Specialist.UNKNOWN_SPECIALIST);
          for (Transaction<BusinessTransactionMetadata> record : pendingTransactionList) {
            businessTransactionMetadata = record.getInformation();
            contractHash = businessTransactionMetadata.getContractHash();
            if (openContractBusinessTransactionDao.isContractHashSentConfirmation(contractHash)) {
              openContractBusinessTransactionDao.updateContractTransactionStatus(
                  contractHash, ContractTransactionStatus.PENDING_RESPONSE);
              openContractBusinessTransactionDao.updateEventStatus(
                  contractHash, EventStatus.NOTIFIED);
              transactionTransmissionManager.confirmReception(record.getTransactionID());
            }
          }
        }

        if (eventTypeCode.equals(
            EventType.INCOMING_CONFIRM_BUSINESS_TRANSACTION_RESPONSE.getCode())) {
          // TODO: check if contract hash was sent.
          List<Transaction<BusinessTransactionMetadata>> pendingTransactionList =
              transactionTransmissionManager.getPendingTransactions(Specialist.UNKNOWN_SPECIALIST);
          for (Transaction<BusinessTransactionMetadata> record : pendingTransactionList) {
            businessTransactionMetadata = record.getInformation();
            contractHash = businessTransactionMetadata.getContractHash();
            if (openContractBusinessTransactionDao.isContractHashPendingResponse(contractHash)) {
              openContractBusinessTransactionDao.updateContractTransactionStatus(
                  contractHash, ContractTransactionStatus.CONTRACT_OPENED);
              openContractBusinessTransactionDao.updateEventStatus(
                  contractHash, EventStatus.NOTIFIED);
              contractType = openContractBusinessTransactionDao.getContractType(contractHash);
              switch (contractType) {
                case PURCHASE:
                  customerBrokerContractPurchaseManager
                      .updateStatusCustomerBrokerPurchaseContractStatus(
                          contractHash, ContractStatus.PENDING_PAYMENT);
              }
              transactionTransmissionManager.confirmReception(record.getTransactionID());
              raiseNewContractEvent();
            }
          }
        }
        // TODO: look a better way to deal with this exceptions
      } catch (CantDeliverPendingTransactionsException e) {
        e.printStackTrace();
      } catch (CantUpdateRecordException e) {
        e.printStackTrace();
      } catch (CantupdateCustomerBrokerContractPurchaseException e) {
        e.printStackTrace();
      } catch (CantConfirmTransactionException e) {
        e.printStackTrace();
      }
    }
    private void doTheMainTask() {

      /*
      El RelayAgent del IncomingCrypto analizará las transacciones con estado (RESPONSIBLE,NO_ACTION_REQUIRED).
      */
      List<Transaction<CryptoTransaction>> responsibleTransactionList = null;
      try {
        responsibleTransactionList = this.registry.getResponsibleNARTransactions();
      } catch (InvalidParameterException e) {
        this.errorManager.reportUnexpectedPluginException(
            Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
            UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
            e);
        return;
      }

      if (responsibleTransactionList.isEmpty()) return;

      System.out.println(
          "TTF - INCOMING CRYPTO RELAY: "
              + responsibleTransactionList.size()
              + " TRANSACTION(s) DETECTED");

      // Por cada una de ellas haría los siguientes pasos en el orden enunciado:
      // Deduciría a partir de la información de las mismas su Specialist y lo marcaría.
      // Pasaría la transacción al estado (RESPONSIBLE,TO_BE_NOTIFIED)
      for (Transaction<CryptoTransaction> transaction : responsibleTransactionList) {
        try {
          this.registry.setToNotify(
              transaction.getTransactionID(),
              this.specialistSelector.getSpecialist(transaction.getInformation()));
          System.out.println("TTF - INCOMING CRYPTO RELAY: SPECIALIST SETTED");
        } catch (CantSelectSpecialistException e) {
          // TODO: MANAGE EXCEPTION
          errorManager.reportUnexpectedPluginException(
              Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
              UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
              e);
        }
      }

      /*
      Cuando termina de recorrer la lista recorre ahora todas las que están con TransactonStatus RESPONSIBLE y ProtocolStatus TO_BE_NOTIFIED o SENDING_NOTIFIED. Registra todos los especialistas que vio en este recoorido (no intentar optimizar usando el recorrido anterior porque puede perderse si el sistema se cae) y realiza los siguente pasos en el orden enunciado:
      Por cada Specialist registrado en el recorrido anterior lanza el evento correspondiente (IncomingCryptTransactionsWaitingTransferenceSpecalistEvent)
      */
      EnumSet<Specialist> specialistSet;
      try {
        specialistSet = this.registry.getSpecialists();
      } catch (InvalidParameterException e) {
        errorManager.reportUnexpectedPluginException(
            Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
            UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
            e);
        System.out.println("TTF - INCOMING CRYPTO RELAY: GETSPECIALISTS FAILED");
        return;
      }

      System.out.println("TTF - INCOMING CRYPTO RELAY: SPECIALIST LIST CALCULATED");
      System.out.println(
          "TTF - INCOMING CRYPTO RELAY: " + specialistSet.size() + " SPECIALIST(s) TO CALL");

      try {
        this.eventsLauncher.sendEvents(specialistSet);
      } catch (SpecialistNotRegisteredException e) {
        this.errorManager.reportUnexpectedPluginException(
            Plugins.BITDUBAI_INCOMING_CRYPTO_TRANSACTION,
            UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
            e);
        return;
      }

      System.out.println("TTF - INCOMING CRYPTO RELAY: SPECIALIST(s) INFORMED");

      //  Pasa cada transacción con ProtocolStatus TO_BE_NOTIFIED a SENDING_NOTIFED.
      this.registry.setToSendingNotified();
      // System.out.println("TTF - INCOMING CRYPTO RELAY: TRANSACTION(s) SETTED TO NOTIFIED");

      // Aquí termina su tarea, será el receptor de las transacciones quien las confirmará
      // al recibirlas

    }