/// <summary>
        /// Creates the command packet's header and returns a BinaryWriter so the caller
        /// can write the command packet's payload.
        /// </summary>
        /// <param name="ms">A MemoryStream to write the command packet.</param>
        /// <param name="command">A CapabilitiesProtocolCommands that specifies the command.</param>
        /// <returns>A BinaryWriter that contains the command packet's header.</returns>
        private BinaryWriter GetBinaryWriter(MemoryStream ms, CapabilitiesProtocolCommands command)
        {
            BinaryWriter bw = new BinaryWriter(ms, Encoding.UTF8);

            bw.Write(PROTOCOL_IDENTIFIER);
            bw.Write((byte)command);
            return(bw);
        }
        /// <summary>
        /// Handles the <see cref="US.OpenServer.Protocols.CapabilitiesProtocolCommands.PROTOCOL_IDS"/> and
        /// <see cref="US.OpenServer.Protocols.CapabilitiesProtocolCommands.ERROR"/>
        /// command packet request.
        /// </summary>
        /// <param name="br">A BinaryReader that contains the command packet.</param>
        public override void OnPacketReceived(BinaryReader br)
        {
            ushort protocolId   = 0;
            string errorMessage = null;

            CapabilitiesProtocolCommands command = (CapabilitiesProtocolCommands)br.ReadByte();

            switch (command)
            {
            case CapabilitiesProtocolCommands.GET_PROTOCOL_IDS:
            {
                ushort[]     protocolIds = Session.GetLocalSupportedProtocolIds();
                MemoryStream ms          = new MemoryStream();
                BinaryWriter bw          = GetBinaryWriter(ms, CapabilitiesProtocolCommands.PROTOCOL_IDS);
                bw.Write(protocolIds);
                Log(Level.Debug, string.Format("Sent Protocol IDs: {0}", string.Join(", ", protocolIds.ToArray())));
                Session.Send(ms);
                break;
            }

            case CapabilitiesProtocolCommands.PROTOCOL_IDS:
                lock (this)
                {
                    supportedRemoteProtocolIds = br.ReadUInt16s();
                    Log(Level.Debug, string.Format("Received Protocol IDs: {0}", string.Join(", ", supportedRemoteProtocolIds.ToArray())));
                    Monitor.PulseAll(this);
                }
                break;

            case CapabilitiesProtocolCommands.ERROR:
                lock (this)
                {
                    protocolId   = br.ReadUInt16();
                    errorMessage = br.ReadString();
                    Log(Level.Error, errorMessage);
                    Monitor.PulseAll(this);
                }
                break;

            default:
                Log(Level.Error, string.Format("Invalid or unsupported command.  Command: {0}", command));
                break;
            }

            if (!string.IsNullOrEmpty(errorMessage))
            {
                Session.OnCapabilitiesError(protocolId, errorMessage);
            }
        }
 /// <summary>
 /// Creates the command packet's header and returns a BinaryWriter so the caller
 /// can write the command packet's payload.
 /// </summary>
 /// <param name="ms">A MemoryStream to write the command packet.</param>
 /// <param name="command">A CapabilitiesProtocolCommands that specifies the command.</param>
 /// <returns>A BinaryWriter that contains the command packet's header.</returns>
 private BinaryWriter GetBinaryWriter(MemoryStream ms, CapabilitiesProtocolCommands command)
 {
     BinaryWriter bw = new BinaryWriter(ms, Encoding.UTF8);
     bw.Write(PROTOCOL_IDENTIFIER);
     bw.Write((byte)command);
     return bw;
 }