/// <summary>
        /// Handles writing the information about a trade being closed.
        /// </summary>
        /// <param name="peerTradeSession">The <see cref="IPeerTradeSession{TChar,TItem}"/>.</param>
        /// <param name="c">The character that canceled the trade.</param>
        public void WriteTradeCanceled(IPeerTradeSession <TChar, TItem> peerTradeSession, TChar c)
        {
            if (peerTradeSession == null)
            {
                const string errmsg = "Parameter `peerTradeSession` cannot be null.";
                if (log.IsErrorEnabled)
                {
                    log.Error(errmsg);
                }
                Debug.Fail(errmsg);
                return;
            }

            if (c == null)
            {
                const string errmsg = "Parameter `c` cannot be null.";
                if (log.IsErrorEnabled)
                {
                    log.Error(errmsg);
                }
                Debug.Fail(errmsg);
                return;
            }

            // Check who can receive the data
            var sendToSource = CanSendDataTo(peerTradeSession.CharSource);
            var sendToTarget = CanSendDataTo(peerTradeSession.CharTarget);

            if (!sendToSource && !sendToTarget)
            {
                return;
            }

            // Construct and send the data
            using (var pw = CreateWriter(PeerTradeInfoServerMessage.Canceled))
            {
                var sourceClosed = (c == peerTradeSession.CharSource);
                pw.Write(sourceClosed);

                if (sendToSource)
                {
                    SendDataTo(peerTradeSession.CharSource, pw);
                }

                if (sendToTarget)
                {
                    SendDataTo(peerTradeSession.CharTarget, pw);
                }
            }
        }
        /// <summary>
        /// Handles writing the information for starting a trade session.
        /// </summary>
        /// <param name="peerTradeSession">The <see cref="IPeerTradeSession{TChar,TItem}"/>.</param>
        public void WriteTradeOpened(IPeerTradeSession <TChar, TItem> peerTradeSession)
        {
            if (peerTradeSession == null)
            {
                const string errmsg = "Parameter `peerTradeSession` cannot be null.";
                if (log.IsErrorEnabled)
                {
                    log.Error(errmsg);
                }
                Debug.Fail(errmsg);
                return;
            }

            // Check who can receive the data
            var sendToSource = CanSendDataTo(peerTradeSession.CharSource);
            var sendToTarget = CanSendDataTo(peerTradeSession.CharTarget);

            // Construct and send the data
            if (sendToSource)
            {
                using (var pw = CreateWriter(PeerTradeInfoServerMessage.Open))
                {
                    const bool isClientSource       = true;
                    var        otherCharDisplayName = GetCharDisplayName(peerTradeSession.CharTarget);

                    pw.Write(isClientSource);
                    pw.Write(otherCharDisplayName);

                    SendDataTo(peerTradeSession.CharSource, pw);
                }
            }

            if (sendToTarget)
            {
                using (var pw = CreateWriter(PeerTradeInfoServerMessage.Open))
                {
                    const bool isClientSource       = false;
                    var        otherCharDisplayName = GetCharDisplayName(peerTradeSession.CharSource);

                    pw.Write(isClientSource);
                    pw.Write(otherCharDisplayName);

                    SendDataTo(peerTradeSession.CharTarget, pw);
                }
            }
        }
        /// <summary>
        /// Handles writing the information about a table slot changing.
        /// </summary>
        /// <param name="peerTradeSession">The <see cref="IPeerTradeSession{TChar,TItem}"/>.</param>
        /// <param name="c">The character that owns the side of the trade table that changed.</param>
        /// <param name="slot">The slot that changed.</param>
        /// <param name="item">The item that currently occupies the slot.</param>
        public void WriteTradeTableSlotChanged(IPeerTradeSession <TChar, TItem> peerTradeSession, TChar c, InventorySlot slot,
                                               TItem item)
        {
            if (peerTradeSession == null)
            {
                const string errmsg = "Parameter `peerTradeSession` cannot be null.";
                if (log.IsErrorEnabled)
                {
                    log.Error(errmsg);
                }
                Debug.Fail(errmsg);
                return;
            }

            if (c == null)
            {
                const string errmsg = "Parameter `c` cannot be null.";
                if (log.IsErrorEnabled)
                {
                    log.Error(errmsg);
                }
                Debug.Fail(errmsg);
                return;
            }

            if (c != peerTradeSession.CharSource && c != peerTradeSession.CharTarget)
            {
                const string errmsg = "Character `{0}` is not part of the trade session `{1}`!";
                if (log.IsErrorEnabled)
                {
                    log.ErrorFormat(errmsg, c, peerTradeSession);
                }
                Debug.Fail(string.Format(errmsg, c, peerTradeSession));
                return;
            }

            // Check who can receive the data
            var sendToSource = CanSendDataTo(peerTradeSession.CharSource);
            var sendToTarget = CanSendDataTo(peerTradeSession.CharTarget);

            if (!sendToSource && !sendToTarget)
            {
                return;
            }

            // Find out what side the change took place on
            var isSourceSide = (peerTradeSession.CharSource == c);

            // Get the item information
            var itemInfo = item == null ? null : GetItemInfo(item);

            // Construct and send the data
            using (var pw = CreateWriter(PeerTradeInfoServerMessage.UpdateSlot))
            {
                // Build
                pw.Write(isSourceSide);
                pw.Write(slot);
                pw.Write(itemInfo == null);

                if (itemInfo != null)
                {
                    WriteItemInfo(pw, itemInfo);
                }

                // Send
                if (sendToSource)
                {
                    SendDataTo(peerTradeSession.CharSource, pw);
                }

                if (sendToTarget)
                {
                    SendDataTo(peerTradeSession.CharTarget, pw);
                }
            }
        }