Handles a single request object and returns the correct result as follows:

        - A valid response object if it is a regular request (with ID)
        - ``None`` if it was a notification (if None is returned, a response object with
          "received" body was already sent to the client.

        :param request_object: A :py:class:`gemstone.core.structs.JsonRpcRequest` object
                               representing a Request object
        :return: A :py:class:`gemstone.core.structs.JsonRpcResponse` object representing a
                 Response object or None if no response is expected (it was a notification)

def handle_single_request(self, request_object):
        """
        Handles a single request object and returns the correct result as follows:

        - A valid response object if it is a regular request (with ID)
        - ``None`` if it was a notification (if None is returned, a response object with
          "received" body was already sent to the client.

        :param request_object: A :py:class:`gemstone.core.structs.JsonRpcRequest` object
                               representing a Request object
        :return: A :py:class:`gemstone.core.structs.JsonRpcResponse` object representing a
                 Response object or None if no response is expected (it was a notification)

        """
        # don't handle responses?
        if isinstance(request_object, JsonRpcResponse):
            return request_object

        error = None
        result = None
        id_ = request_object.id

        # validate method name
        if request_object.method not in self.methods:
            resp = GenericResponse.METHOD_NOT_FOUND
            resp.id = id_
            return resp

        # check for private access
        method = self.methods[request_object.method]

        if isinstance(request_object.params, (list, tuple)):
            self.call_method_from_all_plugins("on_method_call", request_object)
        else:
            self.call_method_from_all_plugins("on_method_call", request_object)

        if self._method_is_private(method):
            if not self.get_current_user():
                resp = GenericResponse.ACCESS_DENIED
                resp.id = id_
                return resp

        method = self.prepare_method_call(method, request_object.params)

        # before request hook
        _method_duration = time.time()

        try:
            result = yield self.call_method(method)
        except Exception as e:
            # catch all exceptions generated by method
            # and handle in a special manner only the TypeError
            if isinstance(e, TypeError):
                # TODO: find a proper way to check that the function got the wrong
                # parameters (with **kwargs)
                if "got an unexpected keyword argument" in e.args[0]:
                    resp = GenericResponse.INVALID_PARAMS
                    resp.id = id_
                    return resp
                # TODO: find a proper way to check that the function got the wrong
                # parameters (with *args)
                elif "takes" in e.args[0] and "positional argument" in e.args[0] and "were given" in \
                        e.args[0]:
                    resp = GenericResponse.INVALID_PARAMS
                    resp.id = id_
                    return resp
                elif "missing" in e.args[0] and "required positional argument" in e.args[0]:
                    resp = GenericResponse.INVALID_PARAMS
                    resp.id = id_
                    return resp
            # generic handling for any exception (even TypeError) that
            # is not generated because of bad parameters

            self.call_method_from_all_plugins("on_internal_error", e)

            err = GenericResponse.INTERNAL_ERROR
            err.id = id_
            err.error["data"] = {
                "class": type(e).__name__,
                "info": str(e)
            }
            return err

        to_return_resp = JsonRpcResponse(result=result, error=error, id=id_)

        return to_return_resp