private static void wc_UploadDataCompleted(object sender, UploadDataCompletedEventArgs e)
        {
            ICommand cmd;
            if (!e.Cancelled)
            {
                if (e.Error != null)
                {
                    WebException ex = e.Error as WebException;
                    string title = OtherStrings.Error;
                    if (ex.Response != null)
                    {
                        HttpWebResponse response = (HttpWebResponse)ex.Response;
                        if (response.StatusCode == HttpStatusCode.Conflict && ((TransmissonRequest)e.UserState).allowRecursion)
                        {
                            try
                            {
                                string sessionid = ex.Response.Headers["X-Transmission-Session-Id"];
                                if (sessionid != null && sessionid.Length > 0)
                                {
                                    TransmissionWebClient.X_transmission_session_id = sessionid;
                                    (sender as TransmissionWebClient).UploadDataAsync(
                                        new Uri(Program.Settings.Current.RpcUrl), null,
                                        ((TransmissonRequest)e.UserState).data,
                                        new TransmissonRequest(((TransmissonRequest)e.UserState).requestid,
                                        ((TransmissonRequest)e.UserState).data, false));
                                    return;
                                }
                            }
                            catch { }
                        }
                        else if (response.StatusCode == HttpStatusCode.NotFound)
                        {
                            title = OtherStrings.NotFound;
                            ex = new WebException(OtherStrings.NotFoundError);
                        }
                        else if (response.StatusCode == HttpStatusCode.Forbidden || response.StatusCode == HttpStatusCode.Unauthorized)
                        {
                            using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(response.CharacterSet)))
                            {
                                string s = sr.ReadToEnd();
                                if (s.Contains("Unauthorized IP Address."))
                                {
                                    title = OtherStrings.UnauthorizedIP;
                                    ex = new WebException(OtherStrings.UnauthorizedIPError);
                                }
                                else if (s.Contains("Unauthorized User"))
                                {
                                    title = OtherStrings.UnauthorizedUser;
                                    ex = new WebException(OtherStrings.UnauthorizedUserError);
                                }
                            }
                        }
                    }
                    cmd = new ErrorCommand(title, ex.Message, false);
                }
                else
                {
                    try
                    {
#if LOGRPC
                        Program.LogDebug("RPC response: " + ((TransmissonRequest)e.UserState).requestid, GetString(e.Result));
#endif
                        JsonObject jsonResponse = (JsonObject)JsonConvert.Import(GetString(e.Result));
                        if ((string)jsonResponse["result"] != "success")
                        {
                            string response = (string)jsonResponse["result"];
                            if (response.StartsWith("http error"))
                            {
                                int i = response.IndexOf(':');
                                if (i >= 0)
                                    response = response.Substring(i + 2);
                                else
                                    response = response.Remove(0, 11); /* strlen("http error") = 11 */

                                cmd = new ErrorCommand(OtherStrings.UnsuccessfulRequest, string.Format(OtherStrings.HttpError, Environment.NewLine, response), true);
                            }
                            else
                                cmd = new ErrorCommand(OtherStrings.UnsuccessfulRequest, response, true);
                            if (Toolbox.ToShort(jsonResponse[ProtocolConstants.KEY_TAG]).Equals((short)ResponseTag.UpdateBlocklist))
                                RemoteSettingsDialog.BlocklistUpdateDone(-1);
                        }
                        else
                        {
                            switch (Toolbox.ToShort(jsonResponse[ProtocolConstants.KEY_TAG]))
                            {
                                case (short)ResponseTag.TorrentGet:
                                    cmd = new TorrentGetCommand(jsonResponse);
                                    break;

                                case (short)ResponseTag.SessionGet:
                                    cmd = new SessionCommand(jsonResponse, (sender as WebClient).Headers);
                                    break;

                                case (short)ResponseTag.SessionStats:
                                    cmd = new SessionStatsCommand(jsonResponse);
                                    break;

                                case (short)ResponseTag.UpdateFiles:
                                    cmd = new UpdateFilesCommand(jsonResponse);
                                    break;

                                case (short)ResponseTag.PortTest:
                                    cmd = new PortTestCommand(jsonResponse);
                                    break;

                                case (short)ResponseTag.UpdateBlocklist:
                                    cmd = new UpdateBlocklistCommand(jsonResponse);
                                    break;

                                case (short)ResponseTag.DoNothing:
                                    cmd = new NoCommand();
                                    break;

                                default:
                                    cmd = new ErrorCommand(OtherStrings.UnknownResponseTag, e.Result != null ? GetString(e.Result) : "null", false);
                                    break;
                            }
                        }
                    }
                    catch (InvalidCastException)
                    {
                        cmd = new ErrorCommand(OtherStrings.UnableToParse, e.Result != null ? GetString(e.Result) : "Null", false);
                    }
                    catch (JsonException ex)
                    {
                        cmd = new ErrorCommand(string.Format("{0} ({1})", OtherStrings.UnableToParse, ex.GetType()), GetString(e.Result), false);
                    }
                    catch (Exception ex)
                    {
                        cmd = new ErrorCommand(ex, false);
                    }
                }
                try
                {
                    cmd.Execute();
                }
                catch (Exception ee) // just for debugging...
                {
                    Console.WriteLine(ee.Message);
                    Program.LogDebug(ee.Source, ee.Message);
                }
                (sender as TransmissionWebClient).OnCompleted(cmd);
            }
            else
            {
                if (!Program.Connected)
                {
                    Program.Connected = false;
                    Program.Form.UpdateStatus("", false);
                    Program.Form.connectButton.Enabled = Program.Form.connectToolStripMenuItem.Enabled = true;
                }
            }
        }
        static void wc_UploadDataCompleted(object sender, UploadDataCompletedEventArgs e)
        {
            if (!e.Cancelled)
            {
                ICommand cmd;
                if (e.Error != null)
                {
                    var    ex    = e.Error as WebException;
                    string title = OtherStrings.Error;
                    if (ex?.Response != null)
                    {
                        HttpWebResponse response = (HttpWebResponse)ex.Response;
                        if (response.StatusCode == HttpStatusCode.Conflict && ((TransmissonRequest)e.UserState).allowRecursion)
                        {
                            try
                            {
                                string sessionid = ex.Response.Headers["X-Transmission-Session-Id"];
                                if (!string.IsNullOrEmpty(sessionid))
                                {
                                    TransmissionWebClient.XTransmissionSessionId = sessionid;
                                    ((TransmissionWebClient)sender).UploadDataAsync(new Uri(Program.Settings.Current.RpcUrl), null, ((TransmissonRequest)e.UserState).data, new TransmissonRequest(((TransmissonRequest)e.UserState).requestid, ((TransmissonRequest)e.UserState).data, false));
                                    return;
                                }
                            }
                            catch { }
                        }
                        else if (response.StatusCode == HttpStatusCode.NotFound)
                        {
                            title = OtherStrings.NotFound;
                            ex    = new WebException(OtherStrings.NotFoundError);
                        }
                        else if (response.StatusCode == HttpStatusCode.Forbidden || response.StatusCode == HttpStatusCode.Unauthorized)
                        {
                            using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(response.CharacterSet)))
                            {
                                String s = sr.ReadToEnd();
                                if (s.Contains("Unauthorized IP Address."))
                                {
                                    title = OtherStrings.UnauthorizedIP;
                                    ex    = new WebException(OtherStrings.UnauthorizedIPError);
                                }
                                else if (s.Contains("Unauthorized User"))
                                {
                                    title = OtherStrings.UnauthorizedUser;
                                    ex    = new WebException(OtherStrings.UnauthorizedUserError);
                                }
                            }
                        }
                    }
                    cmd = new ErrorCommand(title, ex?.Message, false);
                }
                else
                {
                    try
                    {
#if LOGRPC
                        Program.LogDebug("RPC response: " + ((TransmissonRequest)e.UserState).requestid, GetString(e.Result));
#endif
                        JsonObject jsonResponse = (JsonObject)JsonConvert.Import(GetString(e.Result));
                        if ((string)jsonResponse["result"] != "success")
                        {
                            string response = (string)jsonResponse["result"];
                            if (response.StartsWith("http error"))
                            {
                                int i = response.IndexOf(':');
                                if (i >= 0)
                                {
                                    response = response.Substring(i + 2);
                                }
                                else
                                {
                                    response = response.Remove(0, 11); /* strlen("http error") = 11 */
                                }
                                cmd = new ErrorCommand(OtherStrings.UnsuccessfulRequest, string.Format(OtherStrings.HttpError, Environment.NewLine, response), true);
                            }
                            else
                            {
                                cmd = new ErrorCommand(OtherStrings.UnsuccessfulRequest, response, true);
                            }
                            if (Toolbox.ToShort(jsonResponse[ProtocolConstants.KEY_TAG]).Equals((short)ResponseTag.UpdateBlocklist))
                            {
                                RemoteSettingsDialog.BlocklistUpdateDone(-1);
                            }
                        }
                        else
                        {
                            switch (Toolbox.ToShort(jsonResponse[ProtocolConstants.KEY_TAG]))
                            {
                            case (short)ResponseTag.TorrentGet:
                                cmd = new TorrentGetCommand(jsonResponse);
                                break;

                            case (short)ResponseTag.SessionGet:
                                cmd = new SessionCommand(jsonResponse, ((WebClient)sender).Headers);
                                break;

                            case (short)ResponseTag.SessionStats:
                                cmd = new SessionStatsCommand(jsonResponse);
                                break;

                            case (short)ResponseTag.UpdateFiles:
                                cmd = new UpdateFilesCommand(jsonResponse);
                                break;

                            case (short)ResponseTag.PortTest:
                                cmd = new PortTestCommand(jsonResponse);
                                break;

                            case (short)ResponseTag.UpdateBlocklist:
                                cmd = new UpdateBlocklistCommand(jsonResponse);
                                break;

                            case (short)ResponseTag.DoNothing:
                                cmd = new NoCommand();
                                break;

                            default:
                                cmd = new ErrorCommand(OtherStrings.UnknownResponseTag, e.Result != null ? GetString(e.Result) : "null", false);
                                break;
                            }
                        }
                    }
                    catch (InvalidCastException)
                    {
                        cmd = new ErrorCommand(OtherStrings.UnableToParse, e.Result != null ? GetString(e.Result) : "Null", false);
                    }
                    catch (JsonException ex)
                    {
                        cmd = new ErrorCommand($"{OtherStrings.UnableToParse} ({ex.GetType()})", GetString(e.Result), false);
                    }
                    catch (Exception ex)
                    {
                        cmd = new ErrorCommand(ex, false);
                    }
                }
                try
                {
                    cmd.Execute();
                }
                catch (Exception ee)
                { // just for debugging...
                    Console.WriteLine(ee.Message);
                    Program.LogDebug(ee.Source, ee.Message);
                }
                ((TransmissionWebClient)sender).OnCompleted(cmd);
            }
            else
            {
                if (!Program.Connected)
                {
                    Program.Connected = false;
                    Program.Form.UpdateStatus("", false);
                    Program.Form.connectButton.Enabled = Program.Form.connectToolStripMenuItem.Enabled = true;
                }
            }
        }