public void handle(Request request) {
    log.entry(request.getUri().toString());
    try {
      Object[] raw_args = request.getArguments().toArray();
      if (raw_args.length != parameter_types_.length) {
        request.getResult().addError(
            new Result.Error("invalid number of method arguments",
                             "got " + raw_args.length + " arguments for method with " +
                             parameter_types_.length + " arguments"));
        log.exit("invalid number of arguments");
        return;
      }
      Object[] args = new Object[raw_args.length];
      for (int i = 0; i < raw_args.length; i++) {
        args[i] = json_parser_.convertValue(raw_args[i], parameter_types_[i]);
      }
      Object result = method_.invoke(instance_, args);
      if (result != null) {
        request.getResult().addValue(result);
      }
    } catch (InvocationTargetException e) {
      log.catching(Level.TRACE, e);
      Throwable cause = e.getCause();
      if (cause != null) {
        if (cause instanceof RpcException) {
          request.getResult().addError(
              new Result.Error(cause.getMessage(), ((RpcException) cause).getDetails()));
        } else {
          request.getResult().addError(
              new Result.Error(cause.getClass().getName(), cause.getMessage()));
        }
      } else {
        request.getResult().addError(
            new Result.Error("unspecified exception thrown by RPC method", null));
      }
    } catch (ReflectiveOperationException e) {
      log.catching(Level.TRACE, e);
      request.getResult().addError(
          new Result.Error("cannot call method with specified arguments", null));
    } catch (Exception e) {
      log.catching(Level.TRACE, e);
      request.getResult().addError(new Result.Error(e.getClass().getName(), e.getMessage()));
    }
    log.exit();
  }