/// <summary>
        /// Create a PixelFormat object from a data packet describing it
        /// </summary>
        /// <param name="packet">The data packet.</param>
        /// <returns>A new <see cref="PixelFormat"/> object</returns>
        public static PixelFormat FromServerInit(byte[] packet)
        {
            var format = new PixelFormat();

            format.BitsPerPixel = packet[4];
            format.Depth = packet[5];

            format.IsBigEndian = packet[6] != 0;
            format.IsTrueColor = packet[7] != 0;

            format.RedMax = (packet[8] << 8) | packet[9];
            format.GreenMax = (packet[10] << 8) | packet[11];
            format.BlueMax = (packet[12] << 8) | packet[13];

            format.RedShift = packet[14];
            format.GreenShift = packet[15];
            format.BlueShift = packet[16];

            return format;
        }
        /// <summary>Initialize the connection.</summary>
        /// <param name="shareDesktop">Indicates whether the desktop is shared.</param>
        /// <returns>An async task</returns>
        public override async Task<string> InitializeAsync(bool shareDesktop)
        {
            using (await this.exclusiveLock.Enter())
            {
                if ((this.RequiresPassword && this.ConnectionState != ConnectionState.SendingPassword)
                    || (this.RequiresPassword == false && this.ConnectionState != ConnectionState.Handshaking))
                {
                    throw new InvalidOperationException();
                }

                this.ConnectionState = ConnectionState.Initializing;

                using (var cancellation = new CancellationTokenSource())
                {
                    cancellation.CancelAfter(DefaultTimeout);
                    var share = new byte[] { (byte)(shareDesktop ? 1 : 0) };
                    await this.writeStream.WriteAsync(share, 0, 1, cancellation.Token);
                    await this.writeStream.FlushAsync();
                }

                var packet = new byte[ServerInitHeaderLength];

                using (var cancellation = new CancellationTokenSource())
                {
                    cancellation.CancelAfter(DefaultTimeout);
                    await this.ReadPacketAsync(packet, cancellation.Token);
                }

                this.Width = (packet[0] << 8) | packet[1];
                this.Height = (packet[2] << 8) | packet[3];

                this.pixelFormat = PixelFormat.FromServerInit(packet);

                var nameLength = ConvertBigEndianU32(packet, 20);

                packet = new byte[nameLength];

                using (var cancellation = new CancellationTokenSource())
                {
                    cancellation.CancelAfter(DefaultTimeout);
                    var ignored = this.ReadPacketAsync(packet, cancellation.Token);
                }

                this.Name = Encoding.UTF8.GetString(packet, 0, packet.Length);

                this.Initialized = true;

                this.ConnectionState = ConnectionState.Connected;
                return this.Name;
            }
        }