/// <summary>
        /// Used to communicate channel properties between the client and the server.
        /// Sent by the server during the login process or when channel properties are updated.
        /// </summary>
        /// <param name="channelState"></param>
        public virtual void ChannelState(ChannelState channelState)
        {
            if (!channelState.ShouldSerializeChannelId())
            {
                throw new InvalidOperationException($"{nameof(ChannelState)} must provide a {channelState.ChannelId}.");
            }

            var channel = ChannelDictionary.AddOrUpdate(channelState.ChannelId, i =>
            {
                //Add new channel to the dictionary
                return(new Channel(this, channelState.ChannelId, channelState.Name, channelState.Parent)
                {
                    Temporary = channelState.Temporary,
                    Description = channelState.Description,
                    Position = channelState.Position
                });
            },
                                                        (i, c) => c);

            //Update channel in the dictionary
            if (channelState.ShouldSerializeName())
            {
                channel.Name = channelState.Name;
            }
            if (channelState.ShouldSerializeParent())
            {
                channel.Parent = channelState.Parent;
            }
            if (channelState.ShouldSerializeTemporary())
            {
                channel.Temporary = channelState.Temporary;
            }
            if (channelState.ShouldSerializeDescription())
            {
                channel.Description = channelState.Description;
            }
            if (channelState.ShouldSerializePosition())
            {
                channel.Position = channelState.Position;
            }

            if (channel.Id == 0)
            {
                RootChannel = channel;
            }

            ChannelJoined(channel);

            Extensions.Log.Info("Chanel State", channelState);
        }