public function run() {
        global $CFG, $SESSION;

        // we will probably need a lot of memory in some functions
        raise_memory_limit(MEMORY_EXTRA);

        // set some longer timeout, this script is not sending any output,
        // this means we need to manually extend the timeout operations
        // that need longer time to finish
        external_api::set_timeout();

        // set up exception handler first, we want to sent them back in correct format that
        // the other system understands
        // we do not need to call the original default handler because this ws handler does everything
        set_exception_handler(array($this, 'exception_handler'));

        // init all properties from the request data
        $this->parse_request();

        // authenticate user, this has to be done after the request parsing
        // this also sets up $USER and $SESSION
        $this->authenticate_user();

        // find all needed function info and make sure user may actually execute the function
        $this->load_function_info();

        // Log the web service request.
        $params = array(
            'other' => array(
                'function' => $this->functionname
            )
        );
        $event = \core\event\webservice_function_called::create($params);
        $event->set_legacy_logdata(array(SITEID, 'webservice', $this->functionname, '' , getremoteaddr() , 0, $this->userid));
        $event->trigger();

        // Do additional setup stuff.
        $settings = external_settings::get_instance();
        $sessionlang = $settings->get_lang();
        if (!empty($sessionlang)) {
            $SESSION->lang = $sessionlang;
        }

        setup_lang_from_browser();

        if (empty($CFG->lang)) {
            if (empty($SESSION->lang)) {
                $CFG->lang = 'en';
            } else {
                $CFG->lang = $SESSION->lang;
            }
        }

        // finally, execute the function - any errors are catched by the default exception handler
        $this->execute();

        // send the results back in correct format
        $this->send_response();

        // session cleanup
        $this->session_cleanup();

        die;
    }