private void processMetadata() {

    try {

      listRecorMessageToSend =
          outgoingMessageDao.findAll(
              CommunicationNetworkServiceDatabaseConstants.OUTGOING_MESSAGES_STATUS_COLUMN_NAME,
              FermatMessagesStatus.PENDING_TO_SEND.getCode());

      if (listRecorMessageToSend != null && !listRecorMessageToSend.isEmpty()) {

        for (FermatMessage fm : listRecorMessageToSend) {

          if (!poolConnectionsWaitingForResponse.containsKey(fm.getReceiver())) {

            /*
             * Create the sender basic profile
             */
            PlatformComponentProfile sender =
                wsCommunicationsCloudClientManager
                    .getCommunicationsCloudClientConnection()
                    .constructBasicPlatformComponentProfileFactory(
                        fm.getSender(),
                        NetworkServiceType.UNDEFINED,
                        PlatformComponentType.ACTOR_ASSET_REDEEM_POINT);

            /*
             * Create the receiver basic profile
             */
            PlatformComponentProfile receiver =
                wsCommunicationsCloudClientManager
                    .getCommunicationsCloudClientConnection()
                    .constructBasicPlatformComponentProfileFactory(
                        fm.getReceiver(),
                        NetworkServiceType.UNDEFINED,
                        PlatformComponentType.ACTOR_ASSET_ISSUER);

            try {
              communicationNetworkServiceConnectionManager.connectTo(
                  sender, platformComponentProfile, receiver);
            } catch (Exception e) {
              e.printStackTrace();
            }

            // pass the metada to a pool wainting for the response of the other peer or server
            // failure
            poolConnectionsWaitingForResponse.put(fm.getReceiver(), fm);
          }
        }
      }

    } catch (CantReadRecordDataBaseException e) {
      errorManager.reportUnexpectedPluginException(
          Plugins.BITDUBAI_DAP_ASSET_ISSUER_ACTOR_NETWORK_SERVICE,
          UnexpectedPluginExceptionSeverity.DISABLES_SOME_FUNCTIONALITY_WITHIN_THIS_PLUGIN,
          new Exception("Can not send Message PENDING_TO_SEND"));
    }
  }
  /**
   * Handle the event CompleteComponentRegistrationNotificationEvent
   *
   * @param event
   */
  public void handleCompleteComponentRegistrationNotificationEvent(
      CompleteComponentRegistrationNotificationEvent event) {

    try {

      if (wsCommunicationsCloudClientManager
              .getCommunicationsCloudClientConnection(networkServiceType)
              .isRegister()
          && event.getPlatformComponentProfileRegistered().getPlatformComponentType()
              == PlatformComponentType.COMMUNICATION_CLOUD_CLIENT
          && !this.register) {

        if (communicationRegistrationProcessNetworkServiceAgent != null
            && communicationRegistrationProcessNetworkServiceAgent.getActive()) {
          communicationRegistrationProcessNetworkServiceAgent.stop();
          communicationRegistrationProcessNetworkServiceAgent = null;
        }
        wsCommunicationsCloudClientManager
            .getCommunicationsCloudClientConnection(networkServiceType)
            .registerComponentForCommunication(
                this.getNetworkServiceProfile().getNetworkServiceType(),
                this.getNetworkServiceProfile());
      }

      if (event.getPlatformComponentProfileRegistered().getPlatformComponentType()
              == PlatformComponentType.NETWORK_SERVICE
          && event.getPlatformComponentProfileRegistered().getNetworkServiceType()
              == getNetworkServiceProfile().getNetworkServiceType()
          && event
              .getPlatformComponentProfileRegistered()
              .getIdentityPublicKey()
              .equals(identity.getPublicKey())) {

        System.out.println(
            "###################\n"
                + "NETWORK SERVICE REGISTERED: "
                + name
                + "\n###################");

        this.register = Boolean.TRUE;
        onNetworkServiceRegistered();
      }

      if (event.getPlatformComponentProfileRegistered().getPlatformComponentType()
              != PlatformComponentType.COMMUNICATION_CLOUD_CLIENT
          && event.getPlatformComponentProfileRegistered().getPlatformComponentType()
              != PlatformComponentType.NETWORK_SERVICE) {

        onComponentRegistered(event.getPlatformComponentProfileRegistered());
      }

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /**
   * (non-javadoc)
   *
   * @see NetworkService#constructDiscoveryQueryParamsFactory(PlatformComponentType,
   *     NetworkServiceType, String,String, Location, Double, String, String, Integer, Integer,
   *     PlatformComponentType, NetworkServiceType)
   */
  @Override
  public DiscoveryQueryParameters constructDiscoveryQueryParamsFactory(
      final PlatformComponentType platformComponentType,
      final NetworkServiceType networkServiceType,
      final String alias,
      final String identityPublicKey,
      final Location location,
      final Double distance,
      final String name,
      final String extraData,
      final Integer firstRecord,
      final Integer numRegister,
      final PlatformComponentType fromOtherPlatformComponentType,
      final NetworkServiceType fromOtherNetworkServiceType) {

    return wsCommunicationsCloudClientManager
        .getCommunicationsCloudClientConnection()
        .constructDiscoveryQueryParamsFactory(
            platformComponentType,
            networkServiceType,
            alias,
            identityPublicKey,
            location,
            distance,
            name,
            extraData,
            firstRecord,
            numRegister,
            fromOtherPlatformComponentType,
            fromOtherNetworkServiceType);
  }
  /**
   * Handle the event ClientConnectionCloseNotificationEvent
   *
   * @param event
   */
  public void handleClientConnectionCloseNotificationEvent(
      ClientConnectionCloseNotificationEvent event) {

    try {

      if (!wsCommunicationsCloudClientManager
          .getCommunicationsCloudClientConnection(networkServiceType)
          .isRegister()) {

        this.register = Boolean.FALSE;

        if (communicationNetworkServiceConnectionManager != null) {
          communicationNetworkServiceConnectionManager.closeAllConnection();
          communicationNetworkServiceConnectionManager.stop();
        }

        communicationSupervisorPendingMessagesAgent.removeAllConnectionWaitingForResponse();

        onClientConnectionClose();
      }

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 /**
  * This method initialize the cryptoPaymentRequestNetworkServiceConnectionManager. IMPORTANT: Call
  * this method only in the RegistrationProcessNetworkServiceAgent, when execute the registration
  * process because at this moment, is create the platformComponentProfile for this component
  */
 @Override
 public void initializeCommunicationNetworkServiceConnectionManager() {
   this.communicationNetworkServiceConnectionManager =
       new CommunicationNetworkServiceConnectionManager(
           this.getPlatformComponentProfilePluginRoot(),
           identity,
           wsCommunicationsCloudClientManager.getCommunicationsCloudClientConnection(),
           dataBase,
           errorManager,
           eventManager,
           this.getEventSource(),
           getPluginVersionReference(),
           this);
 }
  @Override
  public void requestRemoteNetworkServicesRegisteredList(
      DiscoveryQueryParameters discoveryQueryParameters) {

    /*
     * Request the list of component registers
     */
    try {

      wsCommunicationsCloudClientManager
          .getCommunicationsCloudClientConnection()
          .requestListComponentRegistered(
              this.getPlatformComponentProfilePluginRoot(), discoveryQueryParameters);

    } catch (CantRequestListException e) {

      errorManager.reportUnexpectedPluginException(
          this.getPluginVersionReference(),
          UnexpectedPluginExceptionSeverity.DISABLES_THIS_PLUGIN,
          e);
    }
  }
  /**
   * Handle the event ClientConnectionLooseNotificationEvent
   *
   * @param event
   */
  public void handleClientConnectionLooseNotificationEvent(
      ClientConnectionLooseNotificationEvent event) {

    try {

      if (!wsCommunicationsCloudClientManager
          .getCommunicationsCloudClientConnection(networkServiceType)
          .isRegister()) {

        if (communicationNetworkServiceConnectionManager != null) {
          communicationNetworkServiceConnectionManager.stop();
        }

        this.register = Boolean.FALSE;

        reprocessMessages();

        onClientConnectionLoose();
      }

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /** Service Interface implementation */
  @Override
  public void start() throws CantStartPluginException {

    System.out.println("********* Crypto Payment Request: Starting. ");

    try {
      loadKeyPair(pluginFileSystem);
    } catch (CantLoadKeyPairException e) {

      errorManager.reportUnexpectedPluginException(
          this.getPluginVersionReference(),
          UnexpectedPluginExceptionSeverity.DISABLES_THIS_PLUGIN,
          e);
      throw new CantStartPluginException(
          e, "", "Problem trying to load the key pair of the plugin.");
    }

    /*
     * Validate required resources
     */
    validateInjectedResources();

    // initialize crypto payment request dao

    try {

      cryptoPaymentRequestNetworkServiceDao =
          new CryptoPaymentRequestNetworkServiceDao(pluginDatabaseSystem, pluginId);

      cryptoPaymentRequestNetworkServiceDao.initialize();

    } catch (CantInitializeCryptoPaymentRequestNetworkServiceDatabaseException e) {

      CantStartPluginException pluginStartException =
          new CantStartPluginException(
              e, "", "Problem initializing crypto payment request network service dao.");
      errorManager.reportUnexpectedPluginException(
          this.getPluginVersionReference(),
          UnexpectedPluginExceptionSeverity.DISABLES_THIS_PLUGIN,
          pluginStartException);
      throw pluginStartException;
    }

    try {

      /*
       * Initialize the data base
       */
      initializeCommunicationDb();

      /*
       * Initialize listeners
       */
      initializeListener();

      /*
       * Verify if the communication cloud client is active
       */
      if (!wsCommunicationsCloudClientManager.isDisable()) {

        /*
         * Initialize the agent and start
         */
        communicationRegistrationProcessNetworkServiceAgent =
            new CommunicationRegistrationProcessNetworkServiceAgent(
                this, wsCommunicationsCloudClientManager.getCommunicationsCloudClientConnection());
        communicationRegistrationProcessNetworkServiceAgent.start();
      }

      remoteNetworkServicesRegisteredList = new CopyOnWriteArrayList<>();

      // change message state to process again first time
      reprocessMessage();

      // declare a schedule to process waiting request message
      Timer timer = new Timer();

      timer.schedule(
          new TimerTask() {
            @Override
            public void run() {
              // change message state to process retry later
              reprocessMessage();
            }
          },
          2 * 3600 * 1000);

      /*
       * Its all ok, set the new status
       */
      this.serviceStatus = ServiceStatus.STARTED;

    } catch (CantInitializeNetworkServiceDatabaseException exception) {

      StringBuffer contextBuffer = new StringBuffer();
      contextBuffer.append("Plugin ID: " + pluginId);
      contextBuffer.append(CantStartPluginException.CONTEXT_CONTENT_SEPARATOR);
      contextBuffer.append(
          "Database Name: " + CommunicationNetworkServiceDatabaseConstants.DATA_BASE_NAME);

      String context = contextBuffer.toString();
      String possibleCause =
          "The Template Database triggered an unexpected problem that wasn't able to solve by itself";
      CantStartPluginException pluginStartException =
          new CantStartPluginException(
              CantStartPluginException.DEFAULT_MESSAGE, exception, context, possibleCause);

      errorManager.reportUnexpectedPluginException(
          this.getPluginVersionReference(),
          UnexpectedPluginExceptionSeverity.DISABLES_THIS_PLUGIN,
          pluginStartException);
      throw pluginStartException;
    }

    System.out.println("********* Crypto Payment Request: Successful start. ");
  }
  /**
   * (non-javadoc)
   *
   * @see AbstractPlugin#start()
   */
  @Override
  public final void start() throws CantStartPluginException {

    if (!starting.getAndSet(true)) {

      if (this.serviceStatus != ServiceStatus.STARTING) {

        /*
         * Set status tu starting
         */
        this.serviceStatus = ServiceStatus.STARTING;

        /*
         * Validate required resources
         */
        validateInjectedResources();

        try {

          /*
           * Initialize the identity
           */
          initializeIdentity();

          /*
           * Initialize the data base
           */
          initializeDataBase();

          /*
           * Initialize the  data base for developers tools
           */
          initializeDataBaseForDevelopers();

          /*
           * Initialize listeners
           */
          initializeListener();

          /*
           * Verify if the communication cloud client is active
           */
          if (!wsCommunicationsCloudClientManager.isDisable()) {

            /*
             * Construct my profile and register me
             */
            this.networkServiceProfile =
                wsCommunicationsCloudClientManager
                    .getCommunicationsCloudClientConnection(networkServiceType)
                    .constructPlatformComponentProfileFactory(
                        identity.getPublicKey(),
                        name.toLowerCase(),
                        name,
                        networkServiceType,
                        platformComponentType,
                        extraData);

            /*
             * Initialize connection manager
             */
            this.communicationNetworkServiceConnectionManager =
                new CommunicationNetworkServiceConnectionManager(this, errorManager);

            /*
             * Initialize the agents and start
             */
            this.communicationRegistrationProcessNetworkServiceAgent =
                new CommunicationRegistrationProcessNetworkServiceAgent(this);
            this.communicationRegistrationProcessNetworkServiceAgent.start();

            this.communicationSupervisorPendingMessagesAgent =
                new CommunicationSupervisorPendingMessagesAgent(this);
            this.communicationSupervisorPendingMessagesAgent.start();
          } else {

            System.out.println(" -- COMMUNICATION  cloud client is DISABLED");
          }

          /*
           * Call on start method
           */
          onStart();

          /*
           * Reprocess messages
           */
          reprocessMessages();

          /*
           * Its all ok, set the new status
           */
          this.serviceStatus = ServiceStatus.STARTED;

        } catch (Exception exception) {

          System.out.println(exception.toString());

          StringBuffer contextBuffer = new StringBuffer();
          contextBuffer.append("Plugin ID: " + pluginId);
          contextBuffer.append(CantStartPluginException.CONTEXT_CONTENT_SEPARATOR);
          contextBuffer.append(
              "Database Name: " + CommunicationNetworkServiceDatabaseConstants.DATA_BASE_NAME);
          contextBuffer.append("NS Name: " + networkServiceType);

          String context = contextBuffer.toString();
          String possibleCause =
              "The Template triggered an unexpected problem that wasn't able to solve by itself - ";
          possibleCause += exception.getMessage();
          CantStartPluginException pluginStartException =
              new CantStartPluginException(
                  CantStartPluginException.DEFAULT_MESSAGE, exception, context, possibleCause);
          exception.printStackTrace();

          errorManager.reportUnexpectedPluginException(
              this.getPluginVersionReference(),
              UnexpectedPluginExceptionSeverity.DISABLES_THIS_PLUGIN,
              pluginStartException);
          throw pluginStartException;
        }
      }
    }
  }
  /**
   * Get the CommunicationsClientConnection instance
   *
   * @return CommunicationsClientConnection
   */
  public CommunicationsClientConnection getCommunicationsClientConnection() {

    return wsCommunicationsCloudClientManager.getCommunicationsCloudClientConnection(
        networkServiceType);
  }