/// <summary>
        /// Callback when data is ready to be processed
        /// </summary>
        /// <param name="ar">State information for the callback</param>
        private void OnReadData(IAsyncResult ar)
        {
            // grab the byte buffer
            byte[] buff = (byte[])ar.AsyncState;

            try {
                // end the current read
                mStream.EndRead(ar);

                // parse it
                if (ParseInputReport(buff))
                {
                    // post an event
                    WiimoteChanged?.Invoke(this, new WiimoteChangedEventArgs(mWiimoteState));
                }

                // start reading again
                BeginAsyncRead();
            }
            catch (OperationCanceledException) {
                //ThrowException(ex);
            }
            catch (Exception ex) {
                ThrowException(ex);
                return;
            }
        }
        public void InternalWiimoteChangedHandler(WiimoteChanged update)
        {
            _state = update.Body;

            // send a msg to our subscribers that the wiimote changed
            SendNotification <WiimoteChanged>(_subMgrPort, update);

            update.ResponsePort.Post(DefaultUpdateResponseType.Instance);
        }