private async void button1_Click(object sender, EventArgs e)
        {
            var operation = OperationMessage.MACRead(0x0002);

            float priotity = 0;
            List<Task> tasks = new List<Task>();

            for (int i = 0; i < 8; i++)
            {
                var task = new Task(async () =>
                    {
                        Debug.WriteLine("Message " + priotity + " enqueued");
                        OutputHeader outputMessage = new OutputHeader(priotity)
                        {
                            SecurityEnabled = true,
                            RoutingEnabled = true,
                            EndPoint = 1,
                            Retries = 3,
                            Content = operation
                        };
                        priotity += 0.1f;
                        Debug.WriteLine(outputMessage.Priority + " Response: " + (await CommunicationManager.Instance.SendMessage(outputMessage)).ToString() + " " + DateTime.Now.Millisecond);
                    });

                task.Start();

                tasks.Add(task);
            }

            await Task.WhenAll(tasks);
        }
        public async Task<bool> SendMessage(IMessage message)
        {
            OutputHeader outputMessage = new OutputHeader(this.OutputParameters.Priority)
            {
                EndPoint = this.OutputParameters.Endpoint,
                Retries = this.OutputParameters.MaxRetries,
                Content = message,
            };

            return await this.communicationManager.SendMessage(outputMessage);
        }
        /// <summary>
        /// Sends the an message to the node physically connected.
        /// </summary>
        /// <param name="operation">The message to be sent.</param>
        /// <returns></returns>
        private bool SendInternalMessage(IMessage message)
        {
            if (message.DestinationAddress != 0 && message.DestinationAddress != this.NodeAddress)
                throw new InvalidOperationException("This method can be used only to send internal messages");

            OutputHeader outputMessage = new OutputHeader()
            {
                MessageId = 255, // Internal use only
                SecurityEnabled = true,
                RoutingEnabled = true,
                EndPoint = 1,
                Retries = 3,
                Content = message
            };

            if (message is OperationMessage)
                Debug.WriteLine(this.PortName + " UART SEND OPCODE " + ((OperationMessage)message).OpCode.ToString());

            return this.SendData(outputMessage.ToBinary());
        }
        public async Task<bool> SendMessage(OutputHeader message)
        {
            if (this.pendingConfirmationTask != null && !this.pendingConfirmationTask.Task.IsCompleted)
                throw new InvalidOperationException("Sending in progress");

            this.pendingConfirmationTask = new TaskCompletionSource<bool>();
            
            this.currentMessageId = (currentMessageId + 1) % 254; //255 is reserved for internal messages
            message.MessageId = this.currentMessageId;

            if (message.Content is OperationMessage)
                Debug.WriteLine(this.PortName + " UART SEND OPCODE " + ((OperationMessage)message.Content).OpCode.ToString());

            if (!this.SendData(message.ToBinary()))
            {
                return false;
            }
            else
            {
                //Await for a confirmation with timeout
                Task delayTask = Task.Delay(this.ConfirmationTimeout);
                Task firstTask = await Task.WhenAny(this.pendingConfirmationTask.Task, delayTask);

                if (firstTask == delayTask)
                {
                    //Timeout
                    Debug.WriteLine(this.PortName + " Confirmation response aborted TIMEOUT!");
                    this.pendingConfirmationTask.SetCanceled();
                    return false;
                }
                else
                {
                    return pendingConfirmationTask.Task.Result;
                }
            }
        }