def send_request(self, request, response=None):

        """ Send the request.

        Sends the request and retrieves the results, formats them and returns
         them in a dict or a list (when it's a batchresponse). If something
         goes wrong, raises a SoapFailure or a HTTPError on system-side
         failures. Note: AuthRequest raises an HTTPError on failed
         authentications!

        :param request: The request to send
        :type request: pythonzimbra.request.Request
        :param response: A prebuilt response object
        :type response: pythonzimbra.response.Response
        :raises: pythonzimbra.exceptions.communication.SoapFailure or
                urllib2.HTTPError
        """

        local_response = None

        if response is None:

            if request.request_type == "json":

                local_response = ResponseJson()

            elif request.request_type == "xml":

                local_response = ResponseXml()

            else:

                raise UnknownRequestType()

        try:

            server_request = ur.urlopen(
                self.url,
                request.get_request().encode("utf-8"),
                self.timeout
            )

            server_response = server_request.read()

            if isinstance(server_response, bytes):

                server_response = server_response.decode("utf-8")

            if response is None:

                local_response.set_response(
                    server_response
                )

            else:

                response.set_response(server_response)

        except ue.HTTPError as e:

            if e.code == 500:

                # 500 codes normally returns a SoapFault, that we can use

                server_response = e.fp.read()

                if isinstance(server_response, bytes):

                    server_response = server_response.decode("utf-8")

                if response is None:

                    local_response.set_response(server_response)

                else:

                    response.set_response(server_response)

            else:

                raise e

        if response is None:
            return local_response
Send the request.

        Sends the request and retrieves the results, formats them and returns
         them in a dict or a list (when it's a batchresponse). If something
         goes wrong, raises a SoapFailure or a HTTPError on system-side
         failures. Note: AuthRequest raises an HTTPError on failed
         authentications!

        :param request: The request to send
        :type request: pythonzimbra.request.Request
        :param response: A prebuilt response object
        :type response: pythonzimbra.response.Response
        :raises: pythonzimbra.exceptions.communication.SoapFailure or
                urllib2.HTTPError