public MessageManager(NodeManagement nodeManagement) throws RemoteException {
    UnicastRemoteObject.exportObject(this, 0);

    this.nodeManagement = nodeManagement;

    // instance the message queue
    int messagesQueueSize =
        nodeManagement
            .getConfigFile()
            .getProperty("MessagesQueueSize", DEFAULT_MESSAGES_QUEUE_SIZE);
    messagesQueue = new LinkedBlockingQueue<MessageContainer>(messagesQueueSize);

    // instance the broadcasted messages queue
    int broadcastedMessagesQueueSize =
        nodeManagement
            .getConfigFile()
            .getProperty("BroadcastedMessagesQueueSize", DEFAULT_BROADCASTED_MESSAGES_QUEUE_SIZE);
    broadcastedMessagesQueue =
        new LinkedBlockingQueue<MessageContainer>(broadcastedMessagesQueueSize);

    synchronizationTime = new ConcurrentHashMap<String, Long>();
  }
  public void startMessageProcessing() {
    long messageExpirationTime =
        nodeManagement
            .getConfigFile()
            .getProperty("MessageExpirationTime", DEFAULT_MESSAGE_EXPIRATION_TIME);

    // start the message depurator to empty the list of broadcasted messages after their timestamp
    // has expired
    MessageDepurator messageDepurator =
        new MessageDepurator(nodeManagement, broadcastedMessagesQueue, messageExpirationTime);
    new Thread(messageDepurator).start();

    // start the message processor to process the arriving messages
    MessageProcessor messageProcessor = new MessageProcessor(nodeManagement, messagesQueue);
    new Thread(messageProcessor).start();

    // start the message requester to get the new messages from every group node
    if (nodeManagement.getConfigFile().getProperty("MessageRequesterEnabled", false)) {
      MessageRequester messageRequester = new MessageRequester(nodeManagement);
      new Thread(messageRequester).start();
    }
  }