private void SendCommand(CommandWithActions toSend)
        {
            try
            {
                int sequenceNumber;
                lock (this)
                {
                    sequenceNumber = _sequenceNumber;
                    _sequenceNumber++;

                    _responseListeners[sequenceNumber] = toSend;
                }

                byte[] payload  = toSend.Command.GetBytes(sequenceNumber);
                var    sendTask = _streamSpheroWrapper.SendBytes(payload);
                sendTask.Start();
                sendTask.Wait();
            }
            catch (AggregateException exception)
            {
                toSend.OnError(exception.InnerException);
            }
            catch (Exception exception)
            {
                toSend.OnError(exception);
            }
        }
        public void SendAndReceive(ISpheroCommand command, Action <ISpheroMessage> onSuccess, Action <Exception> onError)
        {
            //DoCommand(command, onSuccess, onError);
            var message = new CommandWithActions(command, onSuccess, onError);

            lock (_commandsToSend)
            {
                _commandsToSend.Enqueue(message);
                if (_commandsToSend.Count > 0)
                {
                    _itemsReadyEvent.Set();
                }
            }
        }
        public void SendAndReceive(ISpheroCommand command, Action <ISpheroMessage> onSuccess, Action <Exception> onError)
        {
            //DoCommand(command, onSuccess, onError);
            var message = new CommandWithActions(command, onSuccess, onError);

            lock (_commandsToSend)
            {
                _commandsToSend.Enqueue(message);
                if (_commandsToSend.Count == 1)
                {
                    _itemsToSendEvent.Release();
                }
                while (_commandsToSend.Count > MaxQueueSize)
                {
                    // TODO - shoudl at least trace this really!
                    _commandsToSend.Dequeue();
                }
            }
        }
        private async Task SendCommand(CommandWithActions toSend)
        {
            try
            {
                int sequenceNumber;
                lock (this)
                {
                    sequenceNumber = _sequenceNumber;
                    _sequenceNumber++;

                    _responseListeners[sequenceNumber] = toSend;
                }

                byte[] payload = toSend.Command.GetBytes(sequenceNumber);
                await _streamSpheroWrapper.SendBytes(payload);
            }
            catch (Exception exception)
            {
                toSend.OnError(exception);
            }
        }
        private void SendCommmands()
        {
            try
            {
                while (true)
                {
                    var waitResult = _itemsReadyEvent.WaitOne(100);

                    if (!waitResult)
                    {
                        if (_disconnected)
                        {
                            break;
                        }
                        continue;
                    }

                    CommandWithActions toSendThisTime = null;
                    lock (_commandsToSend)
                    {
                        toSendThisTime = _commandsToSend.Dequeue();
                        if (_commandsToSend.Count == 0)
                        {
                            _itemsReadyEvent.Reset();
                        }
                    }

                    SendCommand(toSendThisTime);
                }
            }
            catch (SpheroPluginException exception)
            {
                // assume disconnected
                RaiseDisconnected();
            }
        }
        protected async Task SendCommmands()
        {
            try
            {
                while (true)
                {
                    var waitResult = await _itemsToSendEvent.WaitAsync(1000);

                    if (!waitResult)
                    {
                        if (_disconnected)
                        {
                            break;
                        }
                        continue;
                    }

                    CommandWithActions toSendThisTime = null;
                    lock (_commandsToSend)
                    {
                        toSendThisTime = _commandsToSend.Dequeue();
                        if (_commandsToSend.Count != 0)
                        {
                            _itemsToSendEvent.Release();
                        }
                    }

                    await SendCommand(toSendThisTime);
                }
            }
            catch (SpheroPluginException exception)
            {
                // assume disconnected
                RaiseDisconnected();
            }
        }