/// <summary>
            /// runs the receiving end
            /// </summary>
            /// <param name="token"></param>
            /// <param name="reader"></param>
            private void Run(CancellationToken token, TextReader reader)
            {
                try
                {
                    while (!token.IsCancellationRequested)
                    {
                        var line = reader.ReadLine();
                        if (line == null)
                        {
                            break;
                        }

                        // ReSharper disable once MethodSupportsCancellation (unncessary)
                        Task.Run(() => client.OnRawReceived(line));
                    }
                }
                catch (IOException e)
                {
                    if ((e.InnerException as SocketException)?.ErrorCode != 10004)
                    {
                        client.OnException(new ExceptionEventArgs(e));
                    }
                }
                catch (Exception e)
                {
                    client.OnException(new ExceptionEventArgs(e));
                }
                finally
                {
                    if (!token.IsCancellationRequested)
                    {
                        // ReSharper disable once MethodSupportsCancellation
                        Task.ContinueWith(t => client.HandleUnexpectedDisconnect());
                    }
                }
            }
            private void Run(CancellationToken token, TextWriter writer)
            {
                try
                {
                    var isSignalled = false;
                    while (!token.IsCancellationRequested)
                    {
                        while (client.sendQueue.Count > 0)
                        {
                            if (token.IsCancellationRequested)
                            {
                                break;
                            }

                            QueuedMessage message;
                            if (!TryRead(out message))
                            {
                                break;
                            }

                            if (message.Limit?.Throttle() ?? false)
                            {
                                message.Priority--;
                                var rem = message.Limit.Remaining;
                                if (rem > TimeSpan.Zero)
                                {
                                    // ReSharper disable once MethodSupportsCancellation
                                    Task.Delay(rem, token)
                                    .ContinueWith(t =>
                                    {
                                        if (t.IsFaulted || t.IsCanceled || token.IsCancellationRequested)
                                        {
                                            return;
                                        }
                                        lock (client.sendSyncRoot)
                                        {
                                            client.sendQueue.Enqueue(message);
                                        }
                                        Signal();
                                    });
                                }
                                else
                                {
                                    lock (client.sendSyncRoot)
                                    {
                                        client.sendQueue.Enqueue(message);
                                    }
                                }
                            }
                            else
                            {
                                writer.WriteLine(message.Message);
                            }
                        }
                        writer.Flush();

                        while (!token.IsCancellationRequested && !isSignalled)
                        {
                            if (signal.WaitOne(100))
                            {
                                isSignalled = true;
                            }
                        }
                        isSignalled = false;
                    }
                }
                catch (Exception e)
                {
                    client.OnException(new ExceptionEventArgs(e));
                }
                finally
                {
                    if (!token.IsCancellationRequested)
                    {
                        // ReSharper disable once MethodSupportsCancellation
                        Task.ContinueWith(t => client.HandleUnexpectedDisconnect());
                    }
                }
            }