protected function dispatch(Command $command)
    {
        // re-connect if we have timed out
        if ($this->isTimedOut() === true) {
            $this->close();
            $this->connect();
        }

        // construct message
        $message = $command->getCommand() . "\r\n";

        if (($data = $command->getData()) !== false) {
            $message .= $data . "\r\n";
        }

        // write to stream
        if ($this->stream->write($message) === false) {
            throw new Exception(
                'Error writing data to the server.',
                Exception::SERVER_WRITE
            );
        }

        // read response from stream
        $response = $this->stream->readLine();

        // validate against common errors
        $this->validateResponse($response);

        $data = null;

        if ($command->returnsData()) {
            $bytes = preg_replace('/^.*\b(\d+)$/', '$1', $response);
            $data = $this->stream->read($bytes);
        }

        return $command->parseResponse($response, $data, $this);
    }