protected function remote_response($add = '')
    {
        static $s_header_sent = false;

        if (!$s_header_sent) {
            $s_header_sent = true;
            $this->nocacheing_headers();
            header('Content-Type: text/plain; charset=' . $this->get_charset());
        }

        // unset default env vars
        unset($this->env['task'], $this->env['action'], $this->env['comm_path']);

        $rcmail = rcmail::get_instance();
        $response['action'] = $rcmail->action;

        if ($unlock = rcube_utils::get_input_value('_unlock', rcube_utils::INPUT_GPC)) {
            $response['unlock'] = $unlock;
        }

        if (!empty($this->env))
            $response['env'] = $this->env;

        if (!empty($this->texts))
            $response['texts'] = $this->texts;

        // send function calls
        $response['exec'] = $this->get_js_commands() . $add;

        if (!empty($this->callbacks))
            $response['callbacks'] = $this->callbacks;

        // trigger generic hook where plugins can put additional content to the response
        $hook = $this->app->plugins->exec_hook("render_response", array('response' => $response));

        // save some memory
        $response = $hook['response'];
        unset($hook['response']);

        echo self::json_serialize($response, $this->devel_mode, false);
    }