Sends commands to this hypervisor.

        :param command: a uBridge hypervisor command

        :returns: results as a list

def send(self, command):
        """
        Sends commands to this hypervisor.

        :param command: a uBridge hypervisor command

        :returns: results as a list
        """

        # uBridge responses are of the form:
        #   1xx yyyyyy\r\n
        #   1xx yyyyyy\r\n
        #   ...
        #   100-yyyy\r\n
        # or
        #   2xx-yyyy\r\n
        #
        # Where 1xx is a code from 100-199 for a success or 200-299 for an error
        # The result might be multiple lines and might be less than the buffer size
        # but still have more data. The only thing we know for sure is the last line
        # will begin with '100-' or a '2xx-' and end with '\r\n'

        if self._writer is None or self._reader is None:
            raise UbridgeError("Not connected")

        try:
            command = command.strip() + '\n'
            log.debug("sending {}".format(command))
            self._writer.write(command.encode())
            yield from self._writer.drain()
        except OSError as e:
            raise UbridgeError("Lost communication with {host}:{port} :{error}, Dynamips process running: {run}"
                               .format(host=self._host, port=self._port, error=e, run=self.is_running()))

        # Now retrieve the result
        data = []
        buf = ''
        retries = 0
        max_retries = 10
        while True:
            try:
                try:
                    chunk = yield from self._reader.read(1024)
                except asyncio.CancelledError:
                    # task has been canceled but continue to read
                    # any remaining data sent by the hypervisor
                    continue
                except ConnectionResetError as e:
                    # Sometimes WinError 64 (ERROR_NETNAME_DELETED) is returned here on Windows.
                    # These happen if connection reset is received before IOCP could complete
                    # a previous operation. Ignore and try again....
                    log.warning("Connection reset received while reading uBridge response: {}".format(e))
                    continue
                if not chunk:
                    if retries > max_retries:
                        raise UbridgeError("No data returned from {host}:{port}, uBridge process running: {run}"
                                            .format(host=self._host, port=self._port, run=self.is_running()))
                    else:
                        retries += 1
                        yield from asyncio.sleep(0.1)
                        continue
                retries = 0
                buf += chunk.decode("utf-8")
            except OSError as e:
                raise UbridgeError("Lost communication with {host}:{port} :{error}, uBridge process running: {run}"
                                   .format(host=self._host, port=self._port, error=e, run=self.is_running()))

            # If the buffer doesn't end in '\n' then we can't be done
            try:
                if buf[-1] != '\n':
                    continue
            except IndexError:
                raise UbridgeError("Could not communicate with {host}:{port}, uBridge process running: {run}"
                                   .format(host=self._host, port=self._port, run=self.is_running()))

            data += buf.split('\r\n')
            if data[-1] == '':
                data.pop()
            buf = ''

            # Does it contain an error code?
            if self.error_re.search(data[-1]):
                raise UbridgeError(data[-1][4:])

            # Or does the last line begin with '100-'? Then we are done!
            if data[-1][:4] == '100-':
                data[-1] = data[-1][4:]
                if data[-1] == 'OK':
                    data.pop()
                break

        # Remove success responses codes
        for index in range(len(data)):
            if self.success_re.search(data[index]):
                data[index] = data[index][4:]

        log.debug("returned result {}".format(data))
        return data