private function establishConnection($host, $port, $timeout)
    {
        $deferred = new Deferred();

        $timer = $this->loop->addTimer(
            $timeout,
            function () use ($deferred, $timeout) {
                $exception = new \RuntimeException(sprintf('Connection timed out after %d seconds.', $timeout));
                $deferred->reject($exception);
            }
        );

        $this->connector->connect($host.':'.$port)
            ->always(function () use ($timer) {
                $this->loop->cancelTimer($timer);
            })
            ->then(function (DuplexStreamInterface $stream) use ($deferred) {
                $stream->on('data', function ($data) {
                    $this->handleReceive($data);
                });

                $stream->on('close', function () {
                    $this->handleClose();
                });

                $stream->on('error', function (\Exception $e) {
                    $this->handleError($e);
                });

                $deferred->resolve($stream);
            })
            ->otherwise(function (\Exception $e) use ($deferred) {
                $deferred->reject($e);
            });

        return $deferred->promise();
    }