private async Task <List <ResultDataType> > ExecuteAsync <ResultDataType>(Messages.RequestMessage Message)
        {
            using (var Socket = new ClientWebSocket())
            {
                await Socket.ConnectAsync(Uri, System.Threading.CancellationToken.None);

                try
                {
                    return(await ExecuteAsync <ResultDataType>(Socket, Message));
                }
                finally
                {
                    await Socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, null, System.Threading.CancellationToken.None);
                }
            }
        }
        private byte[] GetMessageBytes(Messages.RequestMessage Message)
        {
            var Json = JsonConvert.SerializeObject(Message);

            if (UseBinary)
            {
                var SB = new StringBuilder();
                SB.Append((char)("application/json".Length));
                SB.Append("application/json");
                SB.Append(Json);
                return(System.Text.Encoding.UTF8.GetBytes(SB.ToString()));
            }
            else
            {
                return(System.Text.Encoding.UTF8.GetBytes(Json));
            }
        }
        private async Task <List <ResultDataType> > ExecuteAsync <ResultDataType>(ClientWebSocket Socket, Messages.RequestMessage Message)
        {
            byte[] MessageBytes = GetMessageBytes(Message);
            await Socket.SendAsync(new ArraySegment <byte>(MessageBytes), UseBinary?WebSocketMessageType.Binary : WebSocketMessageType.Text, true, System.Threading.CancellationToken.None);

            List <ResultDataType> ToReturn = null;

            while (true)
            {
                var MS     = new System.IO.MemoryStream();
                var Buffer = new ArraySegment <byte>(new byte[ReadBufferSize]);
                while (true)
                {
                    var Data = await Socket.ReceiveAsync(Buffer, System.Threading.CancellationToken.None);

                    MS.Write(Buffer.Array, 0, Data.Count);
                    if (Data.EndOfMessage)
                    {
                        break;
                    }
                }
                var ResponseString = System.Text.Encoding.UTF8.GetString(MS.ToArray());
                var Response       = JsonConvert.DeserializeObject <Messages.ScriptResponse <ResultDataType> >(ResponseString);

                if (Response.Result.Data != null)
                {
                    if (ToReturn == null)
                    {
                        ToReturn = Response.Result.Data;
                    }
                    else
                    {
                        ToReturn.AddRange(Response.Result.Data);
                    }
                }

                switch (Response.Status.Code)
                {
                case 200:     // SUCCESS
                case 204:     // NO CONTENT
                    if (ToReturn == null)
                    {
                        ToReturn = new List <ResultDataType>();
                    }
                    return(ToReturn);

                case 206:     // PARTIAL CONTENT
                    continue;

                case 401:
                    throw new Exceptions.UnauthorizedException(Response.Status.Message);

                case 407:     // AUTHENTICATE
                    if (string.IsNullOrEmpty(Username) || string.IsNullOrEmpty(Password))
                    {
                        throw new Exceptions.UnauthorizedException(Response.Status.Message);
                    }

                    MessageBytes = GetMessageBytes(new Messages.AuthenticationRequestMessage
                    {
                        Arguments = new Messages.AuthenticationRequestArguments(Username, Password)
                    });
                    await Socket.SendAsync(new ArraySegment <byte>(MessageBytes), UseBinary?WebSocketMessageType.Binary : WebSocketMessageType.Text, true, System.Threading.CancellationToken.None);

                    break;

                case 498:
                    throw new Exceptions.MalformedRequestException(Response.Status.Message);

                case 499:
                    throw new Exceptions.InvalidRequestArgumentsException(Response.Status.Message);

                case 500:
                    throw new Exceptions.ServerErrorException(Response.Status.Message);

                case 597:
                    throw new Exceptions.ScriptEvaluationErrorException(Response.Status.Message);

                case 598:
                    throw new Exceptions.ServerTimeoutException(Response.Status.Message);

                case 599:
                    throw new Exceptions.ServerSerializationError(Response.Status.Message);

                default:
                    throw new Exception("Unsupported StatusCode (" + Response.Status.Code + "): " + Response.Status.Message);
                }
            }
        }