/** 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;
        }
      }
    }
  }